dishui 0.0.46 → 0.0.48

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 (115) hide show
  1. package/dist/chart.js +35 -33
  2. package/dist/components/Chart/index.d.ts +1 -1
  3. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js +1 -2
  4. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  5. package/dist/components/pro/CodeEditor/themes.js +0 -25
  6. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  7. package/dist/components/pro/CodeEditor/types.d.ts +1 -1
  8. package/dist/components/pro/DataTable/pivotExtension.d.ts +6 -0
  9. package/dist/components/pro/DataTable/pivotExtension.js +31 -30
  10. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  11. package/dist/components/pro/Flow/Flow.js +500 -459
  12. package/dist/components/pro/Flow/Flow.js.map +1 -1
  13. package/dist/components/pro/Flow/FlowCanvas.js +526 -524
  14. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  15. package/dist/components/pro/Flow/canvas/GridRenderer.d.ts +3 -0
  16. package/dist/components/pro/Flow/canvas/GridRenderer.js +28 -23
  17. package/dist/components/pro/Flow/canvas/GridRenderer.js.map +1 -1
  18. package/dist/components/pro/Flow/canvas/MiniMapRenderer.js +18 -17
  19. package/dist/components/pro/Flow/canvas/MiniMapRenderer.js.map +1 -1
  20. package/dist/components/pro/Flow/canvas/PixiApp.d.ts +24 -0
  21. package/dist/components/pro/Flow/canvas/PixiApp.js +60 -15
  22. package/dist/components/pro/Flow/canvas/PixiApp.js.map +1 -1
  23. package/dist/components/pro/Flow/constants.js +7 -7
  24. package/dist/components/pro/Flow/constants.js.map +1 -1
  25. package/dist/components/pro/Flow/context/FlowAIContext.d.ts +15 -0
  26. package/dist/components/pro/Flow/context/FlowAIContext.js +32 -0
  27. package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -0
  28. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +4 -1
  29. package/dist/components/pro/Flow/context/FlowUIContext.js +58 -55
  30. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  31. package/dist/components/pro/Flow/edges/EdgeRenderer.js +22 -21
  32. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  33. package/dist/components/pro/Flow/hooks/useFlowImportExport.d.ts +6 -0
  34. package/dist/components/pro/Flow/hooks/useFlowImportExport.js +146 -89
  35. package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
  36. package/dist/components/pro/Flow/hooks/useLayoutActions.d.ts +2 -0
  37. package/dist/components/pro/Flow/hooks/useLayoutActions.js +94 -65
  38. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  39. package/dist/components/pro/Flow/hooks/usePdfExport.d.ts +10 -0
  40. package/dist/components/pro/Flow/hooks/usePdfExport.js +60 -0
  41. package/dist/components/pro/Flow/hooks/usePdfExport.js.map +1 -0
  42. package/dist/components/pro/Flow/hooks/usePixiApp.d.ts +6 -1
  43. package/dist/components/pro/Flow/hooks/usePixiApp.js +49 -30
  44. package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
  45. package/dist/components/pro/Flow/index.d.ts +5 -2
  46. package/dist/components/pro/Flow/lines/FreehandTool.js +21 -20
  47. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  48. package/dist/components/pro/Flow/lines/GeometricLineTool.js +22 -18
  49. package/dist/components/pro/Flow/lines/GeometricLineTool.js.map +1 -1
  50. package/dist/components/pro/Flow/lines/LineRenderer.js +19 -18
  51. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  52. package/dist/components/pro/Flow/nodes/DataNodeView.d.ts +7 -0
  53. package/dist/components/pro/Flow/nodes/DataNodeView.js +217 -0
  54. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -0
  55. package/dist/components/pro/Flow/nodes/MediaContent.js +149 -120
  56. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  57. package/dist/components/pro/Flow/nodes/MediaOverlay.js +22 -17
  58. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  59. package/dist/components/pro/Flow/nodes/NodeRenderer.js +77 -76
  60. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  61. package/dist/components/pro/Flow/nodes/aiClient.d.ts +22 -0
  62. package/dist/components/pro/Flow/nodes/aiClient.js +107 -54
  63. package/dist/components/pro/Flow/nodes/aiClient.js.map +1 -1
  64. package/dist/components/pro/Flow/nodes/dataUtils.d.ts +52 -0
  65. package/dist/components/pro/Flow/nodes/dataUtils.js +270 -0
  66. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -0
  67. package/dist/components/pro/Flow/nodes/svgIcons.js +59 -27
  68. package/dist/components/pro/Flow/nodes/svgIcons.js.map +1 -1
  69. package/dist/components/pro/Flow/panels/AIPanel.d.ts +2 -0
  70. package/dist/components/pro/Flow/panels/AIPanel.js +498 -0
  71. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -0
  72. package/dist/components/pro/Flow/panels/DataInspectorSection.d.ts +11 -0
  73. package/dist/components/pro/Flow/panels/DataInspectorSection.js +436 -0
  74. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -0
  75. package/dist/components/pro/Flow/panels/ExpandableTextarea.d.ts +16 -0
  76. package/dist/components/pro/Flow/panels/ExpandableTextarea.js +65 -0
  77. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -0
  78. package/dist/components/pro/Flow/panels/FlowPanelGroup.js +51 -39
  79. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  80. package/dist/components/pro/Flow/panels/FlowToolbar.d.ts +5 -1
  81. package/dist/components/pro/Flow/panels/FlowToolbar.js +310 -233
  82. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  83. package/dist/components/pro/Flow/panels/InspectorPanel.js +358 -363
  84. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  85. package/dist/components/pro/Flow/panels/OutlinePanel.js +63 -62
  86. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  87. package/dist/components/pro/Flow/panels/ProjectTitle.d.ts +8 -0
  88. package/dist/components/pro/Flow/panels/ProjectTitle.js +49 -0
  89. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -0
  90. package/dist/components/pro/Flow/panels/ShapePalette.js +128 -115
  91. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  92. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +13 -0
  93. package/dist/components/pro/Flow/panels/toolbarIcons.js +241 -87
  94. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  95. package/dist/components/pro/Flow/types.d.ts +77 -1
  96. package/dist/components/pro/Flow/types.js.map +1 -1
  97. package/dist/components/pro/Flow/utils/pdfExport.d.ts +20 -0
  98. package/dist/components/pro/Flow/utils/pdfExport.js +95 -0
  99. package/dist/components/pro/Flow/utils/pdfExport.js.map +1 -0
  100. package/dist/components/pro/Flow/utils/themeColor.d.ts +86 -0
  101. package/dist/components/pro/Flow/utils/themeColor.js +190 -0
  102. package/dist/components/pro/Flow/utils/themeColor.js.map +1 -0
  103. package/dist/contexts/AppContext.d.ts +1 -1
  104. package/dist/contexts/AppContext.js +28 -29
  105. package/dist/contexts/AppContext.js.map +1 -1
  106. package/dist/dishui.css +1 -1
  107. package/dist/favicon.svg +10 -0
  108. package/dist/flow.js +59 -51
  109. package/dist/index-nostyled.d.ts +1 -1
  110. package/dist/index.d.ts +1 -1
  111. package/dist/styles/themeStyles.js +6 -11
  112. package/dist/styles/themeStyles.js.map +1 -1
  113. package/dist/utils/themes.js +3 -23
  114. package/dist/utils/themes.js.map +1 -1
  115. package/package.json +17 -18
