@extend-ai/react-xlsx 0.20.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{chart-renderer-AAVZ34BF.cjs → chart-renderer-3QDNTMRN.cjs} +526 -604
- package/dist/chart-renderer-3QDNTMRN.cjs.map +1 -0
- package/dist/{chart-renderer-RXO7WP4Q.js → chart-renderer-7DTEXXG6.js} +19 -97
- package/dist/chart-renderer-7DTEXXG6.js.map +1 -0
- package/dist/{chart-renderer-KGLAI4DN.js → chart-renderer-F355CYSE.js} +13 -92
- package/dist/chart-renderer-F355CYSE.js.map +1 -0
- package/dist/{chart-renderer-NM5UVCTO.cjs → chart-renderer-LGW4EH4M.cjs} +287 -366
- package/dist/chart-renderer-LGW4EH4M.cjs.map +1 -0
- package/dist/{chunk-WSQDFXDW.js → chunk-3LMOGW6A.js} +22 -6
- package/dist/chunk-3LMOGW6A.js.map +1 -0
- package/dist/chunk-A4S3AMON.js +108 -0
- package/dist/chunk-A4S3AMON.js.map +1 -0
- package/dist/{chunk-T5WZHPIN.cjs → chunk-AD4CGQN2.cjs} +2 -2
- package/dist/{chunk-T5WZHPIN.cjs.map → chunk-AD4CGQN2.cjs.map} +1 -1
- package/dist/chunk-AJT23BDP.js +111 -0
- package/dist/chunk-AJT23BDP.js.map +1 -0
- package/dist/{chunk-CJBI5F6V.cjs → chunk-AZWBTFJI.cjs} +12 -93
- package/dist/chunk-AZWBTFJI.cjs.map +1 -0
- package/dist/{chunk-6K3NSKDJ.cjs → chunk-D2UA4P6N.cjs} +15 -4
- package/dist/chunk-D2UA4P6N.cjs.map +1 -0
- package/dist/{chunk-QN3D3JS2.js → chunk-GXYDJPHM.js} +162 -40
- package/dist/chunk-GXYDJPHM.js.map +1 -0
- package/dist/chunk-IDNIGBUM.cjs +108 -0
- package/dist/chunk-IDNIGBUM.cjs.map +1 -0
- package/dist/{chunk-3JTCYAUX.js → chunk-IYGZTLDY.js} +14 -3
- package/dist/chunk-IYGZTLDY.js.map +1 -0
- package/dist/chunk-M55TBS4X.cjs +111 -0
- package/dist/chunk-M55TBS4X.cjs.map +1 -0
- package/dist/{chunk-MCFUTO4J.cjs → chunk-OCF75R75.cjs} +25 -9
- package/dist/chunk-OCF75R75.cjs.map +1 -0
- package/dist/{chunk-NBH72POD.js → chunk-PUI6QI4U.js} +11 -92
- package/dist/chunk-PUI6QI4U.js.map +1 -0
- package/dist/{chunk-2YBG7XQ3.cjs → chunk-ZJ76CZAL.cjs} +1683 -1561
- package/dist/chunk-ZJ76CZAL.cjs.map +1 -0
- package/dist/index.cjs +626 -529
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +124 -27
- package/dist/index.js.map +1 -1
- package/dist/{internal-DrXSHYJZ.d.cts → internal-BJsg5os3.d.cts} +13 -0
- package/dist/{internal-DrXSHYJZ.d.ts → internal-BJsg5os3.d.ts} +13 -0
- package/dist/internal.cjs +6 -5
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +4 -3
- package/dist/preact-LICENSE.txt +21 -0
- package/dist/region-map-geography-24TXETDP.cjs +184 -0
- package/dist/region-map-geography-24TXETDP.cjs.map +1 -0
- package/dist/region-map-geography-OR6DHAF7.js +182 -0
- package/dist/region-map-geography-OR6DHAF7.js.map +1 -0
- package/dist/shared-chart-3STFRVWT.js +215 -0
- package/dist/shared-chart-3STFRVWT.js.map +1 -0
- package/dist/shared-chart-BFQNYOIQ.js +221 -0
- package/dist/shared-chart-BFQNYOIQ.js.map +1 -0
- package/dist/shared-chart-DVC5S2P6.cjs +222 -0
- package/dist/shared-chart-DVC5S2P6.cjs.map +1 -0
- package/dist/shared-chart-MFQSQG4K.cjs +216 -0
- package/dist/shared-chart-MFQSQG4K.cjs.map +1 -0
- package/dist/{spreadsheet-font-assets-4AHYDTAQ.cjs → spreadsheet-font-assets-6FKCVICP.cjs} +2 -2
- package/dist/{spreadsheet-font-assets-4AHYDTAQ.cjs.map → spreadsheet-font-assets-6FKCVICP.cjs.map} +1 -1
- package/dist/{surface-regl-AY7JZVYY.cjs → surface-regl-BBJ6OIKK.cjs} +15 -13
- package/dist/surface-regl-BBJ6OIKK.cjs.map +1 -0
- package/dist/{surface-regl-TJUWTLAZ.js → surface-regl-R2N54JT2.js} +7 -5
- package/dist/{surface-regl-TJUWTLAZ.js.map → surface-regl-R2N54JT2.js.map} +1 -1
- package/dist/{surface-regl-5Z6IVOID.cjs → surface-regl-SUJ2TFZA.cjs} +2 -2
- package/dist/{surface-regl-5Z6IVOID.cjs.map → surface-regl-SUJ2TFZA.cjs.map} +1 -1
- package/dist/us-atlas-LICENSE.txt +13 -0
- package/dist/vanilla.cjs +6 -5
- package/dist/vanilla.cjs.map +1 -1
- package/dist/vanilla.d.cts +2 -2
- package/dist/vanilla.d.ts +2 -2
- package/dist/vanilla.js +4 -3
- package/dist/world-atlas-LICENSE.txt +13 -0
- package/dist/xlsx-worker.js +82 -1
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +7 -6
- package/dist/chart-renderer-AAVZ34BF.cjs.map +0 -1
- package/dist/chart-renderer-KGLAI4DN.js.map +0 -1
- package/dist/chart-renderer-NM5UVCTO.cjs.map +0 -1
- package/dist/chart-renderer-RXO7WP4Q.js.map +0 -1
- package/dist/chunk-2YBG7XQ3.cjs.map +0 -1
- package/dist/chunk-3JTCYAUX.js.map +0 -1
- package/dist/chunk-6K3NSKDJ.cjs.map +0 -1
- package/dist/chunk-CJBI5F6V.cjs.map +0 -1
- package/dist/chunk-MCFUTO4J.cjs.map +0 -1
- package/dist/chunk-NBH72POD.js.map +0 -1
- package/dist/chunk-QN3D3JS2.js.map +0 -1
- package/dist/chunk-WSQDFXDW.js.map +0 -1
- package/dist/region-map-geography-6TGXBY3V.cjs +0 -184
- package/dist/region-map-geography-6TGXBY3V.cjs.map +0 -1
- package/dist/region-map-geography-YD54DI3H.js +0 -182
- package/dist/region-map-geography-YD54DI3H.js.map +0 -1
- package/dist/surface-regl-AY7JZVYY.cjs.map +0 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderSelectionRectHandles,
|
|
3
|
+
useChartEvents
|
|
4
|
+
} from "./chunk-A4S3AMON.js";
|
|
5
|
+
|
|
6
|
+
// src/shared-chart.tsx
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
var svgNamespace = "http://www.w3.org/2000/svg";
|
|
10
|
+
var allowedElements = /* @__PURE__ */ new Set([
|
|
11
|
+
"svg",
|
|
12
|
+
"g",
|
|
13
|
+
"defs",
|
|
14
|
+
"clipPath",
|
|
15
|
+
"rect",
|
|
16
|
+
"circle",
|
|
17
|
+
"ellipse",
|
|
18
|
+
"path",
|
|
19
|
+
"line",
|
|
20
|
+
"polyline",
|
|
21
|
+
"polygon",
|
|
22
|
+
"text",
|
|
23
|
+
"tspan",
|
|
24
|
+
"linearGradient",
|
|
25
|
+
"radialGradient",
|
|
26
|
+
"stop",
|
|
27
|
+
"pattern"
|
|
28
|
+
]);
|
|
29
|
+
var plainAttributes = /* @__PURE__ */ new Set([
|
|
30
|
+
"x",
|
|
31
|
+
"y",
|
|
32
|
+
"width",
|
|
33
|
+
"height",
|
|
34
|
+
"x1",
|
|
35
|
+
"x2",
|
|
36
|
+
"y1",
|
|
37
|
+
"y2",
|
|
38
|
+
"cx",
|
|
39
|
+
"cy",
|
|
40
|
+
"fx",
|
|
41
|
+
"fy",
|
|
42
|
+
"r",
|
|
43
|
+
"rx",
|
|
44
|
+
"ry",
|
|
45
|
+
"fr",
|
|
46
|
+
"viewBox",
|
|
47
|
+
"transform",
|
|
48
|
+
"d",
|
|
49
|
+
"points",
|
|
50
|
+
"font-family",
|
|
51
|
+
"font-weight",
|
|
52
|
+
"font-size",
|
|
53
|
+
"text-anchor",
|
|
54
|
+
"dominant-baseline",
|
|
55
|
+
"stroke-linecap",
|
|
56
|
+
"stroke-linejoin",
|
|
57
|
+
"stroke-width",
|
|
58
|
+
"stroke-dasharray",
|
|
59
|
+
"opacity",
|
|
60
|
+
"fill-opacity",
|
|
61
|
+
"stroke-opacity",
|
|
62
|
+
"fill-rule",
|
|
63
|
+
"shape-rendering",
|
|
64
|
+
"offset",
|
|
65
|
+
"stop-opacity",
|
|
66
|
+
"gradientUnits",
|
|
67
|
+
"gradientTransform",
|
|
68
|
+
"patternUnits",
|
|
69
|
+
"patternContentUnits",
|
|
70
|
+
"data-chart-kind",
|
|
71
|
+
"data-chart-series",
|
|
72
|
+
"data-chart-point",
|
|
73
|
+
"data-chart-x",
|
|
74
|
+
"data-chart-y"
|
|
75
|
+
]);
|
|
76
|
+
function safeChartSvg(markup, prefix) {
|
|
77
|
+
const svg = new DOMParser().parseFromString(markup, "image/svg+xml").documentElement;
|
|
78
|
+
if (svg.localName !== "svg" || svg.namespaceURI !== svgNamespace) return null;
|
|
79
|
+
for (const node of [svg, ...Array.from(svg.querySelectorAll("*"))]) {
|
|
80
|
+
if (node.namespaceURI !== svgNamespace || !allowedElements.has(node.localName)) return null;
|
|
81
|
+
for (const { name, value } of Array.from(node.attributes)) {
|
|
82
|
+
if (plainAttributes.has(name) || name === "xmlns") continue;
|
|
83
|
+
if (name === "id" && /^[\w-]+$/.test(value)) {
|
|
84
|
+
node.setAttribute(name, prefix + value);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (name === "href" && /^(linearGradient|radialGradient)$/.test(node.localName) && /^#[\w-]+$/.test(value)) {
|
|
88
|
+
node.setAttribute(name, "#" + prefix + value.slice(1));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (["fill", "stroke", "stop-color", "clip-path"].includes(name)) {
|
|
92
|
+
const local = /^url\(#([\w-]+)\)$/.exec(value);
|
|
93
|
+
if (local) {
|
|
94
|
+
node.setAttribute(name, "url(#" + prefix + local[1] + ")");
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (/^(?:#[\da-f]{3,8}|[a-z]+)$/i.test(value)) continue;
|
|
98
|
+
}
|
|
99
|
+
node.removeAttribute(name);
|
|
100
|
+
}
|
|
101
|
+
if (node.hasAttribute("data-chart-series")) {
|
|
102
|
+
node.setAttribute("data-xlsx-chart-series-index", node.getAttribute("data-chart-series"));
|
|
103
|
+
const point = node.getAttribute("data-chart-point");
|
|
104
|
+
if (point != null) node.setAttribute("data-xlsx-chart-point-index", point);
|
|
105
|
+
const kind = node.getAttribute("data-chart-kind");
|
|
106
|
+
if (kind === "bar") node.setAttribute("data-xlsx-chart-selection-mode", "seriesFirst");
|
|
107
|
+
if (kind === "legendEntry") node.setAttribute("data-xlsx-chart-element-kind", kind);
|
|
108
|
+
const style = node.style;
|
|
109
|
+
style.cursor = "pointer";
|
|
110
|
+
style.pointerEvents = "all";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return svg;
|
|
114
|
+
}
|
|
115
|
+
function renderSharedChart(renderer, chart, source, width, height, prefix) {
|
|
116
|
+
try {
|
|
117
|
+
const svg = renderer.renderChart(source.xml, {
|
|
118
|
+
themeColors: source.themeColors,
|
|
119
|
+
themeOverrideXml: source.themeOverrideXml,
|
|
120
|
+
styleXml: source.styleXml,
|
|
121
|
+
colorStyleXml: source.colorStyleXml,
|
|
122
|
+
width,
|
|
123
|
+
height,
|
|
124
|
+
interactive: true,
|
|
125
|
+
spreadsheetDefaults: true,
|
|
126
|
+
fontFamily: chart.fontFamily,
|
|
127
|
+
data: {
|
|
128
|
+
title: chart.title,
|
|
129
|
+
series: chart.series.map((series) => ({
|
|
130
|
+
chartType: source.kind,
|
|
131
|
+
name: series.name,
|
|
132
|
+
points: Array.from({ length: Math.max(series.values.length, series.categories.length) }, (_, index) => {
|
|
133
|
+
const value = series.values[index];
|
|
134
|
+
const label = series.categories[index];
|
|
135
|
+
return {
|
|
136
|
+
index,
|
|
137
|
+
value: value == null ? null : String(value),
|
|
138
|
+
categories: series.categories.length || series.categoriesRef?.formula ? [{ level: 0, label: label == null ? "" : String(label) }] : []
|
|
139
|
+
};
|
|
140
|
+
})
|
|
141
|
+
}))
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return svg ? safeChartSvg(svg, prefix) : null;
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function selectionHandles(svg, chartId, selected) {
|
|
150
|
+
if (!selected || selected.chartId !== chartId || selected.kind === "chart") return null;
|
|
151
|
+
return Array.from(svg.querySelectorAll("[data-chart-point]")).map((node, index) => {
|
|
152
|
+
if (Number(node.getAttribute("data-chart-series")) !== selected.seriesIndex || selected.kind === "point" && Number(node.getAttribute("data-chart-point")) !== selected.pointIndex) return null;
|
|
153
|
+
if (node.getAttribute("data-chart-kind") === "bar") {
|
|
154
|
+
return renderSelectionRectHandles(
|
|
155
|
+
String(index),
|
|
156
|
+
Number(node.getAttribute("x")),
|
|
157
|
+
Number(node.getAttribute("y")),
|
|
158
|
+
Number(node.getAttribute("width")),
|
|
159
|
+
Number(node.getAttribute("height"))
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (!node.hasAttribute("data-chart-x") || !node.hasAttribute("data-chart-y")) return null;
|
|
163
|
+
return renderSelectionRectHandles(
|
|
164
|
+
String(index),
|
|
165
|
+
Number(node.getAttribute("data-chart-x")) - 4,
|
|
166
|
+
Number(node.getAttribute("data-chart-y")) - 4,
|
|
167
|
+
8,
|
|
168
|
+
8
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function SharedChartSvg(props) {
|
|
173
|
+
const { chart, rect, renderer, source, selectedChartElement, fallback } = props;
|
|
174
|
+
const id = React.useId();
|
|
175
|
+
const width = Math.max(1, rect.width);
|
|
176
|
+
const height = Math.max(1, rect.height);
|
|
177
|
+
const svg = React.useMemo(() => renderSharedChart(
|
|
178
|
+
renderer,
|
|
179
|
+
chart,
|
|
180
|
+
source,
|
|
181
|
+
width,
|
|
182
|
+
height,
|
|
183
|
+
"oc-" + id.replace(/[^\w-]/g, "") + "-"
|
|
184
|
+
), [renderer, chart, source, width, height, id]);
|
|
185
|
+
const graphics = React.useRef(null);
|
|
186
|
+
React.useLayoutEffect(() => {
|
|
187
|
+
if (graphics.current && svg) graphics.current.replaceChildren(svg);
|
|
188
|
+
}, [svg]);
|
|
189
|
+
const handles = React.useMemo(
|
|
190
|
+
() => svg && selectionHandles(svg, chart.id, selectedChartElement),
|
|
191
|
+
[svg, chart.id, selectedChartElement]
|
|
192
|
+
);
|
|
193
|
+
const { handlePointerDown, handleDoubleClick } = useChartEvents(props);
|
|
194
|
+
if (!svg) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
195
|
+
return /* @__PURE__ */ jsxs(
|
|
196
|
+
"svg",
|
|
197
|
+
{
|
|
198
|
+
"aria-label": chart.title ?? chart.name ?? "Chart",
|
|
199
|
+
"data-xlsx-chart-renderer": "office-charts",
|
|
200
|
+
onDoubleClick: handleDoubleClick,
|
|
201
|
+
onPointerDown: handlePointerDown,
|
|
202
|
+
role: "img",
|
|
203
|
+
style: { display: "block", height: "100%", pointerEvents: "auto", width: "100%" },
|
|
204
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
205
|
+
children: [
|
|
206
|
+
/* @__PURE__ */ jsx("g", { ref: graphics }),
|
|
207
|
+
handles
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
export {
|
|
213
|
+
SharedChartSvg
|
|
214
|
+
};
|
|
215
|
+
//# sourceMappingURL=shared-chart-3STFRVWT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared-chart.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type { OfficeCharts } from \"@extend-ai/rust-office-charts\";\nimport { renderSelectionRectHandles, useChartEvents } from \"./chart-interaction\";\nimport type { ChartSvgProps } from \"./chart-renderer\";\nimport type { XlsxChart, XlsxChartRenderSource, XlsxChartElementSelection } from \"./types\";\n\nconst svgNamespace = \"http://www.w3.org/2000/svg\";\nconst allowedElements = new Set([\n \"svg\", \"g\", \"defs\", \"clipPath\", \"rect\", \"circle\", \"ellipse\", \"path\", \"line\", \"polyline\", \"polygon\",\n \"text\", \"tspan\", \"linearGradient\", \"radialGradient\", \"stop\", \"pattern\"\n]);\nconst plainAttributes = new Set([\n \"x\", \"y\", \"width\", \"height\", \"x1\", \"x2\", \"y1\", \"y2\", \"cx\", \"cy\", \"fx\", \"fy\", \"r\", \"rx\", \"ry\", \"fr\",\n \"viewBox\", \"transform\", \"d\", \"points\", \"font-family\", \"font-weight\", \"font-size\", \"text-anchor\",\n \"dominant-baseline\", \"stroke-linecap\", \"stroke-linejoin\", \"stroke-width\", \"stroke-dasharray\",\n \"opacity\", \"fill-opacity\", \"stroke-opacity\", \"fill-rule\", \"shape-rendering\", \"offset\", \"stop-opacity\",\n \"gradientUnits\", \"gradientTransform\", \"patternUnits\", \"patternContentUnits\",\n \"data-chart-kind\", \"data-chart-series\", \"data-chart-point\", \"data-chart-x\", \"data-chart-y\"\n]);\n\nfunction safeChartSvg(markup: string, prefix: string) {\n const svg = new DOMParser().parseFromString(markup, \"image/svg+xml\").documentElement;\n if (svg.localName !== \"svg\" || svg.namespaceURI !== svgNamespace) return null;\n\n // Only local paint servers and inert geometry can enter the document.\n for (const node of [svg, ...Array.from(svg.querySelectorAll(\"*\"))]) {\n if (node.namespaceURI !== svgNamespace || !allowedElements.has(node.localName)) return null;\n for (const { name, value } of Array.from(node.attributes)) {\n if (plainAttributes.has(name) || name === \"xmlns\") continue;\n if (name === \"id\" && /^[\\w-]+$/.test(value)) {\n node.setAttribute(name, prefix + value);\n continue;\n }\n if (name === \"href\" && /^(linearGradient|radialGradient)$/.test(node.localName) && /^#[\\w-]+$/.test(value)) {\n node.setAttribute(name, \"#\" + prefix + value.slice(1));\n continue;\n }\n if ([\"fill\", \"stroke\", \"stop-color\", \"clip-path\"].includes(name)) {\n const local = /^url\\(#([\\w-]+)\\)$/.exec(value);\n if (local) {\n node.setAttribute(name, \"url(#\" + prefix + local[1] + \")\");\n continue;\n }\n if (/^(?:#[\\da-f]{3,8}|[a-z]+)$/i.test(value)) continue;\n }\n node.removeAttribute(name);\n }\n\n if (node.hasAttribute(\"data-chart-series\")) {\n node.setAttribute(\"data-xlsx-chart-series-index\", node.getAttribute(\"data-chart-series\")!);\n const point = node.getAttribute(\"data-chart-point\");\n if (point != null) node.setAttribute(\"data-xlsx-chart-point-index\", point);\n const kind = node.getAttribute(\"data-chart-kind\");\n if (kind === \"bar\") node.setAttribute(\"data-xlsx-chart-selection-mode\", \"seriesFirst\");\n if (kind === \"legendEntry\") node.setAttribute(\"data-xlsx-chart-element-kind\", kind);\n const style = (node as SVGElement).style;\n style.cursor = \"pointer\";\n style.pointerEvents = \"all\";\n }\n }\n return svg;\n}\n\nfunction renderSharedChart(renderer: OfficeCharts, chart: XlsxChart, source: XlsxChartRenderSource, width: number, height: number, prefix: string) {\n try {\n const svg = renderer.renderChart(source.xml, {\n themeColors: source.themeColors,\n themeOverrideXml: source.themeOverrideXml,\n styleXml: source.styleXml,\n colorStyleXml: source.colorStyleXml,\n width, height,\n interactive: true,\n spreadsheetDefaults: true,\n fontFamily: chart.fontFamily,\n data: {\n title: chart.title,\n series: chart.series.map((series) => ({\n chartType: source.kind,\n name: series.name,\n points: Array.from({ length: Math.max(series.values.length, series.categories.length) }, (_, index) => {\n const value = series.values[index];\n const label = series.categories[index];\n return {\n index,\n value: value == null ? null : String(value),\n categories: series.categories.length || series.categoriesRef?.formula\n ? [{ level: 0, label: label == null ? \"\" : String(label) }]\n : []\n };\n })\n }))\n }\n });\n return svg ? safeChartSvg(svg, prefix) : null;\n } catch {\n return null;\n }\n}\n\nfunction selectionHandles(svg: Element, chartId: string, selected: XlsxChartElementSelection | null | undefined) {\n if (!selected || selected.chartId !== chartId || selected.kind === \"chart\") return null;\n return Array.from(svg.querySelectorAll(\"[data-chart-point]\")).map((node, index) => {\n if (Number(node.getAttribute(\"data-chart-series\")) !== selected.seriesIndex\n || (selected.kind === \"point\" && Number(node.getAttribute(\"data-chart-point\")) !== selected.pointIndex)) return null;\n if (node.getAttribute(\"data-chart-kind\") === \"bar\") {\n return renderSelectionRectHandles(String(index), Number(node.getAttribute(\"x\")), Number(node.getAttribute(\"y\")),\n Number(node.getAttribute(\"width\")), Number(node.getAttribute(\"height\")));\n }\n if (!node.hasAttribute(\"data-chart-x\") || !node.hasAttribute(\"data-chart-y\")) return null;\n return renderSelectionRectHandles(String(index), Number(node.getAttribute(\"data-chart-x\")) - 4,\n Number(node.getAttribute(\"data-chart-y\")) - 4, 8, 8);\n });\n}\n\nexport function SharedChartSvg(props: ChartSvgProps & {\n source: XlsxChartRenderSource;\n renderer: OfficeCharts;\n fallback: React.ReactNode;\n}) {\n const { chart, rect, renderer, source, selectedChartElement, fallback } = props;\n const id = React.useId();\n const width = Math.max(1, rect.width);\n const height = Math.max(1, rect.height);\n const svg = React.useMemo(() => renderSharedChart(renderer, chart, source, width, height,\n \"oc-\" + id.replace(/[^\\w-]/g, \"\") + \"-\"), [renderer, chart, source, width, height, id]);\n const graphics = React.useRef<SVGGElement>(null);\n React.useLayoutEffect(() => {\n if (graphics.current && svg) graphics.current.replaceChildren(svg);\n }, [svg]);\n const handles = React.useMemo(() => svg && selectionHandles(svg, chart.id, selectedChartElement),\n [svg, chart.id, selectedChartElement]);\n const { handlePointerDown, handleDoubleClick } = useChartEvents(props);\n if (!svg) return <>{fallback}</>;\n return (\n <svg\n aria-label={chart.title ?? chart.name ?? \"Chart\"}\n data-xlsx-chart-renderer=\"office-charts\"\n onDoubleClick={handleDoubleClick}\n onPointerDown={handlePointerDown}\n role=\"img\"\n style={{ display: \"block\", height: \"100%\", pointerEvents: \"auto\", width: \"100%\" }}\n viewBox={`0 0 ${width} ${height}`}\n >\n <g ref={graphics} />\n {handles}\n </svg>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderSelectionRectHandles,
|
|
3
|
+
useChartEvents
|
|
4
|
+
} from "./chunk-AJT23BDP.js";
|
|
5
|
+
import {
|
|
6
|
+
A,
|
|
7
|
+
S,
|
|
8
|
+
T,
|
|
9
|
+
_,
|
|
10
|
+
g,
|
|
11
|
+
u
|
|
12
|
+
} from "./chunk-PUI6QI4U.js";
|
|
13
|
+
|
|
14
|
+
// src/shared-chart.tsx
|
|
15
|
+
var svgNamespace = "http://www.w3.org/2000/svg";
|
|
16
|
+
var allowedElements = /* @__PURE__ */ new Set([
|
|
17
|
+
"svg",
|
|
18
|
+
"g",
|
|
19
|
+
"defs",
|
|
20
|
+
"clipPath",
|
|
21
|
+
"rect",
|
|
22
|
+
"circle",
|
|
23
|
+
"ellipse",
|
|
24
|
+
"path",
|
|
25
|
+
"line",
|
|
26
|
+
"polyline",
|
|
27
|
+
"polygon",
|
|
28
|
+
"text",
|
|
29
|
+
"tspan",
|
|
30
|
+
"linearGradient",
|
|
31
|
+
"radialGradient",
|
|
32
|
+
"stop",
|
|
33
|
+
"pattern"
|
|
34
|
+
]);
|
|
35
|
+
var plainAttributes = /* @__PURE__ */ new Set([
|
|
36
|
+
"x",
|
|
37
|
+
"y",
|
|
38
|
+
"width",
|
|
39
|
+
"height",
|
|
40
|
+
"x1",
|
|
41
|
+
"x2",
|
|
42
|
+
"y1",
|
|
43
|
+
"y2",
|
|
44
|
+
"cx",
|
|
45
|
+
"cy",
|
|
46
|
+
"fx",
|
|
47
|
+
"fy",
|
|
48
|
+
"r",
|
|
49
|
+
"rx",
|
|
50
|
+
"ry",
|
|
51
|
+
"fr",
|
|
52
|
+
"viewBox",
|
|
53
|
+
"transform",
|
|
54
|
+
"d",
|
|
55
|
+
"points",
|
|
56
|
+
"font-family",
|
|
57
|
+
"font-weight",
|
|
58
|
+
"font-size",
|
|
59
|
+
"text-anchor",
|
|
60
|
+
"dominant-baseline",
|
|
61
|
+
"stroke-linecap",
|
|
62
|
+
"stroke-linejoin",
|
|
63
|
+
"stroke-width",
|
|
64
|
+
"stroke-dasharray",
|
|
65
|
+
"opacity",
|
|
66
|
+
"fill-opacity",
|
|
67
|
+
"stroke-opacity",
|
|
68
|
+
"fill-rule",
|
|
69
|
+
"shape-rendering",
|
|
70
|
+
"offset",
|
|
71
|
+
"stop-opacity",
|
|
72
|
+
"gradientUnits",
|
|
73
|
+
"gradientTransform",
|
|
74
|
+
"patternUnits",
|
|
75
|
+
"patternContentUnits",
|
|
76
|
+
"data-chart-kind",
|
|
77
|
+
"data-chart-series",
|
|
78
|
+
"data-chart-point",
|
|
79
|
+
"data-chart-x",
|
|
80
|
+
"data-chart-y"
|
|
81
|
+
]);
|
|
82
|
+
function safeChartSvg(markup, prefix) {
|
|
83
|
+
const svg = new DOMParser().parseFromString(markup, "image/svg+xml").documentElement;
|
|
84
|
+
if (svg.localName !== "svg" || svg.namespaceURI !== svgNamespace) return null;
|
|
85
|
+
for (const node of [svg, ...Array.from(svg.querySelectorAll("*"))]) {
|
|
86
|
+
if (node.namespaceURI !== svgNamespace || !allowedElements.has(node.localName)) return null;
|
|
87
|
+
for (const { name, value } of Array.from(node.attributes)) {
|
|
88
|
+
if (plainAttributes.has(name) || name === "xmlns") continue;
|
|
89
|
+
if (name === "id" && /^[\w-]+$/.test(value)) {
|
|
90
|
+
node.setAttribute(name, prefix + value);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (name === "href" && /^(linearGradient|radialGradient)$/.test(node.localName) && /^#[\w-]+$/.test(value)) {
|
|
94
|
+
node.setAttribute(name, "#" + prefix + value.slice(1));
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (["fill", "stroke", "stop-color", "clip-path"].includes(name)) {
|
|
98
|
+
const local = /^url\(#([\w-]+)\)$/.exec(value);
|
|
99
|
+
if (local) {
|
|
100
|
+
node.setAttribute(name, "url(#" + prefix + local[1] + ")");
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (/^(?:#[\da-f]{3,8}|[a-z]+)$/i.test(value)) continue;
|
|
104
|
+
}
|
|
105
|
+
node.removeAttribute(name);
|
|
106
|
+
}
|
|
107
|
+
if (node.hasAttribute("data-chart-series")) {
|
|
108
|
+
node.setAttribute("data-xlsx-chart-series-index", node.getAttribute("data-chart-series"));
|
|
109
|
+
const point = node.getAttribute("data-chart-point");
|
|
110
|
+
if (point != null) node.setAttribute("data-xlsx-chart-point-index", point);
|
|
111
|
+
const kind = node.getAttribute("data-chart-kind");
|
|
112
|
+
if (kind === "bar") node.setAttribute("data-xlsx-chart-selection-mode", "seriesFirst");
|
|
113
|
+
if (kind === "legendEntry") node.setAttribute("data-xlsx-chart-element-kind", kind);
|
|
114
|
+
const style = node.style;
|
|
115
|
+
style.cursor = "pointer";
|
|
116
|
+
style.pointerEvents = "all";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return svg;
|
|
120
|
+
}
|
|
121
|
+
function renderSharedChart(renderer, chart, source, width, height, prefix) {
|
|
122
|
+
try {
|
|
123
|
+
const svg = renderer.renderChart(source.xml, {
|
|
124
|
+
themeColors: source.themeColors,
|
|
125
|
+
themeOverrideXml: source.themeOverrideXml,
|
|
126
|
+
styleXml: source.styleXml,
|
|
127
|
+
colorStyleXml: source.colorStyleXml,
|
|
128
|
+
width,
|
|
129
|
+
height,
|
|
130
|
+
interactive: true,
|
|
131
|
+
spreadsheetDefaults: true,
|
|
132
|
+
fontFamily: chart.fontFamily,
|
|
133
|
+
data: {
|
|
134
|
+
title: chart.title,
|
|
135
|
+
series: chart.series.map((series) => ({
|
|
136
|
+
chartType: source.kind,
|
|
137
|
+
name: series.name,
|
|
138
|
+
points: Array.from({ length: Math.max(series.values.length, series.categories.length) }, (_2, index) => {
|
|
139
|
+
const value = series.values[index];
|
|
140
|
+
const label = series.categories[index];
|
|
141
|
+
return {
|
|
142
|
+
index,
|
|
143
|
+
value: value == null ? null : String(value),
|
|
144
|
+
categories: series.categories.length || series.categoriesRef?.formula ? [{ level: 0, label: label == null ? "" : String(label) }] : []
|
|
145
|
+
};
|
|
146
|
+
})
|
|
147
|
+
}))
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return svg ? safeChartSvg(svg, prefix) : null;
|
|
151
|
+
} catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function selectionHandles(svg, chartId, selected) {
|
|
156
|
+
if (!selected || selected.chartId !== chartId || selected.kind === "chart") return null;
|
|
157
|
+
return Array.from(svg.querySelectorAll("[data-chart-point]")).map((node, index) => {
|
|
158
|
+
if (Number(node.getAttribute("data-chart-series")) !== selected.seriesIndex || selected.kind === "point" && Number(node.getAttribute("data-chart-point")) !== selected.pointIndex) return null;
|
|
159
|
+
if (node.getAttribute("data-chart-kind") === "bar") {
|
|
160
|
+
return renderSelectionRectHandles(
|
|
161
|
+
String(index),
|
|
162
|
+
Number(node.getAttribute("x")),
|
|
163
|
+
Number(node.getAttribute("y")),
|
|
164
|
+
Number(node.getAttribute("width")),
|
|
165
|
+
Number(node.getAttribute("height"))
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
if (!node.hasAttribute("data-chart-x") || !node.hasAttribute("data-chart-y")) return null;
|
|
169
|
+
return renderSelectionRectHandles(
|
|
170
|
+
String(index),
|
|
171
|
+
Number(node.getAttribute("data-chart-x")) - 4,
|
|
172
|
+
Number(node.getAttribute("data-chart-y")) - 4,
|
|
173
|
+
8,
|
|
174
|
+
8
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function SharedChartSvg(props) {
|
|
179
|
+
const { chart, rect, renderer, source, selectedChartElement, fallback } = props;
|
|
180
|
+
const id = g();
|
|
181
|
+
const width = Math.max(1, rect.width);
|
|
182
|
+
const height = Math.max(1, rect.height);
|
|
183
|
+
const svg = T(() => renderSharedChart(
|
|
184
|
+
renderer,
|
|
185
|
+
chart,
|
|
186
|
+
source,
|
|
187
|
+
width,
|
|
188
|
+
height,
|
|
189
|
+
"oc-" + id.replace(/[^\w-]/g, "") + "-"
|
|
190
|
+
), [renderer, chart, source, width, height, id]);
|
|
191
|
+
const graphics = A(null);
|
|
192
|
+
_(() => {
|
|
193
|
+
if (graphics.current && svg) graphics.current.replaceChildren(svg);
|
|
194
|
+
}, [svg]);
|
|
195
|
+
const handles = T(
|
|
196
|
+
() => svg && selectionHandles(svg, chart.id, selectedChartElement),
|
|
197
|
+
[svg, chart.id, selectedChartElement]
|
|
198
|
+
);
|
|
199
|
+
const { handlePointerDown, handleDoubleClick } = useChartEvents(props);
|
|
200
|
+
if (!svg) return /* @__PURE__ */ u(S, { children: fallback });
|
|
201
|
+
return /* @__PURE__ */ u(
|
|
202
|
+
"svg",
|
|
203
|
+
{
|
|
204
|
+
"aria-label": chart.title ?? chart.name ?? "Chart",
|
|
205
|
+
"data-xlsx-chart-renderer": "office-charts",
|
|
206
|
+
onDoubleClick: handleDoubleClick,
|
|
207
|
+
onPointerDown: handlePointerDown,
|
|
208
|
+
role: "img",
|
|
209
|
+
style: { display: "block", height: "100%", pointerEvents: "auto", width: "100%" },
|
|
210
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
211
|
+
children: [
|
|
212
|
+
/* @__PURE__ */ u("g", { ref: graphics }),
|
|
213
|
+
handles
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
export {
|
|
219
|
+
SharedChartSvg
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=shared-chart-BFQNYOIQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared-chart.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type { OfficeCharts } from \"@extend-ai/rust-office-charts\";\nimport { renderSelectionRectHandles, useChartEvents } from \"./chart-interaction\";\nimport type { ChartSvgProps } from \"./chart-renderer\";\nimport type { XlsxChart, XlsxChartRenderSource, XlsxChartElementSelection } from \"./types\";\n\nconst svgNamespace = \"http://www.w3.org/2000/svg\";\nconst allowedElements = new Set([\n \"svg\", \"g\", \"defs\", \"clipPath\", \"rect\", \"circle\", \"ellipse\", \"path\", \"line\", \"polyline\", \"polygon\",\n \"text\", \"tspan\", \"linearGradient\", \"radialGradient\", \"stop\", \"pattern\"\n]);\nconst plainAttributes = new Set([\n \"x\", \"y\", \"width\", \"height\", \"x1\", \"x2\", \"y1\", \"y2\", \"cx\", \"cy\", \"fx\", \"fy\", \"r\", \"rx\", \"ry\", \"fr\",\n \"viewBox\", \"transform\", \"d\", \"points\", \"font-family\", \"font-weight\", \"font-size\", \"text-anchor\",\n \"dominant-baseline\", \"stroke-linecap\", \"stroke-linejoin\", \"stroke-width\", \"stroke-dasharray\",\n \"opacity\", \"fill-opacity\", \"stroke-opacity\", \"fill-rule\", \"shape-rendering\", \"offset\", \"stop-opacity\",\n \"gradientUnits\", \"gradientTransform\", \"patternUnits\", \"patternContentUnits\",\n \"data-chart-kind\", \"data-chart-series\", \"data-chart-point\", \"data-chart-x\", \"data-chart-y\"\n]);\n\nfunction safeChartSvg(markup: string, prefix: string) {\n const svg = new DOMParser().parseFromString(markup, \"image/svg+xml\").documentElement;\n if (svg.localName !== \"svg\" || svg.namespaceURI !== svgNamespace) return null;\n\n // Only local paint servers and inert geometry can enter the document.\n for (const node of [svg, ...Array.from(svg.querySelectorAll(\"*\"))]) {\n if (node.namespaceURI !== svgNamespace || !allowedElements.has(node.localName)) return null;\n for (const { name, value } of Array.from(node.attributes)) {\n if (plainAttributes.has(name) || name === \"xmlns\") continue;\n if (name === \"id\" && /^[\\w-]+$/.test(value)) {\n node.setAttribute(name, prefix + value);\n continue;\n }\n if (name === \"href\" && /^(linearGradient|radialGradient)$/.test(node.localName) && /^#[\\w-]+$/.test(value)) {\n node.setAttribute(name, \"#\" + prefix + value.slice(1));\n continue;\n }\n if ([\"fill\", \"stroke\", \"stop-color\", \"clip-path\"].includes(name)) {\n const local = /^url\\(#([\\w-]+)\\)$/.exec(value);\n if (local) {\n node.setAttribute(name, \"url(#\" + prefix + local[1] + \")\");\n continue;\n }\n if (/^(?:#[\\da-f]{3,8}|[a-z]+)$/i.test(value)) continue;\n }\n node.removeAttribute(name);\n }\n\n if (node.hasAttribute(\"data-chart-series\")) {\n node.setAttribute(\"data-xlsx-chart-series-index\", node.getAttribute(\"data-chart-series\")!);\n const point = node.getAttribute(\"data-chart-point\");\n if (point != null) node.setAttribute(\"data-xlsx-chart-point-index\", point);\n const kind = node.getAttribute(\"data-chart-kind\");\n if (kind === \"bar\") node.setAttribute(\"data-xlsx-chart-selection-mode\", \"seriesFirst\");\n if (kind === \"legendEntry\") node.setAttribute(\"data-xlsx-chart-element-kind\", kind);\n const style = (node as SVGElement).style;\n style.cursor = \"pointer\";\n style.pointerEvents = \"all\";\n }\n }\n return svg;\n}\n\nfunction renderSharedChart(renderer: OfficeCharts, chart: XlsxChart, source: XlsxChartRenderSource, width: number, height: number, prefix: string) {\n try {\n const svg = renderer.renderChart(source.xml, {\n themeColors: source.themeColors,\n themeOverrideXml: source.themeOverrideXml,\n styleXml: source.styleXml,\n colorStyleXml: source.colorStyleXml,\n width, height,\n interactive: true,\n spreadsheetDefaults: true,\n fontFamily: chart.fontFamily,\n data: {\n title: chart.title,\n series: chart.series.map((series) => ({\n chartType: source.kind,\n name: series.name,\n points: Array.from({ length: Math.max(series.values.length, series.categories.length) }, (_, index) => {\n const value = series.values[index];\n const label = series.categories[index];\n return {\n index,\n value: value == null ? null : String(value),\n categories: series.categories.length || series.categoriesRef?.formula\n ? [{ level: 0, label: label == null ? \"\" : String(label) }]\n : []\n };\n })\n }))\n }\n });\n return svg ? safeChartSvg(svg, prefix) : null;\n } catch {\n return null;\n }\n}\n\nfunction selectionHandles(svg: Element, chartId: string, selected: XlsxChartElementSelection | null | undefined) {\n if (!selected || selected.chartId !== chartId || selected.kind === \"chart\") return null;\n return Array.from(svg.querySelectorAll(\"[data-chart-point]\")).map((node, index) => {\n if (Number(node.getAttribute(\"data-chart-series\")) !== selected.seriesIndex\n || (selected.kind === \"point\" && Number(node.getAttribute(\"data-chart-point\")) !== selected.pointIndex)) return null;\n if (node.getAttribute(\"data-chart-kind\") === \"bar\") {\n return renderSelectionRectHandles(String(index), Number(node.getAttribute(\"x\")), Number(node.getAttribute(\"y\")),\n Number(node.getAttribute(\"width\")), Number(node.getAttribute(\"height\")));\n }\n if (!node.hasAttribute(\"data-chart-x\") || !node.hasAttribute(\"data-chart-y\")) return null;\n return renderSelectionRectHandles(String(index), Number(node.getAttribute(\"data-chart-x\")) - 4,\n Number(node.getAttribute(\"data-chart-y\")) - 4, 8, 8);\n });\n}\n\nexport function SharedChartSvg(props: ChartSvgProps & {\n source: XlsxChartRenderSource;\n renderer: OfficeCharts;\n fallback: React.ReactNode;\n}) {\n const { chart, rect, renderer, source, selectedChartElement, fallback } = props;\n const id = React.useId();\n const width = Math.max(1, rect.width);\n const height = Math.max(1, rect.height);\n const svg = React.useMemo(() => renderSharedChart(renderer, chart, source, width, height,\n \"oc-\" + id.replace(/[^\\w-]/g, \"\") + \"-\"), [renderer, chart, source, width, height, id]);\n const graphics = React.useRef<SVGGElement>(null);\n React.useLayoutEffect(() => {\n if (graphics.current && svg) graphics.current.replaceChildren(svg);\n }, [svg]);\n const handles = React.useMemo(() => svg && selectionHandles(svg, chart.id, selectedChartElement),\n [svg, chart.id, selectedChartElement]);\n const { handlePointerDown, handleDoubleClick } = useChartEvents(props);\n if (!svg) return <>{fallback}</>;\n return (\n <svg\n aria-label={chart.title ?? chart.name ?? \"Chart\"}\n data-xlsx-chart-renderer=\"office-charts\"\n onDoubleClick={handleDoubleClick}\n onPointerDown={handlePointerDown}\n role=\"img\"\n style={{ display: \"block\", height: \"100%\", pointerEvents: \"auto\", width: \"100%\" }}\n viewBox={`0 0 ${width} ${height}`}\n >\n <g ref={graphics} />\n {handles}\n </svg>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAMA,IAAM,eAAe;AACrB,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAAO;AAAA,EAAK;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAY;AAAA,EACzF;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAkB;AAAA,EAAkB;AAAA,EAAQ;AAC/D,CAAC;AACD,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAAK;AAAA,EAAK;AAAA,EAAS;AAAA,EAAU;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAM;AAAA,EAC9F;AAAA,EAAW;AAAA,EAAa;AAAA,EAAK;AAAA,EAAU;AAAA,EAAe;AAAA,EAAe;AAAA,EAAa;AAAA,EAClF;AAAA,EAAqB;AAAA,EAAkB;AAAA,EAAmB;AAAA,EAAgB;AAAA,EAC1E;AAAA,EAAW;AAAA,EAAgB;AAAA,EAAkB;AAAA,EAAa;AAAA,EAAmB;AAAA,EAAU;AAAA,EACvF;AAAA,EAAiB;AAAA,EAAqB;AAAA,EAAgB;AAAA,EACtD;AAAA,EAAmB;AAAA,EAAqB;AAAA,EAAoB;AAAA,EAAgB;AAC9E,CAAC;AAED,SAAS,aAAa,QAAgB,QAAgB;AACpD,QAAM,MAAM,IAAI,UAAU,EAAE,gBAAgB,QAAQ,eAAe,EAAE;AACrE,MAAI,IAAI,cAAc,SAAS,IAAI,iBAAiB,aAAc,QAAO;AAGzE,aAAW,QAAQ,CAAC,KAAK,GAAG,MAAM,KAAK,IAAI,iBAAiB,GAAG,CAAC,CAAC,GAAG;AAClE,QAAI,KAAK,iBAAiB,gBAAgB,CAAC,gBAAgB,IAAI,KAAK,SAAS,EAAG,QAAO;AACvF,eAAW,EAAE,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU,GAAG;AACzD,UAAI,gBAAgB,IAAI,IAAI,KAAK,SAAS,QAAS;AACnD,UAAI,SAAS,QAAQ,WAAW,KAAK,KAAK,GAAG;AAC3C,aAAK,aAAa,MAAM,SAAS,KAAK;AACtC;AAAA,MACF;AACA,UAAI,SAAS,UAAU,oCAAoC,KAAK,KAAK,SAAS,KAAK,YAAY,KAAK,KAAK,GAAG;AAC1G,aAAK,aAAa,MAAM,MAAM,SAAS,MAAM,MAAM,CAAC,CAAC;AACrD;AAAA,MACF;AACA,UAAI,CAAC,QAAQ,UAAU,cAAc,WAAW,EAAE,SAAS,IAAI,GAAG;AAChE,cAAM,QAAQ,qBAAqB,KAAK,KAAK;AAC7C,YAAI,OAAO;AACT,eAAK,aAAa,MAAM,UAAU,SAAS,MAAM,CAAC,IAAI,GAAG;AACzD;AAAA,QACF;AACA,YAAI,8BAA8B,KAAK,KAAK,EAAG;AAAA,MACjD;AACA,WAAK,gBAAgB,IAAI;AAAA,IAC3B;AAEA,QAAI,KAAK,aAAa,mBAAmB,GAAG;AAC1C,WAAK,aAAa,gCAAgC,KAAK,aAAa,mBAAmB,CAAE;AACzF,YAAM,QAAQ,KAAK,aAAa,kBAAkB;AAClD,UAAI,SAAS,KAAM,MAAK,aAAa,+BAA+B,KAAK;AACzE,YAAM,OAAO,KAAK,aAAa,iBAAiB;AAChD,UAAI,SAAS,MAAO,MAAK,aAAa,kCAAkC,aAAa;AACrF,UAAI,SAAS,cAAe,MAAK,aAAa,gCAAgC,IAAI;AAClF,YAAM,QAAS,KAAoB;AACnC,YAAM,SAAS;AACf,YAAM,gBAAgB;AAAA,IACxB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,UAAwB,OAAkB,QAA+B,OAAe,QAAgB,QAAgB;AACjJ,MAAI;AACF,UAAM,MAAM,SAAS,YAAY,OAAO,KAAK;AAAA,MAC3C,aAAa,OAAO;AAAA,MACpB,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB,eAAe,OAAO;AAAA,MACtB;AAAA,MAAO;AAAA,MACP,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,YAAY,MAAM;AAAA,MAClB,MAAM;AAAA,QACJ,OAAO,MAAM;AAAA,QACb,QAAQ,MAAM,OAAO,IAAI,CAAC,YAAY;AAAA,UACpC,WAAW,OAAO;AAAA,UAClB,MAAM,OAAO;AAAA,UACb,QAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,OAAO,QAAQ,OAAO,WAAW,MAAM,EAAE,GAAG,CAACA,IAAG,UAAU;AACrG,kBAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,kBAAM,QAAQ,OAAO,WAAW,KAAK;AACrC,mBAAO;AAAA,cACL;AAAA,cACA,OAAO,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,cAC1C,YAAY,OAAO,WAAW,UAAU,OAAO,eAAe,UAC1D,CAAC,EAAE,OAAO,GAAG,OAAO,SAAS,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC,IACxD,CAAC;AAAA,YACP;AAAA,UACF,CAAC;AAAA,QACH,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AACD,WAAO,MAAM,aAAa,KAAK,MAAM,IAAI;AAAA,EAC3C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,KAAc,SAAiB,UAAwD;AAC/G,MAAI,CAAC,YAAY,SAAS,YAAY,WAAW,SAAS,SAAS,QAAS,QAAO;AACnF,SAAO,MAAM,KAAK,IAAI,iBAAiB,oBAAoB,CAAC,EAAE,IAAI,CAAC,MAAM,UAAU;AACjF,QAAI,OAAO,KAAK,aAAa,mBAAmB,CAAC,MAAM,SAAS,eAC1D,SAAS,SAAS,WAAW,OAAO,KAAK,aAAa,kBAAkB,CAAC,MAAM,SAAS,WAAa,QAAO;AAClH,QAAI,KAAK,aAAa,iBAAiB,MAAM,OAAO;AAClD,aAAO;AAAA,QAA2B,OAAO,KAAK;AAAA,QAAG,OAAO,KAAK,aAAa,GAAG,CAAC;AAAA,QAAG,OAAO,KAAK,aAAa,GAAG,CAAC;AAAA,QAC5G,OAAO,KAAK,aAAa,OAAO,CAAC;AAAA,QAAG,OAAO,KAAK,aAAa,QAAQ,CAAC;AAAA,MAAC;AAAA,IAC3E;AACA,QAAI,CAAC,KAAK,aAAa,cAAc,KAAK,CAAC,KAAK,aAAa,cAAc,EAAG,QAAO;AACrF,WAAO;AAAA,MAA2B,OAAO,KAAK;AAAA,MAAG,OAAO,KAAK,aAAa,cAAc,CAAC,IAAI;AAAA,MAC3F,OAAO,KAAK,aAAa,cAAc,CAAC,IAAI;AAAA,MAAG;AAAA,MAAG;AAAA,IAAC;AAAA,EACvD,CAAC;AACH;AAEO,SAAS,eAAe,OAI5B;AACD,QAAM,EAAE,OAAO,MAAM,UAAU,QAAQ,sBAAsB,SAAS,IAAI;AAC1E,QAAM,KAAW,EAAM;AACvB,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK;AACpC,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM;AACtC,QAAM,MAAY,EAAQ,MAAM;AAAA,IAAkB;AAAA,IAAU;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAO;AAAA,IAChF,QAAQ,GAAG,QAAQ,WAAW,EAAE,IAAI;AAAA,EAAG,GAAG,CAAC,UAAU,OAAO,QAAQ,OAAO,QAAQ,EAAE,CAAC;AACxF,QAAM,WAAiB,EAAoB,IAAI;AAC/C,EAAM,EAAgB,MAAM;AAC1B,QAAI,SAAS,WAAW,IAAK,UAAS,QAAQ,gBAAgB,GAAG;AAAA,EACnE,GAAG,CAAC,GAAG,CAAC;AACR,QAAM,UAAgB;AAAA,IAAQ,MAAM,OAAO,iBAAiB,KAAK,MAAM,IAAI,oBAAoB;AAAA,IAC7F,CAAC,KAAK,MAAM,IAAI,oBAAoB;AAAA,EAAC;AACvC,QAAM,EAAE,mBAAmB,kBAAkB,IAAI,eAAe,KAAK;AACrE,MAAI,CAAC,IAAK,QAAO,uBAAG,oBAAS;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,MAAM,SAAS,MAAM,QAAQ;AAAA,MACzC,4BAAyB;AAAA,MACzB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,MAAK;AAAA,MACL,OAAO,EAAE,SAAS,SAAS,QAAQ,QAAQ,eAAe,QAAQ,OAAO,OAAO;AAAA,MAChF,SAAS,OAAO,KAAK,IAAI,MAAM;AAAA,MAE/B;AAAA,0BAAC,OAAE,KAAK,UAAU;AAAA,QACjB;AAAA;AAAA;AAAA,EACH;AAEJ;","names":["_"]}
|