@@ -0,0 +1,436 @@
1
+ import u from "../../../Button/index.js";
2
+ import j from "../../../Input/index.js";
3
+ import y from "../../../Label/index.js";
4
+ import f from "../../../Select/index.js";
5
+ import { DATA_CHART_PALETTE as w, applyCsvText as $, labelFor as z, makeDefaultDataConfig as E, matrixToTable as G, numericFields as W, parseCsv as X, parseDataFile as q, toCsv as J } from "../nodes/dataUtils.js";
6
+ import { ExpandableTextarea as K } from "./ExpandableTextarea.js";
7
+ import { useEffect as Q, useMemo as Z, useRef as O, useState as U } from "react";
8
+ import { Fragment as N, jsx as s, jsxs as n } from "react/jsx-runtime";
9
+ var ee = [
10
+ {
11
+ value: "string",
12
+ label: "文本"
13
+ },
14
+ {
15
+ value: "number",
16
+ label: "数值"
17
+ },
18
+ {
19
+ value: "date",
20
+ label: "日期"
21
+ },
22
+ {
23
+ value: "boolean",
24
+ label: "布尔"
25
+ }
26
+ ], le = [
27
+ {
28
+ value: "bar",
29
+ label: "柱状图"
30
+ },
31
+ {
32
+ value: "barHorizontal",
33
+ label: "横向柱状图"
34
+ },
35
+ {
36
+ value: "line",
37
+ label: "折线图"
38
+ },
39
+ {
40
+ value: "area",
41
+ label: "面积图"
42
+ },
43
+ {
44
+ value: "scatter",
45
+ label: "散点图"
46
+ },
47
+ {
48
+ value: "pie",
49
+ label: "饼图"
50
+ }
51
+ ], te = [
52
+ {
53
+ value: "top",
54
+ label: "上方"
55
+ },
56
+ {
57
+ value: "bottom",
58
+ label: "下方"
59
+ },
60
+ {
61
+ value: "left",
62
+ label: "左侧"
63
+ },
64
+ {
65
+ value: "right",
66
+ label: "右侧"
67
+ }
68
+ ], se = {
69
+ columns: [],
70
+ rows: [],
71
+ view: "table"
72
+ };
73
+ function ue({ node: h, onUpdateData: b }) {
74
+ const t = h.data.dataConfig ?? se, x = O(null), p = (e) => {
75
+ b(h.id, "dataConfig", {
76
+ ...t,
77
+ ...e
78
+ });
79
+ }, m = Z(() => J(t.columns, t.rows), [t.columns, t.rows]), [A, k] = U(m), g = O(m);
80
+ Q(() => {
81
+ m !== g.current && (g.current = m, k(m));
82
+ }, [m]);
83
+ const I = (e) => {
84
+ e !== g.current && (g.current = e, b(h.id, "dataConfig", $(t, e)));
85
+ }, V = async (e) => {
86
+ try {
87
+ const l = await q(e);
88
+ if (l.columns.length === 0) {
89
+ window.alert("未能从文件中解析出任何数据。");
90
+ return;
91
+ }
92
+ b(h.id, "dataConfig", E(l, e.name));
93
+ } catch (l) {
94
+ window.alert(`解析失败:${l?.message ?? l}`);
95
+ }
96
+ }, F = (e, l) => {
97
+ const o = t.columns.map((r, i) => i === e ? {
98
+ ...r,
99
+ ...l
100
+ } : r);
101
+ p({ columns: o });
102
+ }, D = () => {
103
+ const e = new Set(t.columns.map((v) => v.key));
104
+ let l = "col", o = 1;
105
+ for (; e.has(l); ) l = `col_${o++}`;
106
+ const r = [...t.columns, {
107
+ key: l,
108
+ label: l,
109
+ type: "string"
110
+ }], i = t.rows.map((v) => ({
111
+ ...v,
112
+ [l]: ""
113
+ }));
114
+ p({
115
+ columns: r,
116
+ rows: i
117
+ });
118
+ }, R = (e) => {
119
+ const l = t.columns[e], o = t.columns.filter((c, _) => _ !== e), r = t.rows.map((c) => {
120
+ const { [l.key]: _, ...Y } = c;
121
+ return Y;
122
+ }), i = t.chart ? {
123
+ ...t.chart,
124
+ xField: t.chart.xField === l.key ? o.find((c) => c.type !== "number")?.key ?? o[0]?.key : t.chart.xField,
125
+ yFields: (t.chart.yFields ?? []).filter((c) => c !== l.key)
126
+ } : t.chart, v = t.pivot ? {
127
+ ...t.pivot,
128
+ rowFields: t.pivot.rowFields.filter((c) => c !== l.key),
129
+ colFields: t.pivot.colFields.filter((c) => c !== l.key),
130
+ values: t.pivot.values.filter((c) => c.field !== l.key)
131
+ } : t.pivot;
132
+ p({
133
+ columns: o,
134
+ rows: r,
135
+ chart: i,
136
+ pivot: v
137
+ });
138
+ }, L = () => {
139
+ const e = window.prompt("粘贴 CSV 文本(第一行为表头):");
140
+ if (!e) return;
141
+ const l = G(X(e));
142
+ if (l.columns.length === 0) {
143
+ window.alert("未能解析出数据。");
144
+ return;
145
+ }
146
+ b(h.id, "dataConfig", E(l));
147
+ }, T = W(t.columns), a = t.chart ?? { type: "bar" }, d = (e) => p({ chart: {
148
+ ...a,
149
+ ...e
150
+ } }), M = (e, l) => {
151
+ d({ seriesColors: {
152
+ ...a.seriesColors ?? {},
153
+ [e]: l
154
+ } });
155
+ }, B = (e) => {
156
+ const l = { ...a.seriesColors ?? {} };
157
+ delete l[e], d({ seriesColors: Object.keys(l).length ? l : void 0 });
158
+ }, S = a.palette?.length ? a.palette : w, H = (e, l) => {
159
+ const o = w.map((r, i) => i === e ? l : a.palette?.[i] ?? r);
160
+ d({ palette: o });
161
+ }, C = t.pivot ?? {
162
+ enabled: !1,
163
+ rowFields: [],
164
+ colFields: [],
165
+ values: []
166
+ }, P = (e) => p({ pivot: {
167
+ ...C,
168
+ ...e
169
+ } });
170
+ return /* @__PURE__ */ n("div", {
171
+ className: "flow-inspector-section",
172
+ children: [
173
+ /* @__PURE__ */ s("div", {
174
+ className: "flow-inspector-section-title",
175
+ children: "Data"
176
+ }),
177
+ /* @__PURE__ */ n("div", {
178
+ className: "flow-inspector-row",
179
+ children: [
180
+ /* @__PURE__ */ s("input", {
181
+ ref: x,
182
+ type: "file",
183
+ accept: ".csv,.tsv,.txt,.xlsx,.xlsm,text/csv",
184
+ hidden: !0,
185
+ onChange: (e) => {
186
+ const l = e.target.files?.[0];
187
+ e.target.value = "", l && V(l);
188
+ }
189
+ }),
190
+ /* @__PURE__ */ s(u, {
191
+ size: "xs",
192
+ variant: "neutral",
193
+ onClick: () => x.current?.click(),
194
+ children: "上传 CSV / Excel"
195
+ }),
196
+ /* @__PURE__ */ s(u, {
197
+ size: "xs",
198
+ variant: "ghost",
199
+ onClick: L,
200
+ children: "粘贴 CSV"
201
+ })
202
+ ]
203
+ }),
204
+ t.sourceName && /* @__PURE__ */ n("div", {
205
+ className: "flow-inspector-help",
206
+ children: ["来源:", t.sourceName]
207
+ }),
208
+ /* @__PURE__ */ n("div", {
209
+ className: "flow-inspector-row",
210
+ children: [/* @__PURE__ */ s(y, {
211
+ size: "xs",
212
+ className: "flow-inspector-label",
213
+ children: "视图"
214
+ }), /* @__PURE__ */ s(f, {
215
+ options: [{
216
+ value: "table",
217
+ label: "表格 / 透视"
218
+ }, {
219
+ value: "chart",
220
+ label: "图表"
221
+ }],
222
+ value: t.view,
223
+ onChange: (e) => p({ view: e })
224
+ })]
225
+ }),
226
+ /* @__PURE__ */ n("div", {
227
+ className: "flow-inspector-subtitle",
228
+ children: [
229
+ "列配置(",
230
+ t.columns.length,
231
+ ")"
232
+ ]
233
+ }),
234
+ t.columns.map((e, l) => /* @__PURE__ */ n("div", {
235
+ className: "flow-data-col-row",
236
+ children: [
237
+ /* @__PURE__ */ s(j, {
238
+ size: "xs",
239
+ value: e.label ?? e.key,
240
+ placeholder: "列名",
241
+ onChange: (o) => F(l, { label: o.target.value }),
242
+ className: "flex-1"
243
+ }),
244
+ /* @__PURE__ */ s(f, {
245
+ options: ee,
246
+ value: e.type,
247
+ onChange: (o) => F(l, { type: o })
248
+ }),
249
+ /* @__PURE__ */ s(u, {
250
+ size: "xs",
251
+ variant: "ghost",
252
+ onClick: () => R(l),
253
+ children: "✕"
254
+ })
255
+ ]
256
+ }, l)),
257
+ /* @__PURE__ */ s("div", {
258
+ className: "flow-inspector-row",
259
+ children: /* @__PURE__ */ s(u, {
260
+ size: "xs",
261
+ variant: "ghost",
262
+ onClick: D,
263
+ children: "+ 添加列"
264
+ })
265
+ }),
266
+ /* @__PURE__ */ n("div", {
267
+ className: "flow-inspector-subtitle",
268
+ children: [
269
+ "数据(CSV · ",
270
+ t.rows.length,
271
+ " 行)"
272
+ ]
273
+ }),
274
+ /* @__PURE__ */ s(K, {
275
+ label: "CSV 数据(首行为表头)",
276
+ value: A,
277
+ onChange: k,
278
+ onBlur: I,
279
+ rows: 8,
280
+ placeholder: `类别,数值
281
+ A,30
282
+ B,45`
283
+ }),
284
+ /* @__PURE__ */ s("div", {
285
+ className: "flow-inspector-help",
286
+ children: "直接编辑 CSV 文本,失焦或关闭全屏后生效。已有列的类型会保留。"
287
+ }),
288
+ t.view === "chart" && /* @__PURE__ */ n(N, { children: [
289
+ /* @__PURE__ */ s("div", {
290
+ className: "flow-inspector-subtitle",
291
+ children: "图表配置"
292
+ }),
293
+ /* @__PURE__ */ n("div", {
294
+ className: "flow-inspector-row",
295
+ children: [/* @__PURE__ */ s(y, {
296
+ size: "xs",
297
+ className: "flow-inspector-label",
298
+ children: "类型"
299
+ }), /* @__PURE__ */ s(f, {
300
+ options: le,
301
+ value: a.type,
302
+ onChange: (e) => d({ type: e })
303
+ })]
304
+ }),
305
+ /* @__PURE__ */ n("div", {
306
+ className: "flow-inspector-row",
307
+ children: [/* @__PURE__ */ s(y, {
308
+ size: "xs",
309
+ className: "flow-inspector-label",
310
+ children: a.type === "scatter" ? "X 字段" : "类别轴"
311
+ }), /* @__PURE__ */ s(f, {
312
+ options: t.columns.map((e) => ({
313
+ value: e.key,
314
+ label: e.label ?? e.key
315
+ })),
316
+ value: a.xField ?? "",
317
+ onChange: (e) => d({ xField: typeof e == "string" ? e : String(e) })
318
+ })]
319
+ }),
320
+ /* @__PURE__ */ s("div", {
321
+ className: "flow-inspector-subtitle-sm",
322
+ children: a.type === "scatter" || a.type === "pie" ? "数值字段" : "数值字段(可多选,多系列)"
323
+ }),
324
+ T.length === 0 && /* @__PURE__ */ s("div", {
325
+ className: "flow-inspector-help",
326
+ children: "没有数值列,请先将某列类型设为「数值」。"
327
+ }),
328
+ T.map((e) => {
329
+ const l = (a.yFields ?? []).includes(e), o = a.type === "scatter" || a.type === "pie";
330
+ return /* @__PURE__ */ n("label", {
331
+ className: "flow-data-field-toggle",
332
+ children: [/* @__PURE__ */ s("input", {
333
+ type: o ? "radio" : "checkbox",
334
+ className: o ? "radio radio-xs radio-primary" : "checkbox checkbox-xs checkbox-primary",
335
+ checked: l,
336
+ onChange: (r) => {
337
+ if (o) {
338
+ d({ yFields: [e] });
339
+ return;
340
+ }
341
+ const i = new Set(a.yFields ?? []);
342
+ r.target.checked ? i.add(e) : i.delete(e), d({ yFields: Array.from(i) });
343
+ }
344
+ }), /* @__PURE__ */ s("span", { children: z(t.columns, e) })]
345
+ }, e);
346
+ }),
347
+ (a.yFields ?? []).length > 0 && a.type !== "pie" && /* @__PURE__ */ n(N, { children: [/* @__PURE__ */ s("div", {
348
+ className: "flow-inspector-subtitle-sm",
349
+ children: "系列颜色"
350
+ }), (a.yFields ?? []).map((e, l) => {
351
+ const o = a.seriesColors?.[e] ?? w[l % w.length], r = !!a.seriesColors?.[e];
352
+ return /* @__PURE__ */ n("div", {
353
+ className: "flow-data-color-row",
354
+ children: [
355
+ /* @__PURE__ */ s("input", {
356
+ type: "color",
357
+ value: o,
358
+ onChange: (i) => M(e, i.target.value)
359
+ }),
360
+ /* @__PURE__ */ s("span", {
361
+ className: "flow-data-color-label",
362
+ children: z(t.columns, e)
363
+ }),
364
+ r && /* @__PURE__ */ s(u, {
365
+ size: "xs",
366
+ variant: "ghost",
367
+ onClick: () => B(e),
368
+ children: "重置"
369
+ })
370
+ ]
371
+ }, e);
372
+ })] }),
373
+ a.type === "pie" && /* @__PURE__ */ n(N, { children: [
374
+ /* @__PURE__ */ s("div", {
375
+ className: "flow-inspector-subtitle-sm",
376
+ children: "饼图配色"
377
+ }),
378
+ /* @__PURE__ */ s("div", {
379
+ className: "flow-data-palette",
380
+ children: w.map((e, l) => /* @__PURE__ */ s("input", {
381
+ type: "color",
382
+ value: S[l % S.length],
383
+ onChange: (o) => H(l, o.target.value)
384
+ }, l))
385
+ }),
386
+ a.palette && /* @__PURE__ */ s("div", {
387
+ className: "flow-inspector-row",
388
+ children: /* @__PURE__ */ s(u, {
389
+ size: "xs",
390
+ variant: "ghost",
391
+ onClick: () => d({ palette: void 0 }),
392
+ children: "重置为默认配色"
393
+ })
394
+ })
395
+ ] })
396
+ ] }),
397
+ t.view === "table" && /* @__PURE__ */ n(N, { children: [
398
+ /* @__PURE__ */ s("div", {
399
+ className: "flow-inspector-subtitle",
400
+ children: "透视(Pivot)"
401
+ }),
402
+ /* @__PURE__ */ n("label", {
403
+ className: "flow-data-field-toggle",
404
+ children: [/* @__PURE__ */ s("input", {
405
+ type: "checkbox",
406
+ className: "toggle toggle-xs toggle-primary",
407
+ checked: C.enabled,
408
+ onChange: (e) => P({ enabled: e.target.checked })
409
+ }), /* @__PURE__ */ s("span", { children: "开启透视模式" })]
410
+ }),
411
+ C.enabled && /* @__PURE__ */ n("div", {
412
+ className: "flow-inspector-row",
413
+ children: [/* @__PURE__ */ s(y, {
414
+ size: "xs",
415
+ className: "flow-inspector-label",
416
+ children: "面板位置"
417
+ }), /* @__PURE__ */ s(f, {
418
+ options: te,
419
+ value: C.panelPlacement ?? "top",
420
+ onChange: (e) => P({ panelPlacement: e })
421
+ })]
422
+ }),
423
+ /* @__PURE__ */ s("div", {
424
+ className: "flow-inspector-help",
425
+ children: "透视的行/列/度量可在画布节点内的透视面板上交互拖拽调整。"
426
+ })
427
+ ] })
428
+ ]
429
+ });
430
+ }
431
+ export {
432
+ ue as DataInspectorSection,
433
+ ue as default
434
+ };
435
+
436
+ //# sourceMappingURL=DataInspectorSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataInspectorSection.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/DataInspectorSection.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport Input from '../../../Input';\nimport Select from '../../../Select';\nimport Button from '../../../Button';\nimport Label from '../../../Label';\nimport { ExpandableTextarea } from './ExpandableTextarea';\nimport type {\n FlowNode,\n FlowDataConfig,\n FlowDataColumn,\n FlowDataColumnType,\n FlowDataChartType,\n FlowDataView,\n FlowDataPivotPanelPlacement,\n} from '../types';\nimport {\n parseDataFile,\n parseCsv,\n matrixToTable,\n makeDefaultDataConfig,\n applyCsvText,\n toCsv,\n numericFields,\n labelFor,\n DATA_CHART_PALETTE,\n} from '../nodes/dataUtils';\n\nconst COLUMN_TYPE_OPTIONS: Array<{ value: FlowDataColumnType; label: string }> = [\n { value: 'string', label: '文本' },\n { value: 'number', label: '数值' },\n { value: 'date', label: '日期' },\n { value: 'boolean', label: '布尔' },\n];\n\nconst CHART_TYPE_OPTIONS: Array<{ value: FlowDataChartType; label: string }> = [\n { value: 'bar', label: '柱状图' },\n { value: 'barHorizontal', label: '横向柱状图' },\n { value: 'line', label: '折线图' },\n { value: 'area', label: '面积图' },\n { value: 'scatter', label: '散点图' },\n { value: 'pie', label: '饼图' },\n];\n\nconst PIVOT_PLACEMENT_OPTIONS: Array<{ value: FlowDataPivotPanelPlacement; label: string }> = [\n { value: 'top', label: '上方' },\n { value: 'bottom', label: '下方' },\n { value: 'left', label: '左侧' },\n { value: 'right', label: '右侧' },\n];\n\nconst EMPTY_CONFIG: FlowDataConfig = { columns: [], rows: [], view: 'table' };\n\n/**\n * Inspector controls for a Data node: upload CSV/Excel, edit columns, edit rows\n * as CSV text (with fullscreen), and configure the table (pivot) or chart view.\n */\nexport function DataInspectorSection({\n node,\n onUpdateData,\n}: {\n node: FlowNode;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n const config = node.data.dataConfig ?? EMPTY_CONFIG;\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const update = (patch: Partial<FlowDataConfig>) => {\n onUpdateData(node.id, 'dataConfig', { ...config, ...patch });\n };\n\n // ── CSV text editing (local draft, committed on blur) ────────────────────\n // The textarea edits a CSV serialization of columns+rows. We keep a local\n // draft so typing isn't interrupted by re-parsing; the parse (which re-infers\n // nothing for known columns and preserves chart/pivot field refs) runs once\n // on blur / fullscreen close. When the config changes externally (upload,\n // paste), the draft is re-synced.\n const csvText = useMemo(() => toCsv(config.columns, config.rows), [config.columns, config.rows]);\n const [csvDraft, setCsvDraft] = useState(csvText);\n const lastCommitted = useRef(csvText);\n useEffect(() => {\n if (csvText !== lastCommitted.current) {\n lastCommitted.current = csvText;\n setCsvDraft(csvText);\n }\n }, [csvText]);\n\n const commitCsv = (text: string) => {\n if (text === lastCommitted.current) return;\n lastCommitted.current = text;\n onUpdateData(node.id, 'dataConfig', applyCsvText(config, text));\n };\n\n // ── File upload ────────────────────────────────────────────────────────\n const handleFile = async (file: File) => {\n try {\n const parsed = await parseDataFile(file);\n if (parsed.columns.length === 0) {\n window.alert('未能从文件中解析出任何数据。');\n return;\n }\n onUpdateData(node.id, 'dataConfig', makeDefaultDataConfig(parsed, file.name));\n } catch (e: any) {\n window.alert(`解析失败:${e?.message ?? e}`);\n }\n };\n\n // ── Column editing ─────────────────────────────────────────────────────\n const setColumn = (index: number, patch: Partial<FlowDataColumn>) => {\n const columns = config.columns.map((c, i) => (i === index ? { ...c, ...patch } : c));\n update({ columns });\n };\n\n const addColumn = () => {\n const used = new Set(config.columns.map((c) => c.key));\n let key = 'col';\n let n = 1;\n while (used.has(key)) key = `col_${n++}`;\n const columns: FlowDataColumn[] = [...config.columns, { key, label: key, type: 'string' }];\n // pad existing rows with an empty value for the new column\n const rows = config.rows.map((r) => ({ ...r, [key]: '' }));\n update({ columns, rows });\n };\n\n const removeColumn = (index: number) => {\n const col = config.columns[index];\n const columns = config.columns.filter((_, i) => i !== index);\n const rows = config.rows.map((r) => {\n const { [col.key]: _drop, ...rest } = r;\n return rest;\n });\n // prune chart/pivot references to the removed column\n const chart = config.chart\n ? {\n ...config.chart,\n xField: config.chart.xField === col.key ? columns.find((c) => c.type !== 'number')?.key ?? columns[0]?.key : config.chart.xField,\n yFields: (config.chart.yFields ?? []).filter((f) => f !== col.key),\n }\n : config.chart;\n const pivot = config.pivot\n ? {\n ...config.pivot,\n rowFields: config.pivot.rowFields.filter((f) => f !== col.key),\n colFields: config.pivot.colFields.filter((f) => f !== col.key),\n values: config.pivot.values.filter((v) => v.field !== col.key),\n }\n : config.pivot;\n update({ columns, rows, chart, pivot });\n };\n\n // ── Paste CSV (replace whole table) ─────────────────────────────────────\n const pasteCsv = () => {\n const text = window.prompt('粘贴 CSV 文本(第一行为表头):');\n if (!text) return;\n const parsed = matrixToTable(parseCsv(text));\n if (parsed.columns.length === 0) {\n window.alert('未能解析出数据。');\n return;\n }\n onUpdateData(node.id, 'dataConfig', makeDefaultDataConfig(parsed));\n };\n\n const nums = numericFields(config.columns);\n const chart = config.chart ?? { type: 'bar' as FlowDataChartType };\n const setChart = (patch: Partial<typeof chart>) => update({ chart: { ...chart, ...patch } });\n\n const setSeriesColor = (field: string, color: string) => {\n setChart({ seriesColors: { ...(chart.seriesColors ?? {}), [field]: color } });\n };\n const resetSeriesColor = (field: string) => {\n const next = { ...(chart.seriesColors ?? {}) };\n delete next[field];\n setChart({ seriesColors: Object.keys(next).length ? next : undefined });\n };\n\n const palette = chart.palette?.length ? chart.palette : DATA_CHART_PALETTE;\n const setPaletteColor = (i: number, color: string) => {\n const next = DATA_CHART_PALETTE.map((c, j) => (j === i ? color : (chart.palette?.[j] ?? c)));\n setChart({ palette: next });\n };\n\n const pivot = config.pivot ?? { enabled: false, rowFields: [], colFields: [], values: [] };\n const setPivot = (patch: Partial<typeof pivot>) => update({ pivot: { ...pivot, ...patch } });\n\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Data</div>\n\n {/* Import controls */}\n <div className=\"flow-inspector-row\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".csv,.tsv,.txt,.xlsx,.xlsm,text/csv\"\n hidden\n onChange={(e) => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (file) void handleFile(file);\n }}\n />\n <Button size=\"xs\" variant=\"neutral\" onClick={() => fileInputRef.current?.click()}>\n 上传 CSV / Excel\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={pasteCsv}>\n 粘贴 CSV\n </Button>\n </div>\n {config.sourceName && (\n <div className=\"flow-inspector-help\">来源:{config.sourceName}</div>\n )}\n\n {/* View toggle */}\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">视图</Label>\n <Select\n options={[\n { value: 'table', label: '表格 / 透视' },\n { value: 'chart', label: '图表' },\n ]}\n value={config.view}\n onChange={(v) => update({ view: v as FlowDataView })}\n />\n </div>\n\n {/* Columns editor */}\n <div className=\"flow-inspector-subtitle\">列配置({config.columns.length})</div>\n {config.columns.map((col, i) => (\n <div key={i} className=\"flow-data-col-row\">\n <Input\n size=\"xs\"\n value={col.label ?? col.key}\n placeholder=\"列名\"\n onChange={(e) => setColumn(i, { label: e.target.value })}\n className=\"flex-1\"\n />\n <Select\n options={COLUMN_TYPE_OPTIONS}\n value={col.type}\n onChange={(v) => setColumn(i, { type: v as FlowDataColumnType })}\n />\n <Button size=\"xs\" variant=\"ghost\" onClick={() => removeColumn(i)}>\n ✕\n </Button>\n </div>\n ))}\n <div className=\"flow-inspector-row\">\n <Button size=\"xs\" variant=\"ghost\" onClick={addColumn}>+ 添加列</Button>\n </div>\n\n {/* Rows editor: CSV text with fullscreen */}\n <div className=\"flow-inspector-subtitle\">数据(CSV · {config.rows.length} 行)</div>\n <ExpandableTextarea\n label=\"CSV 数据(首行为表头)\"\n value={csvDraft}\n onChange={setCsvDraft}\n onBlur={commitCsv}\n rows={8}\n placeholder=\"类别,数值&#10;A,30&#10;B,45\"\n />\n <div className=\"flow-inspector-help\">\n 直接编辑 CSV 文本,失焦或关闭全屏后生效。已有列的类型会保留。\n </div>\n\n {/* Chart config */}\n {config.view === 'chart' && (\n <>\n <div className=\"flow-inspector-subtitle\">图表配置</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">类型</Label>\n <Select\n options={CHART_TYPE_OPTIONS}\n value={chart.type}\n onChange={(v) => setChart({ type: v as FlowDataChartType })}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">\n {chart.type === 'scatter' ? 'X 字段' : '类别轴'}\n </Label>\n <Select\n options={config.columns.map((c) => ({ value: c.key, label: c.label ?? c.key }))}\n value={chart.xField ?? ''}\n onChange={(v) => setChart({ xField: typeof v === 'string' ? v : String(v) })}\n />\n </div>\n <div className=\"flow-inspector-subtitle-sm\">\n {chart.type === 'scatter' || chart.type === 'pie' ? '数值字段' : '数值字段(可多选,多系列)'}\n </div>\n {nums.length === 0 && (\n <div className=\"flow-inspector-help\">没有数值列,请先将某列类型设为「数值」。</div>\n )}\n {nums.map((f) => {\n const selected = (chart.yFields ?? []).includes(f);\n const single = chart.type === 'scatter' || chart.type === 'pie';\n return (\n <label key={f} className=\"flow-data-field-toggle\">\n <input\n type={single ? 'radio' : 'checkbox'}\n className={single ? 'radio radio-xs radio-primary' : 'checkbox checkbox-xs checkbox-primary'}\n checked={selected}\n onChange={(e) => {\n if (single) {\n setChart({ yFields: [f] });\n return;\n }\n const current = new Set(chart.yFields ?? []);\n if (e.target.checked) current.add(f);\n else current.delete(f);\n setChart({ yFields: Array.from(current) });\n }}\n />\n <span>{labelFor(config.columns, f)}</span>\n </label>\n );\n })}\n\n {/* Chart colors */}\n {(chart.yFields ?? []).length > 0 && chart.type !== 'pie' && (\n <>\n <div className=\"flow-inspector-subtitle-sm\">系列颜色</div>\n {(chart.yFields ?? []).map((f, i) => {\n const color = chart.seriesColors?.[f] ?? DATA_CHART_PALETTE[i % DATA_CHART_PALETTE.length];\n const overridden = !!chart.seriesColors?.[f];\n return (\n <div key={f} className=\"flow-data-color-row\">\n <input\n type=\"color\"\n value={color}\n onChange={(e) => setSeriesColor(f, e.target.value)}\n />\n <span className=\"flow-data-color-label\">{labelFor(config.columns, f)}</span>\n {overridden && (\n <Button size=\"xs\" variant=\"ghost\" onClick={() => resetSeriesColor(f)}>\n 重置\n </Button>\n )}\n </div>\n );\n })}\n </>\n )}\n {chart.type === 'pie' && (\n <>\n <div className=\"flow-inspector-subtitle-sm\">饼图配色</div>\n <div className=\"flow-data-palette\">\n {DATA_CHART_PALETTE.map((_, i) => (\n <input\n key={i}\n type=\"color\"\n value={palette[i % palette.length]}\n onChange={(e) => setPaletteColor(i, e.target.value)}\n />\n ))}\n </div>\n {chart.palette && (\n <div className=\"flow-inspector-row\">\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setChart({ palette: undefined })}>\n 重置为默认配色\n </Button>\n </div>\n )}\n </>\n )}\n </>\n )}\n\n {/* Pivot config */}\n {config.view === 'table' && (\n <>\n <div className=\"flow-inspector-subtitle\">透视(Pivot)</div>\n <label className=\"flow-data-field-toggle\">\n <input\n type=\"checkbox\"\n className=\"toggle toggle-xs toggle-primary\"\n checked={pivot.enabled}\n onChange={(e) => setPivot({ enabled: e.target.checked })}\n />\n <span>开启透视模式</span>\n </label>\n {pivot.enabled && (\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">面板位置</Label>\n <Select\n options={PIVOT_PLACEMENT_OPTIONS}\n value={pivot.panelPlacement ?? 'top'}\n onChange={(v) => setPivot({ panelPlacement: v as FlowDataPivotPanelPlacement })}\n />\n </div>\n )}\n <div className=\"flow-inspector-help\">\n 透视的行/列/度量可在画布节点内的透视面板上交互拖拽调整。\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport default DataInspectorSection;\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ /**
3
+ * Textarea with a "fullscreen" expand button. The fullscreen overlay edits the
4
+ * same value; `onBlur`/`onDone` let callers commit expensive parses only when
5
+ * editing finishes instead of on every keystroke.
6
+ */
7
+ export declare function ExpandableTextarea({ label, value, onChange, onBlur, rows, placeholder, }: {
8
+ label: string;
9
+ value: string;
10
+ onChange: (value: string) => void;
11
+ /** Called when the inline textarea loses focus or fullscreen is closed. */
12
+ onBlur?: (value: string) => void;
13
+ rows: number;
14
+ placeholder?: string;
15
+ }): React.JSX.Element;
16
+ export default ExpandableTextarea;
@@ -0,0 +1,65 @@
1
+ import c from "../../../Button/index.js";
2
+ import p from "../../../Label/index.js";
3
+ import { useState as u } from "react";
4
+ import { Fragment as h, jsx as e, jsxs as a } from "react/jsx-runtime";
5
+ function v({ label: l, value: r, onChange: s, onBlur: i, rows: d, placeholder: o }) {
6
+ const [f, n] = u(!1), m = () => {
7
+ n(!1), i?.(r);
8
+ };
9
+ return /* @__PURE__ */ a(h, { children: [/* @__PURE__ */ a("div", {
10
+ className: "flow-inspector-row flow-inspector-multiline",
11
+ children: [/* @__PURE__ */ a("div", {
12
+ className: "flow-inspector-field-heading",
13
+ children: [/* @__PURE__ */ e(p, {
14
+ size: "xs",
15
+ className: "flow-inspector-label",
16
+ children: l
17
+ }), /* @__PURE__ */ e(c, {
18
+ size: "xs",
19
+ variant: "ghost",
20
+ square: !0,
21
+ onClick: () => n(!0),
22
+ children: /* @__PURE__ */ e("span", {
23
+ "aria-label": "全屏编辑",
24
+ title: "全屏编辑",
25
+ children: "↗"
26
+ })
27
+ })]
28
+ }), /* @__PURE__ */ e("textarea", {
29
+ className: "flow-inspector-textarea",
30
+ value: r,
31
+ placeholder: o,
32
+ onChange: (t) => s(t.target.value),
33
+ onBlur: () => i?.(r),
34
+ rows: d,
35
+ spellCheck: !1
36
+ })]
37
+ }), f && /* @__PURE__ */ a("div", {
38
+ className: "flow-editor-fullscreen",
39
+ role: "dialog",
40
+ "aria-modal": "true",
41
+ "aria-label": `${l} 全屏编辑`,
42
+ children: [/* @__PURE__ */ a("div", {
43
+ className: "flow-editor-fullscreen-header",
44
+ children: [/* @__PURE__ */ e("strong", { children: l }), /* @__PURE__ */ e(c, {
45
+ size: "sm",
46
+ variant: "ghost",
47
+ onClick: m,
48
+ children: "完成"
49
+ })]
50
+ }), /* @__PURE__ */ e("textarea", {
51
+ className: "flow-inspector-textarea flow-editor-fullscreen-input",
52
+ value: r,
53
+ placeholder: o,
54
+ onChange: (t) => s(t.target.value),
55
+ spellCheck: !1,
56
+ autoFocus: !0
57
+ })]
58
+ })] });
59
+ }
60
+ export {
61
+ v as ExpandableTextarea,
62
+ v as default
63
+ };
64
+
65
+ //# sourceMappingURL=ExpandableTextarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpandableTextarea.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/ExpandableTextarea.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport Button from '../../../Button';\nimport Label from '../../../Label';\n\n/**\n * Textarea with a \"fullscreen\" expand button. The fullscreen overlay edits the\n * same value; `onBlur`/`onDone` let callers commit expensive parses only when\n * editing finishes instead of on every keystroke.\n */\nexport function ExpandableTextarea({\n label,\n value,\n onChange,\n onBlur,\n rows,\n placeholder,\n}: {\n label: string;\n value: string;\n onChange: (value: string) => void;\n /** Called when the inline textarea loses focus or fullscreen is closed. */\n onBlur?: (value: string) => void;\n rows: number;\n placeholder?: string;\n}) {\n const [expanded, setExpanded] = useState(false);\n\n const closeFullscreen = () => {\n setExpanded(false);\n onBlur?.(value);\n };\n\n return (\n <>\n <div className=\"flow-inspector-row flow-inspector-multiline\">\n <div className=\"flow-inspector-field-heading\">\n <Label size=\"xs\" className=\"flow-inspector-label\">{label}</Label>\n <Button size=\"xs\" variant=\"ghost\" square onClick={() => setExpanded(true)}>\n <span aria-label=\"全屏编辑\" title=\"全屏编辑\">↗</span>\n </Button>\n </div>\n <textarea\n className=\"flow-inspector-textarea\"\n value={value}\n placeholder={placeholder}\n onChange={(event) => onChange(event.target.value)}\n onBlur={() => onBlur?.(value)}\n rows={rows}\n spellCheck={false}\n />\n </div>\n {expanded && (\n <div className=\"flow-editor-fullscreen\" role=\"dialog\" aria-modal=\"true\" aria-label={`${label} 全屏编辑`}>\n <div className=\"flow-editor-fullscreen-header\">\n <strong>{label}</strong>\n <Button size=\"sm\" variant=\"ghost\" onClick={closeFullscreen}>完成</Button>\n </div>\n <textarea\n className=\"flow-inspector-textarea flow-editor-fullscreen-input\"\n value={value}\n placeholder={placeholder}\n onChange={(event) => onChange(event.target.value)}\n spellCheck={false}\n autoFocus\n />\n </div>\n )}\n </>\n );\n}\n\nexport default ExpandableTextarea;\n"],"mappings":";;;;AASA,SAAgB,EAAmB,EACjC,OAAA,GACA,OAAA,GACA,UAAA,GACA,QAAA,GACA,MAAA,GACA,aAAA,EAAA,GASC;AACD,QAAM,CAAC,GAAU,CAAA,IAAe,EAAS,EAAK,GAExC,IAAA,MAAwB;AAC5B,IAAA,EAAY,EAAK,GACjB,IAAS,CAAK;AAAA,EAChB;AAEA,SACE,gBAAA,EAAA,GAAA,EAAA,UAAA,CACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAU;AAAA,cAAf,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACE,gBAAA,EAAC,GAAD;AAAA,QAAO,MAAK;AAAA,QAAK,WAAU;AAAA,kBAAwB;AAAA,MAAa,CAAA,GAChE,gBAAA,EAAC,GAAD;AAAA,QAAQ,MAAK;AAAA,QAAK,SAAQ;AAAA,QAAQ,QAAA;AAAA,QAAO,SAAA,MAAe,EAAY,EAAI;AAAA,kBACtE,gBAAA,EAAC,QAAD;AAAA,UAAM,cAAW;AAAA,UAAO,OAAM;AAAA,oBAAO;AAAA,QAAO,CAAA;AAAA,MACtC,CAAA,CACL;AAAA,QACL,gBAAA,EAAC,YAAD;AAAA,MACE,WAAU;AAAA,MACH,OAAA;AAAA,MACM,aAAA;AAAA,MACb,UAAA,CAAW,MAAU,EAAS,EAAM,OAAO,KAAK;AAAA,MAChD,QAAA,MAAc,IAAS,CAAK;AAAA,MACtB,MAAA;AAAA,MACN,YAAY;AAAA,IACb,CAAA,CACE;AAAA,MACJ,KACC,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAU;AAAA,IAAyB,MAAK;AAAA,IAAS,cAAW;AAAA,IAAO,cAAY,GAAG,CAAA;AAAA,cAAvF,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACE,gBAAA,EAAC,UAAD,EAAA,UAAS,EAAc,CAAA,GACvB,gBAAA,EAAC,GAAD;AAAA,QAAQ,MAAK;AAAA,QAAK,SAAQ;AAAA,QAAQ,SAAS;AAAA,kBAAiB;AAAA,MAAU,CAAA,CACnE;AAAA,QACL,gBAAA,EAAC,YAAD;AAAA,MACE,WAAU;AAAA,MACH,OAAA;AAAA,MACM,aAAA;AAAA,MACb,UAAA,CAAW,MAAU,EAAS,EAAM,OAAO,KAAK;AAAA,MAChD,YAAY;AAAA,MACZ,WAAA;AAAA,IACD,CAAA,CACE;AAAA,IAEP,EAAA,CAAA;AAEN"}