dishui 0.0.84 → 0.0.91

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 (102) hide show
  1. package/dist/components/Input/index.js +52 -62
  2. package/dist/components/Input/index.js.map +1 -1
  3. package/dist/components/LayoutSuite/index.d.ts +10 -0
  4. package/dist/components/LayoutSuite/index.js +27 -18
  5. package/dist/components/LayoutSuite/index.js.map +1 -1
  6. package/dist/components/Markdown/markdownComponents.js +1 -0
  7. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  8. package/dist/components/Markdown/useMarkdownSource.js +46 -31
  9. package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
  10. package/dist/components/Markdown/useMarkmapRenderer.js +44 -31
  11. package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
  12. package/dist/components/Markdown/useMermaidRenderer.js +49 -31
  13. package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
  14. package/dist/components/ProtectedRoute/index.d.ts +2 -1
  15. package/dist/components/ProtectedRoute/index.js +16 -6
  16. package/dist/components/ProtectedRoute/index.js.map +1 -1
  17. package/dist/components/Select/index.d.ts +6 -0
  18. package/dist/components/Select/index.js +166 -136
  19. package/dist/components/Select/index.js.map +1 -1
  20. package/dist/components/Table/index.d.ts +23 -2
  21. package/dist/components/Table/index.js +153 -101
  22. package/dist/components/Table/index.js.map +1 -1
  23. package/dist/components/Tabs/index.d.ts +12 -1
  24. package/dist/components/Tabs/index.js +42 -17
  25. package/dist/components/Tabs/index.js.map +1 -1
  26. package/dist/components/pro/ArticleContextMenu/index.js +7 -7
  27. package/dist/components/pro/CodeEditor/editors/CodeEditor.js +200 -189
  28. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  29. package/dist/components/pro/CodeEditor/types.d.ts +3 -0
  30. package/dist/components/pro/DataTable/DataTable.d.ts +1 -1
  31. package/dist/components/pro/DataTable/DataTable.js +124 -247
  32. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  33. package/dist/components/pro/DataTable/components/TableBody.d.ts +3 -1
  34. package/dist/components/pro/DataTable/components/TableBody.js +41 -41
  35. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  36. package/dist/components/pro/DataTable/components/TablePagination.d.ts +3 -9
  37. package/dist/components/pro/DataTable/components/TablePagination.js +29 -25
  38. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  39. package/dist/components/pro/DataTable/components/TableToolbar.d.ts +2 -1
  40. package/dist/components/pro/DataTable/components/TableToolbar.js +25 -19
  41. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  42. package/dist/components/pro/DataTable/index.d.ts +1 -1
  43. package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
  44. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  45. package/dist/components/pro/DataTable/tanstack-table.d.ts +2 -2
  46. package/dist/components/pro/DataTable/tanstack-table.js +29 -21
  47. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  48. package/dist/components/pro/DataTable/treeDataUtils.d.ts +2 -0
  49. package/dist/components/pro/DataTable/treeDataUtils.js +18 -19
  50. package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
  51. package/dist/components/pro/DataTable/types.d.ts +43 -0
  52. package/dist/components/pro/DataTable/useDataTableModel.d.ts +16 -0
  53. package/dist/components/pro/DataTable/useDataTableModel.js +148 -0
  54. package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -0
  55. package/dist/components/pro/FileExplorer/Breadcrumb.js +12 -12
  56. package/dist/components/pro/Flow/nodes/DataNodeView.js +87 -82
  57. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  58. package/dist/components/pro/Flow/nodes/MediaContent.js +1 -1
  59. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  60. package/dist/components/pro/Flow/nodes/MediaOverlay.js +1 -1
  61. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  62. package/dist/components/pro/Flow/nodes/Model3DView.js +69 -63
  63. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  64. package/dist/components/pro/Flow/nodes/chartGeometryBudget.d.ts +14 -0
  65. package/dist/components/pro/Flow/nodes/chartGeometryBudget.js +76 -0
  66. package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -0
  67. package/dist/components/pro/Flow/nodes/demandRender.d.ts +11 -0
  68. package/dist/components/pro/Flow/nodes/demandRender.js +26 -0
  69. package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -0
  70. package/dist/components/pro/RichTextEditor/SlashMenu.js +68 -58
  71. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  72. package/dist/contexts/AppContext.d.ts +1 -0
  73. package/dist/contexts/AppContext.js +144 -145
  74. package/dist/contexts/AppContext.js.map +1 -1
  75. package/dist/contexts/authentication.d.ts +7 -0
  76. package/dist/contexts/authentication.js +22 -0
  77. package/dist/contexts/authentication.js.map +1 -0
  78. package/dist/data-table.js.map +1 -1
  79. package/dist/dishui.css +1 -1
  80. package/dist/hooks/useControllableState.d.ts +6 -14
  81. package/dist/hooks/useControllableState.js +21 -15
  82. package/dist/hooks/useControllableState.js.map +1 -1
  83. package/dist/hooks/useTableColumns.d.ts +3 -3
  84. package/dist/hooks/useTableColumns.js +2 -2
  85. package/dist/hooks/useTableColumns.js.map +1 -1
  86. package/dist/hooks/useTableData.d.ts +11 -4
  87. package/dist/hooks/useTableData.js +44 -26
  88. package/dist/hooks/useTableData.js.map +1 -1
  89. package/dist/index-nostyled.d.ts +2 -2
  90. package/dist/index.d.ts +4 -4
  91. package/dist/index.js +97 -97
  92. package/dist/lite.d.ts +2 -0
  93. package/dist/lite.js +22 -21
  94. package/dist/utils/i18n.js +1 -1
  95. package/dist/utils/i18n.js.map +1 -1
  96. package/dist/utils/routerBuilder.d.ts +7 -5
  97. package/dist/utils/routerBuilder.js +11 -15
  98. package/dist/utils/routerBuilder.js.map +1 -1
  99. package/dist/utils/safeStorage.d.ts +8 -0
  100. package/dist/utils/safeStorage.js +45 -0
  101. package/dist/utils/safeStorage.js.map +1 -0
  102. package/package.json +22 -5
@@ -1,116 +1,122 @@
1
- import { useEffect as e, useRef as t, useState as n } from "react";
2
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
3
- import * as a from "three";
4
- import { OrbitControls as o } from "three/addons/controls/OrbitControls.js";
5
- import { ThreeMFLoader as s } from "three/addons/loaders/3MFLoader.js";
6
- import { OBJLoader as c } from "three/addons/loaders/OBJLoader.js";
7
- import { STLLoader as l } from "three/addons/loaders/STLLoader.js";
1
+ import { createDemandRender as e } from "./demandRender.js";
2
+ import { useEffect as t, useRef as n, useState as r } from "react";
3
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
+ import * as o from "three";
5
+ import { OrbitControls as s } from "three/addons/controls/OrbitControls.js";
6
+ import { ThreeMFLoader as c } from "three/addons/loaders/3MFLoader.js";
7
+ import { OBJLoader as l } from "three/addons/loaders/OBJLoader.js";
8
+ import { STLLoader as u } from "three/addons/loaders/STLLoader.js";
8
9
  //#region src/components/pro/Flow/nodes/Model3DView.tsx
9
- function u(e) {
10
+ function d(e) {
10
11
  let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
11
12
  e.traverse((e) => {
12
- if (!(e instanceof a.Mesh)) return;
13
+ if (!(e instanceof o.Mesh)) return;
13
14
  e.geometry?.dispose();
14
15
  let r = Array.isArray(e.material) ? e.material : [e.material];
15
16
  for (let e of r) if (e && !t.has(e)) {
16
17
  t.add(e);
17
- for (let t of Object.values(e)) t instanceof a.Texture && n.add(t);
18
+ for (let t of Object.values(e)) t instanceof o.Texture && n.add(t);
18
19
  }
19
20
  });
20
21
  for (let e of n) e.dispose();
21
22
  for (let e of t) e.dispose();
22
23
  }
23
- function d(e, t) {
24
+ function f(e, t) {
24
25
  if (e === "stl") {
25
- let e = new l().parse(t);
26
- return e.getAttribute("normal") || e.computeVertexNormals(), new a.Mesh(e, new a.MeshStandardMaterial({
26
+ let e = new u().parse(t);
27
+ return e.getAttribute("normal") || e.computeVertexNormals(), new o.Mesh(e, new o.MeshStandardMaterial({
27
28
  color: 12108492,
28
29
  metalness: .05,
29
30
  roughness: .72,
30
- side: a.DoubleSide
31
+ side: o.DoubleSide
31
32
  }));
32
33
  }
33
- return e === "obj" ? new c().parse(new TextDecoder().decode(t)) : new s().parse(t);
34
+ return e === "obj" ? new l().parse(new TextDecoder().decode(t)) : new c().parse(t);
34
35
  }
35
- function f({ content: s, format: c, interactive: l }) {
36
- let f = t(null), p = t(null), [m, h] = n(null), [g, _] = n(!1);
37
- return e(() => {
38
- p.current && (p.current.enabled = l);
39
- }, [l]), e(() => {
40
- let e = f.current, t = s.trim();
41
- if (!e || !t) return;
42
- let n = !1, r = 0, i = null, m = new AbortController(), g = new a.Scene(), v = new a.PerspectiveCamera(45, 1, .01, 1e4), y = new a.WebGLRenderer({
36
+ function p({ content: c, format: l, interactive: u }) {
37
+ let p = n(null), m = n(null), h = n(u), [g, _] = r(null), [v, y] = r(!1);
38
+ return t(() => {
39
+ h.current = u, m.current && (m.current.enabled = u);
40
+ }, [u]), t(() => {
41
+ let t = p.current, n = c.trim();
42
+ if (!t || !n) return;
43
+ let r = !1, i = null, a = new AbortController(), u = new o.Scene(), g = new o.PerspectiveCamera(45, 1, .01, 1e4), v = new o.WebGLRenderer({
43
44
  antialias: !0,
44
45
  alpha: !0
45
46
  });
46
- y.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2)), y.outputColorSpace = a.SRGBColorSpace, y.setClearColor(0, 0), e.appendChild(y.domElement), g.add(new a.HemisphereLight(16777215, 4477030, 2));
47
- let b = new a.DirectionalLight(16777215, 2.4);
48
- b.position.set(3, 5, 4), g.add(b);
49
- let x = new o(v, y.domElement);
50
- x.enableDamping = !0, x.enabled = l, p.current = x;
51
- let S = () => {
52
- let t = Math.max(1, e.clientWidth), n = Math.max(1, e.clientHeight);
53
- y.setSize(t, n, !1), v.aspect = t / n, v.updateProjectionMatrix();
54
- };
55
- S();
56
- let C = new ResizeObserver(S);
57
- C.observe(e);
58
- let w = () => {
59
- x.update(), y.render(g, v), r = requestAnimationFrame(w);
47
+ v.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2)), v.outputColorSpace = o.SRGBColorSpace, v.setClearColor(0, 0), t.appendChild(v.domElement), u.add(new o.HemisphereLight(16777215, 4477030, 2));
48
+ let b = new o.DirectionalLight(16777215, 2.4);
49
+ b.position.set(3, 5, 4), u.add(b);
50
+ let x = new s(g, v.domElement);
51
+ x.enableDamping = !0, x.enabled = h.current, m.current = x;
52
+ let S = e({
53
+ update: () => x.update(),
54
+ render: () => v.render(u, g)
55
+ });
56
+ x.addEventListener("change", S.invalidate);
57
+ let C = typeof IntersectionObserver > "u", w = () => S.setActive(C && !document.hidden), T = typeof IntersectionObserver > "u" ? null : new IntersectionObserver((e) => {
58
+ C = e.some((e) => e.isIntersecting && e.intersectionRect.width > 0 && e.intersectionRect.height > 0), w();
59
+ });
60
+ T?.observe(t), document.addEventListener("visibilitychange", w), w();
61
+ let E = () => {
62
+ let e = Math.max(1, t.clientWidth), n = Math.max(1, t.clientHeight);
63
+ v.setSize(e, n, !1), g.aspect = e / n, g.updateProjectionMatrix(), S.invalidate();
60
64
  };
61
- return w(), _(!0), h(null), fetch(t, { signal: m.signal }).then((e) => {
65
+ E();
66
+ let D = new ResizeObserver(E);
67
+ return D.observe(t), y(!0), _(null), fetch(n, { signal: a.signal }).then((e) => {
62
68
  if (!e.ok) throw Error(`模型加载失败:HTTP ${e.status}`);
63
69
  return e.arrayBuffer();
64
70
  }).then((e) => {
65
71
  if (e.byteLength > 52428800) throw Error("模型超过 50 MiB,无法加载");
66
- let t = d(c, e);
67
- if (n) {
68
- u(t);
72
+ let t = f(l, e);
73
+ if (r) {
74
+ d(t);
69
75
  return;
70
76
  }
71
77
  i = t, t.updateMatrixWorld(!0);
72
- let r = new a.Box3().setFromObject(t);
73
- if (r.isEmpty()) throw Error("模型不包含可显示的几何体");
74
- let o = r.getCenter(new a.Vector3());
75
- t.position.sub(o), t.updateMatrixWorld(!0);
76
- let s = new a.Box3().setFromObject(t).getBoundingSphere(new a.Sphere());
78
+ let n = new o.Box3().setFromObject(t);
79
+ if (n.isEmpty()) throw Error("模型不包含可显示的几何体");
80
+ let a = n.getCenter(new o.Vector3());
81
+ t.position.sub(a), t.updateMatrixWorld(!0);
82
+ let s = new o.Box3().setFromObject(t).getBoundingSphere(new o.Sphere());
77
83
  if (!Number.isFinite(s.radius) || s.radius <= 0) throw Error("模型尺寸无效");
78
- g.add(t);
79
- let l = a.MathUtils.degToRad(v.fov / 2), f = Math.atan(Math.tan(l) * v.aspect), p = s.radius / Math.sin(Math.min(f, l)) * 1.15;
80
- v.position.copy(new a.Vector3(1, .75, 1).normalize().multiplyScalar(p)), v.near = Math.max(s.radius / 1e3, .001), v.far = Math.max(p + s.radius * 10, s.radius * 1e3), v.updateProjectionMatrix(), x.target.set(0, 0, 0), x.minDistance = s.radius * .05, x.maxDistance = s.radius * 100, x.update();
84
+ u.add(t);
85
+ let c = o.MathUtils.degToRad(g.fov / 2), p = Math.atan(Math.tan(c) * g.aspect), m = s.radius / Math.sin(Math.min(p, c)) * 1.15;
86
+ g.position.copy(new o.Vector3(1, .75, 1).normalize().multiplyScalar(m)), g.near = Math.max(s.radius / 1e3, .001), g.far = Math.max(m + s.radius * 10, s.radius * 1e3), g.updateProjectionMatrix(), x.target.set(0, 0, 0), x.minDistance = s.radius * .05, x.maxDistance = s.radius * 100, S.invalidate();
81
87
  }).catch((e) => {
82
- !n && e?.name !== "AbortError" && h(e?.message ?? "模型加载失败");
88
+ !r && e?.name !== "AbortError" && _(e?.message ?? "模型加载失败");
83
89
  }).finally(() => {
84
- n || _(!1);
90
+ r || y(!1);
85
91
  }), () => {
86
- n = !0, m.abort(), cancelAnimationFrame(r), C.disconnect(), x.dispose(), p.current = null, i && u(i), g.clear(), y.renderLists.dispose(), y.dispose(), y.forceContextLoss(), y.domElement.remove();
92
+ r = !0, a.abort(), S.dispose(), D.disconnect(), T?.disconnect(), document.removeEventListener("visibilitychange", w), x.removeEventListener("change", S.invalidate), x.dispose(), m.current = null, i && d(i), u.clear(), v.renderLists.dispose(), v.dispose(), v.forceContextLoss(), v.domElement.remove();
87
93
  };
88
- }, [s, c]), s.trim() ? /* @__PURE__ */ i("div", {
89
- ref: f,
94
+ }, [c, l]), c.trim() ? /* @__PURE__ */ a("div", {
95
+ ref: p,
90
96
  className: "flow-media-model3d",
91
97
  style: {
92
- pointerEvents: l ? "auto" : "none",
93
- touchAction: l ? "none" : "auto"
98
+ pointerEvents: u ? "auto" : "none",
99
+ touchAction: u ? "none" : "auto"
94
100
  },
95
101
  onPointerDown: (e) => {
96
- l && e.stopPropagation();
102
+ u && e.stopPropagation();
97
103
  },
98
104
  onWheel: (e) => {
99
- l && e.stopPropagation();
105
+ u && e.stopPropagation();
100
106
  },
101
- children: [g && /* @__PURE__ */ r("div", {
107
+ children: [v && /* @__PURE__ */ i("div", {
102
108
  className: "flow-media-loading flow-media-model3d-status",
103
109
  children: "加载模型…"
104
- }), m && /* @__PURE__ */ r("div", {
110
+ }), g && /* @__PURE__ */ i("div", {
105
111
  className: "flow-media-error flow-media-model3d-status",
106
- children: m
112
+ children: g
107
113
  })]
108
- }) : /* @__PURE__ */ r("div", {
114
+ }) : /* @__PURE__ */ i("div", {
109
115
  className: "flow-media-image-empty",
110
116
  children: "输入 STL、OBJ 或 3MF 模型链接"
111
117
  });
112
118
  }
113
119
  //#endregion
114
- export { f as Model3DView };
120
+ export { p as Model3DView };
115
121
 
116
122
  //# sourceMappingURL=Model3DView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Model3DView.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/Model3DView.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { STLLoader } from 'three/addons/loaders/STLLoader.js';\nimport type { FlowModelFormat } from '../types';\n\nfunction disposeObject(root: any) {\n const materials = new Set<any>();\n const textures = new Set<any>();\n root.traverse((object: any) => {\n if (!(object instanceof THREE.Mesh)) return;\n object.geometry?.dispose();\n const list = Array.isArray(object.material) ? object.material : [object.material];\n for (const material of list) {\n if (!material || materials.has(material)) continue;\n materials.add(material);\n for (const value of Object.values(material)) {\n if (value instanceof THREE.Texture) textures.add(value);\n }\n }\n });\n for (const texture of textures) texture.dispose();\n for (const material of materials) material.dispose();\n}\n\nfunction parseModel(format: FlowModelFormat, data: ArrayBuffer): any {\n if (format === 'stl') {\n const geometry = new STLLoader().parse(data);\n if (!geometry.getAttribute('normal')) geometry.computeVertexNormals();\n return new THREE.Mesh(\n geometry,\n new THREE.MeshStandardMaterial({\n color: 0xb8c2cc,\n metalness: 0.05,\n roughness: 0.72,\n side: THREE.DoubleSide,\n }),\n );\n }\n if (format === 'obj') {\n return new OBJLoader().parse(new TextDecoder().decode(data));\n }\n return new ThreeMFLoader().parse(data);\n}\n\nexport function Model3DView({\n content,\n format,\n interactive,\n}: {\n content: string;\n format: FlowModelFormat;\n interactive: boolean;\n}) {\n const hostRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<any>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n if (controlsRef.current) controlsRef.current.enabled = interactive;\n }, [interactive]);\n\n useEffect(() => {\n const host = hostRef.current;\n const source = content.trim();\n if (!host || !source) return;\n\n let cancelled = false;\n let frame = 0;\n let model: any = null;\n const abort = new AbortController();\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(45, 1, 0.01, 10000);\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n renderer.outputColorSpace = THREE.SRGBColorSpace;\n renderer.setClearColor(0x000000, 0);\n host.appendChild(renderer.domElement);\n\n scene.add(new THREE.HemisphereLight(0xffffff, 0x445066, 2));\n const directional = new THREE.DirectionalLight(0xffffff, 2.4);\n directional.position.set(3, 5, 4);\n scene.add(directional);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.enabled = interactive;\n controlsRef.current = controls;\n\n const resize = () => {\n const width = Math.max(1, host.clientWidth);\n const height = Math.max(1, host.clientHeight);\n renderer.setSize(width, height, false);\n camera.aspect = width / height;\n camera.updateProjectionMatrix();\n };\n resize();\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n const animate = () => {\n controls.update();\n renderer.render(scene, camera);\n frame = requestAnimationFrame(animate);\n };\n animate();\n\n setLoading(true);\n setError(null);\n fetch(source, { signal: abort.signal })\n .then(response => {\n if (!response.ok) throw new Error(`模型加载失败:HTTP ${response.status}`);\n return response.arrayBuffer();\n })\n .then(data => {\n if (data.byteLength > 50 * 1024 * 1024) throw new Error('模型超过 50 MiB,无法加载');\n const root = parseModel(format, data);\n if (cancelled) {\n disposeObject(root);\n return;\n }\n model = root;\n root.updateMatrixWorld(true);\n const box = new THREE.Box3().setFromObject(root);\n if (box.isEmpty()) throw new Error('模型不包含可显示的几何体');\n const center = box.getCenter(new THREE.Vector3());\n root.position.sub(center);\n root.updateMatrixWorld(true);\n const sphere = new THREE.Box3().setFromObject(root).getBoundingSphere(new THREE.Sphere());\n if (!Number.isFinite(sphere.radius) || sphere.radius <= 0) throw new Error('模型尺寸无效');\n scene.add(root);\n\n const halfFovY = THREE.MathUtils.degToRad(camera.fov / 2);\n const halfFovX = Math.atan(Math.tan(halfFovY) * camera.aspect);\n const distance = (sphere.radius / Math.sin(Math.min(halfFovX, halfFovY))) * 1.15;\n camera.position.copy(new THREE.Vector3(1, 0.75, 1).normalize().multiplyScalar(distance));\n camera.near = Math.max(sphere.radius / 1000, 0.001);\n camera.far = Math.max(distance + sphere.radius * 10, sphere.radius * 1000);\n camera.updateProjectionMatrix();\n controls.target.set(0, 0, 0);\n controls.minDistance = sphere.radius * 0.05;\n controls.maxDistance = sphere.radius * 100;\n controls.update();\n })\n .catch(nextError => {\n if (!cancelled && nextError?.name !== 'AbortError') setError(nextError?.message ?? '模型加载失败');\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => {\n cancelled = true;\n abort.abort();\n cancelAnimationFrame(frame);\n observer.disconnect();\n controls.dispose();\n controlsRef.current = null;\n if (model) disposeObject(model);\n scene.clear();\n renderer.renderLists.dispose();\n renderer.dispose();\n renderer.forceContextLoss();\n renderer.domElement.remove();\n };\n }, [content, format]);\n\n if (!content.trim()) {\n return <div className=\"flow-media-image-empty\">输入 STL、OBJ 或 3MF 模型链接</div>;\n }\n\n return (\n <div\n ref={hostRef}\n className=\"flow-media-model3d\"\n style={{ pointerEvents: interactive ? 'auto' : 'none', touchAction: interactive ? 'none' : 'auto' }}\n onPointerDown={event => { if (interactive) event.stopPropagation(); }}\n onWheel={event => { if (interactive) event.stopPropagation(); }}\n >\n {loading && <div className=\"flow-media-loading flow-media-model3d-status\">加载模型…</div>}\n {error && <div className=\"flow-media-error flow-media-model3d-status\">{error}</div>}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAQA,SAAS,EAAc,GAAW;CAChC,IAAM,oBAAY,IAAI,IAAS,GACzB,oBAAW,IAAI,IAAS;CAC9B,EAAK,UAAU,MAAgB;EAC7B,IAAI,EAAE,aAAkB,EAAM,OAAO;EACrC,EAAO,UAAU,QAAQ;EACzB,IAAM,IAAO,MAAM,QAAQ,EAAO,QAAQ,IAAI,EAAO,WAAW,CAAC,EAAO,QAAQ;EAChF,KAAK,IAAM,KAAY,GACjB,IAAC,KAAY,GAAU,IAAI,CAAQ,GACvC;KAAU,IAAI,CAAQ;GACtB,KAAK,IAAM,KAAS,OAAO,OAAO,CAAQ,GACxC,AAAI,aAAiB,EAAM,WAAS,EAAS,IAAI,CAAK;EAFlC;CAK1B,CAAC;CACD,KAAK,IAAM,KAAW,GAAU,EAAQ,QAAQ;CAChD,KAAK,IAAM,KAAY,GAAW,EAAS,QAAQ;AACrD;AAEA,SAAS,EAAW,GAAyB,GAAwB;CACnE,IAAI,MAAW,OAAO;EACpB,IAAM,IAAW,IAAI,EAAU,CAAC,CAAC,MAAM,CAAI;EAE3C,OADK,EAAS,aAAa,QAAQ,KAAG,EAAS,qBAAqB,GAC7D,IAAI,EAAM,KACf,GACA,IAAI,EAAM,qBAAqB;GAC7B,OAAO;GACP,WAAW;GACX,WAAW;GACX,MAAM,EAAM;EACd,CAAC,CACH;CACF;CAIA,OAHI,MAAW,QACN,IAAI,EAAU,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,IAEtD,IAAI,EAAc,CAAC,CAAC,MAAM,CAAI;AACvC;AAEA,SAAgB,EAAY,EAC1B,YACA,WACA,kBAKC;CACD,IAAM,IAAU,EAAuB,IAAI,GACrC,IAAc,EAAY,IAAI,GAC9B,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAK;CAmH5C,OAjHA,QAAgB;EACd,AAAI,EAAY,YAAS,EAAY,QAAQ,UAAU;CACzD,GAAG,CAAC,CAAW,CAAC,GAEhB,QAAgB;EACd,IAAM,IAAO,EAAQ,SACf,IAAS,EAAQ,KAAK;EAC5B,IAAI,CAAC,KAAQ,CAAC,GAAQ;EAEtB,IAAI,IAAY,IACZ,IAAQ,GACR,IAAa,MACX,IAAQ,IAAI,gBAAgB,GAC5B,IAAQ,IAAI,EAAM,MAAM,GACxB,IAAS,IAAI,EAAM,kBAAkB,IAAI,GAAG,KAAM,GAAK,GACvD,IAAW,IAAI,EAAM,cAAc;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EAMzE,AALA,EAAS,cAAc,KAAK,IAAI,OAAO,oBAAoB,GAAG,CAAC,CAAC,GAChE,EAAS,mBAAmB,EAAM,gBAClC,EAAS,cAAc,GAAU,CAAC,GAClC,EAAK,YAAY,EAAS,UAAU,GAEpC,EAAM,IAAI,IAAI,EAAM,gBAAgB,UAAU,SAAU,CAAC,CAAC;EAC1D,IAAM,IAAc,IAAI,EAAM,iBAAiB,UAAU,GAAG;EAE5D,AADA,EAAY,SAAS,IAAI,GAAG,GAAG,CAAC,GAChC,EAAM,IAAI,CAAW;EAErB,IAAM,IAAW,IAAI,EAAc,GAAQ,EAAS,UAAU;EAG9D,AAFA,EAAS,gBAAgB,IACzB,EAAS,UAAU,GACnB,EAAY,UAAU;EAEtB,IAAM,UAAe;GACnB,IAAM,IAAQ,KAAK,IAAI,GAAG,EAAK,WAAW,GACpC,IAAS,KAAK,IAAI,GAAG,EAAK,YAAY;GAG5C,AAFA,EAAS,QAAQ,GAAO,GAAQ,EAAK,GACrC,EAAO,SAAS,IAAQ,GACxB,EAAO,uBAAuB;EAChC;EACA,EAAO;EACP,IAAM,IAAW,IAAI,eAAe,CAAM;EAC1C,EAAS,QAAQ,CAAI;EAErB,IAAM,UAAgB;GAGpB,AAFA,EAAS,OAAO,GAChB,EAAS,OAAO,GAAO,CAAM,GAC7B,IAAQ,sBAAsB,CAAO;EACvC;EA+CA,OA9CA,EAAQ,GAER,EAAW,EAAI,GACf,EAAS,IAAI,GACb,MAAM,GAAQ,EAAE,QAAQ,EAAM,OAAO,CAAC,CAAC,CACpC,MAAK,MAAY;GAChB,IAAI,CAAC,EAAS,IAAI,MAAU,MAAM,eAAe,EAAS,QAAQ;GAClE,OAAO,EAAS,YAAY;EAC9B,CAAC,CAAC,CACD,MAAK,MAAQ;GACZ,IAAI,EAAK,aAAa,UAAkB,MAAU,MAAM,kBAAkB;GAC1E,IAAM,IAAO,EAAW,GAAQ,CAAI;GACpC,IAAI,GAAW;IACb,EAAc,CAAI;IAClB;GACF;GAEA,AADA,IAAQ,GACR,EAAK,kBAAkB,EAAI;GAC3B,IAAM,IAAM,IAAI,EAAM,KAAK,CAAC,CAAC,cAAc,CAAI;GAC/C,IAAI,EAAI,QAAQ,GAAG,MAAU,MAAM,cAAc;GACjD,IAAM,IAAS,EAAI,UAAU,IAAI,EAAM,QAAQ,CAAC;GAEhD,AADA,EAAK,SAAS,IAAI,CAAM,GACxB,EAAK,kBAAkB,EAAI;GAC3B,IAAM,IAAS,IAAI,EAAM,KAAK,CAAC,CAAC,cAAc,CAAI,CAAC,CAAC,kBAAkB,IAAI,EAAM,OAAO,CAAC;GACxF,IAAI,CAAC,OAAO,SAAS,EAAO,MAAM,KAAK,EAAO,UAAU,GAAG,MAAU,MAAM,QAAQ;GACnF,EAAM,IAAI,CAAI;GAEd,IAAM,IAAW,EAAM,UAAU,SAAS,EAAO,MAAM,CAAC,GAClD,IAAW,KAAK,KAAK,KAAK,IAAI,CAAQ,IAAI,EAAO,MAAM,GACvD,IAAY,EAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAU,CAAQ,CAAC,IAAK;GAQ5E,AAPA,EAAO,SAAS,KAAK,IAAI,EAAM,QAAQ,GAAG,KAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,eAAe,CAAQ,CAAC,GACvF,EAAO,OAAO,KAAK,IAAI,EAAO,SAAS,KAAM,IAAK,GAClD,EAAO,MAAM,KAAK,IAAI,IAAW,EAAO,SAAS,IAAI,EAAO,SAAS,GAAI,GACzE,EAAO,uBAAuB,GAC9B,EAAS,OAAO,IAAI,GAAG,GAAG,CAAC,GAC3B,EAAS,cAAc,EAAO,SAAS,KACvC,EAAS,cAAc,EAAO,SAAS,KACvC,EAAS,OAAO;EAClB,CAAC,CAAC,CACD,OAAM,MAAa;GAClB,AAAI,CAAC,KAAa,GAAW,SAAS,gBAAc,EAAS,GAAW,WAAW,QAAQ;EAC7F,CAAC,CAAC,CACD,cAAc;GACb,AAAK,KAAW,EAAW,EAAK;EAClC,CAAC,SAEU;GAYX,AAXA,IAAY,IACZ,EAAM,MAAM,GACZ,qBAAqB,CAAK,GAC1B,EAAS,WAAW,GACpB,EAAS,QAAQ,GACjB,EAAY,UAAU,MAClB,KAAO,EAAc,CAAK,GAC9B,EAAM,MAAM,GACZ,EAAS,YAAY,QAAQ,GAC7B,EAAS,QAAQ,GACjB,EAAS,iBAAiB,GAC1B,EAAS,WAAW,OAAO;EAC7B;CACF,GAAG,CAAC,GAAS,CAAM,CAAC,GAEf,EAAQ,KAAK,IAKhB,kBAAC,OAAD;EACE,KAAK;EACL,WAAU;EACV,OAAO;GAAE,eAAe,IAAc,SAAS;GAAQ,aAAa,IAAc,SAAS;EAAO;EAClG,gBAAe,MAAS;GAAE,AAAI,KAAa,EAAM,gBAAgB;EAAG;EACpE,UAAS,MAAS;GAAE,AAAI,KAAa,EAAM,gBAAgB;EAAG;EALhE,UAAA,CAOG,KAAW,kBAAC,OAAD;GAAK,WAAU;GAA+C,UAAA;EAAU,CAAA,GACnF,KAAS,kBAAC,OAAD;GAAK,WAAU;GAA8C,UAAA;EAAW,CAAA,CAC/E;MAbE,kBAAC,OAAD;EAAK,WAAU;EAAyB,UAAA;CAA0B,CAAA;AAe7E"}
1
+ {"version":3,"file":"Model3DView.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/Model3DView.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { STLLoader } from 'three/addons/loaders/STLLoader.js';\nimport type { FlowModelFormat } from '../types';\nimport { createDemandRender } from './demandRender';\n\nfunction disposeObject(root: any) {\n const materials = new Set<any>();\n const textures = new Set<any>();\n root.traverse((object: any) => {\n if (!(object instanceof THREE.Mesh)) return;\n object.geometry?.dispose();\n const list = Array.isArray(object.material) ? object.material : [object.material];\n for (const material of list) {\n if (!material || materials.has(material)) continue;\n materials.add(material);\n for (const value of Object.values(material)) {\n if (value instanceof THREE.Texture) textures.add(value);\n }\n }\n });\n for (const texture of textures) texture.dispose();\n for (const material of materials) material.dispose();\n}\n\nfunction parseModel(format: FlowModelFormat, data: ArrayBuffer): any {\n if (format === 'stl') {\n const geometry = new STLLoader().parse(data);\n if (!geometry.getAttribute('normal')) geometry.computeVertexNormals();\n return new THREE.Mesh(\n geometry,\n new THREE.MeshStandardMaterial({\n color: 0xb8c2cc,\n metalness: 0.05,\n roughness: 0.72,\n side: THREE.DoubleSide,\n }),\n );\n }\n if (format === 'obj') {\n return new OBJLoader().parse(new TextDecoder().decode(data));\n }\n return new ThreeMFLoader().parse(data);\n}\n\nexport function Model3DView({\n content,\n format,\n interactive,\n}: {\n content: string;\n format: FlowModelFormat;\n interactive: boolean;\n}) {\n const hostRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<OrbitControls | null>(null);\n const interactiveRef = useRef(interactive);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n interactiveRef.current = interactive;\n if (controlsRef.current) controlsRef.current.enabled = interactive;\n }, [interactive]);\n\n useEffect(() => {\n const host = hostRef.current;\n const source = content.trim();\n if (!host || !source) return;\n\n let cancelled = false;\n let model: any = null;\n const abort = new AbortController();\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(45, 1, 0.01, 10000);\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n renderer.outputColorSpace = THREE.SRGBColorSpace;\n renderer.setClearColor(0x000000, 0);\n host.appendChild(renderer.domElement);\n\n scene.add(new THREE.HemisphereLight(0xffffff, 0x445066, 2));\n const directional = new THREE.DirectionalLight(0xffffff, 2.4);\n directional.position.set(3, 5, 4);\n scene.add(directional);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.enabled = interactiveRef.current;\n controlsRef.current = controls;\n\n const drawing = createDemandRender({\n update: () => controls.update(),\n render: () => renderer.render(scene, camera),\n });\n controls.addEventListener('change', drawing.invalidate);\n // Observe the actual DOM box, including overlay transforms and clipping.\n // Pausing keeps the loaded model, camera and WebGL context intact.\n let intersecting = typeof IntersectionObserver === 'undefined';\n const updateVisibility = () => drawing.setActive(intersecting && !document.hidden);\n const visibilityObserver = typeof IntersectionObserver === 'undefined' ? null : new IntersectionObserver(entries => {\n intersecting = entries.some(entry => entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0);\n updateVisibility();\n });\n visibilityObserver?.observe(host);\n document.addEventListener('visibilitychange', updateVisibility);\n updateVisibility();\n\n const resize = () => {\n const width = Math.max(1, host.clientWidth);\n const height = Math.max(1, host.clientHeight);\n renderer.setSize(width, height, false);\n camera.aspect = width / height;\n camera.updateProjectionMatrix();\n drawing.invalidate();\n };\n resize();\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n setLoading(true);\n setError(null);\n fetch(source, { signal: abort.signal })\n .then(response => {\n if (!response.ok) throw new Error(`模型加载失败:HTTP ${response.status}`);\n return response.arrayBuffer();\n })\n .then(data => {\n if (data.byteLength > 50 * 1024 * 1024) throw new Error('模型超过 50 MiB,无法加载');\n const root = parseModel(format, data);\n if (cancelled) {\n disposeObject(root);\n return;\n }\n model = root;\n root.updateMatrixWorld(true);\n const box = new THREE.Box3().setFromObject(root);\n if (box.isEmpty()) throw new Error('模型不包含可显示的几何体');\n const center = box.getCenter(new THREE.Vector3());\n root.position.sub(center);\n root.updateMatrixWorld(true);\n const sphere = new THREE.Box3().setFromObject(root).getBoundingSphere(new THREE.Sphere());\n if (!Number.isFinite(sphere.radius) || sphere.radius <= 0) throw new Error('模型尺寸无效');\n scene.add(root);\n\n const halfFovY = THREE.MathUtils.degToRad(camera.fov / 2);\n const halfFovX = Math.atan(Math.tan(halfFovY) * camera.aspect);\n const distance = (sphere.radius / Math.sin(Math.min(halfFovX, halfFovY))) * 1.15;\n camera.position.copy(new THREE.Vector3(1, 0.75, 1).normalize().multiplyScalar(distance));\n camera.near = Math.max(sphere.radius / 1000, 0.001);\n camera.far = Math.max(distance + sphere.radius * 10, sphere.radius * 1000);\n camera.updateProjectionMatrix();\n controls.target.set(0, 0, 0);\n controls.minDistance = sphere.radius * 0.05;\n controls.maxDistance = sphere.radius * 100;\n drawing.invalidate();\n })\n .catch(nextError => {\n if (!cancelled && nextError?.name !== 'AbortError') setError(nextError?.message ?? '模型加载失败');\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => {\n cancelled = true;\n abort.abort();\n drawing.dispose();\n observer.disconnect();\n visibilityObserver?.disconnect();\n document.removeEventListener('visibilitychange', updateVisibility);\n controls.removeEventListener('change', drawing.invalidate);\n controls.dispose();\n controlsRef.current = null;\n if (model) disposeObject(model);\n scene.clear();\n renderer.renderLists.dispose();\n renderer.dispose();\n renderer.forceContextLoss();\n renderer.domElement.remove();\n };\n }, [content, format]);\n\n if (!content.trim()) {\n return <div className=\"flow-media-image-empty\">输入 STL、OBJ 或 3MF 模型链接</div>;\n }\n\n return (\n <div\n ref={hostRef}\n className=\"flow-media-model3d\"\n style={{ pointerEvents: interactive ? 'auto' : 'none', touchAction: interactive ? 'none' : 'auto' }}\n onPointerDown={event => { if (interactive) event.stopPropagation(); }}\n onWheel={event => { if (interactive) event.stopPropagation(); }}\n >\n {loading && <div className=\"flow-media-loading flow-media-model3d-status\">加载模型…</div>}\n {error && <div className=\"flow-media-error flow-media-model3d-status\">{error}</div>}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AASA,SAAS,EAAc,GAAW;CAChC,IAAM,oBAAY,IAAI,IAAS,GACzB,oBAAW,IAAI,IAAS;CAC9B,EAAK,UAAU,MAAgB;EAC7B,IAAI,EAAE,aAAkB,EAAM,OAAO;EACrC,EAAO,UAAU,QAAQ;EACzB,IAAM,IAAO,MAAM,QAAQ,EAAO,QAAQ,IAAI,EAAO,WAAW,CAAC,EAAO,QAAQ;EAChF,KAAK,IAAM,KAAY,GACjB,IAAC,KAAY,GAAU,IAAI,CAAQ,GACvC;KAAU,IAAI,CAAQ;GACtB,KAAK,IAAM,KAAS,OAAO,OAAO,CAAQ,GACxC,AAAI,aAAiB,EAAM,WAAS,EAAS,IAAI,CAAK;EAFlC;CAK1B,CAAC;CACD,KAAK,IAAM,KAAW,GAAU,EAAQ,QAAQ;CAChD,KAAK,IAAM,KAAY,GAAW,EAAS,QAAQ;AACrD;AAEA,SAAS,EAAW,GAAyB,GAAwB;CACnE,IAAI,MAAW,OAAO;EACpB,IAAM,IAAW,IAAI,EAAU,CAAC,CAAC,MAAM,CAAI;EAE3C,OADK,EAAS,aAAa,QAAQ,KAAG,EAAS,qBAAqB,GAC7D,IAAI,EAAM,KACf,GACA,IAAI,EAAM,qBAAqB;GAC7B,OAAO;GACP,WAAW;GACX,WAAW;GACX,MAAM,EAAM;EACd,CAAC,CACH;CACF;CAIA,OAHI,MAAW,QACN,IAAI,EAAU,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,IAEtD,IAAI,EAAc,CAAC,CAAC,MAAM,CAAI;AACvC;AAEA,SAAgB,EAAY,EAC1B,YACA,WACA,kBAKC;CACD,IAAM,IAAU,EAAuB,IAAI,GACrC,IAAc,EAA6B,IAAI,GAC/C,IAAiB,EAAO,CAAW,GACnC,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAK;CAiI5C,OA/HA,QAAgB;EAEd,AADA,EAAe,UAAU,GACrB,EAAY,YAAS,EAAY,QAAQ,UAAU;CACzD,GAAG,CAAC,CAAW,CAAC,GAEhB,QAAgB;EACd,IAAM,IAAO,EAAQ,SACf,IAAS,EAAQ,KAAK;EAC5B,IAAI,CAAC,KAAQ,CAAC,GAAQ;EAEtB,IAAI,IAAY,IACZ,IAAa,MACX,IAAQ,IAAI,gBAAgB,GAC5B,IAAQ,IAAI,EAAM,MAAM,GACxB,IAAS,IAAI,EAAM,kBAAkB,IAAI,GAAG,KAAM,GAAK,GACvD,IAAW,IAAI,EAAM,cAAc;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EAMzE,AALA,EAAS,cAAc,KAAK,IAAI,OAAO,oBAAoB,GAAG,CAAC,CAAC,GAChE,EAAS,mBAAmB,EAAM,gBAClC,EAAS,cAAc,GAAU,CAAC,GAClC,EAAK,YAAY,EAAS,UAAU,GAEpC,EAAM,IAAI,IAAI,EAAM,gBAAgB,UAAU,SAAU,CAAC,CAAC;EAC1D,IAAM,IAAc,IAAI,EAAM,iBAAiB,UAAU,GAAG;EAE5D,AADA,EAAY,SAAS,IAAI,GAAG,GAAG,CAAC,GAChC,EAAM,IAAI,CAAW;EAErB,IAAM,IAAW,IAAI,EAAc,GAAQ,EAAS,UAAU;EAG9D,AAFA,EAAS,gBAAgB,IACzB,EAAS,UAAU,EAAe,SAClC,EAAY,UAAU;EAEtB,IAAM,IAAU,EAAmB;GACjC,cAAc,EAAS,OAAO;GAC9B,cAAc,EAAS,OAAO,GAAO,CAAM;EAC7C,CAAC;EACD,EAAS,iBAAiB,UAAU,EAAQ,UAAU;EAGtD,IAAI,IAAe,OAAO,uBAAyB,KAC7C,UAAyB,EAAQ,UAAU,KAAgB,CAAC,SAAS,MAAM,GAC3E,IAAqB,OAAO,uBAAyB,MAAc,OAAO,IAAI,sBAAqB,MAAW;GAElH,AADA,IAAe,EAAQ,MAAK,MAAS,EAAM,kBAAkB,EAAM,iBAAiB,QAAQ,KAAK,EAAM,iBAAiB,SAAS,CAAC,GAClI,EAAiB;EACnB,CAAC;EAGD,AAFA,GAAoB,QAAQ,CAAI,GAChC,SAAS,iBAAiB,oBAAoB,CAAgB,GAC9D,EAAiB;EAEjB,IAAM,UAAe;GACnB,IAAM,IAAQ,KAAK,IAAI,GAAG,EAAK,WAAW,GACpC,IAAS,KAAK,IAAI,GAAG,EAAK,YAAY;GAI5C,AAHA,EAAS,QAAQ,GAAO,GAAQ,EAAK,GACrC,EAAO,SAAS,IAAQ,GACxB,EAAO,uBAAuB,GAC9B,EAAQ,WAAW;EACrB;EACA,EAAO;EACP,IAAM,IAAW,IAAI,eAAe,CAAM;EA+C1C,OA9CA,EAAS,QAAQ,CAAI,GAErB,EAAW,EAAI,GACf,EAAS,IAAI,GACb,MAAM,GAAQ,EAAE,QAAQ,EAAM,OAAO,CAAC,CAAC,CACpC,MAAK,MAAY;GAChB,IAAI,CAAC,EAAS,IAAI,MAAU,MAAM,eAAe,EAAS,QAAQ;GAClE,OAAO,EAAS,YAAY;EAC9B,CAAC,CAAC,CACD,MAAK,MAAQ;GACZ,IAAI,EAAK,aAAa,UAAkB,MAAU,MAAM,kBAAkB;GAC1E,IAAM,IAAO,EAAW,GAAQ,CAAI;GACpC,IAAI,GAAW;IACb,EAAc,CAAI;IAClB;GACF;GAEA,AADA,IAAQ,GACR,EAAK,kBAAkB,EAAI;GAC3B,IAAM,IAAM,IAAI,EAAM,KAAK,CAAC,CAAC,cAAc,CAAI;GAC/C,IAAI,EAAI,QAAQ,GAAG,MAAU,MAAM,cAAc;GACjD,IAAM,IAAS,EAAI,UAAU,IAAI,EAAM,QAAQ,CAAC;GAEhD,AADA,EAAK,SAAS,IAAI,CAAM,GACxB,EAAK,kBAAkB,EAAI;GAC3B,IAAM,IAAS,IAAI,EAAM,KAAK,CAAC,CAAC,cAAc,CAAI,CAAC,CAAC,kBAAkB,IAAI,EAAM,OAAO,CAAC;GACxF,IAAI,CAAC,OAAO,SAAS,EAAO,MAAM,KAAK,EAAO,UAAU,GAAG,MAAU,MAAM,QAAQ;GACnF,EAAM,IAAI,CAAI;GAEd,IAAM,IAAW,EAAM,UAAU,SAAS,EAAO,MAAM,CAAC,GAClD,IAAW,KAAK,KAAK,KAAK,IAAI,CAAQ,IAAI,EAAO,MAAM,GACvD,IAAY,EAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAU,CAAQ,CAAC,IAAK;GAQ5E,AAPA,EAAO,SAAS,KAAK,IAAI,EAAM,QAAQ,GAAG,KAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,eAAe,CAAQ,CAAC,GACvF,EAAO,OAAO,KAAK,IAAI,EAAO,SAAS,KAAM,IAAK,GAClD,EAAO,MAAM,KAAK,IAAI,IAAW,EAAO,SAAS,IAAI,EAAO,SAAS,GAAI,GACzE,EAAO,uBAAuB,GAC9B,EAAS,OAAO,IAAI,GAAG,GAAG,CAAC,GAC3B,EAAS,cAAc,EAAO,SAAS,KACvC,EAAS,cAAc,EAAO,SAAS,KACvC,EAAQ,WAAW;EACrB,CAAC,CAAC,CACD,OAAM,MAAa;GAClB,AAAI,CAAC,KAAa,GAAW,SAAS,gBAAc,EAAS,GAAW,WAAW,QAAQ;EAC7F,CAAC,CAAC,CACD,cAAc;GACb,AAAK,KAAW,EAAW,EAAK;EAClC,CAAC,SAEU;GAeX,AAdA,IAAY,IACZ,EAAM,MAAM,GACZ,EAAQ,QAAQ,GAChB,EAAS,WAAW,GACpB,GAAoB,WAAW,GAC/B,SAAS,oBAAoB,oBAAoB,CAAgB,GACjE,EAAS,oBAAoB,UAAU,EAAQ,UAAU,GACzD,EAAS,QAAQ,GACjB,EAAY,UAAU,MAClB,KAAO,EAAc,CAAK,GAC9B,EAAM,MAAM,GACZ,EAAS,YAAY,QAAQ,GAC7B,EAAS,QAAQ,GACjB,EAAS,iBAAiB,GAC1B,EAAS,WAAW,OAAO;EAC7B;CACF,GAAG,CAAC,GAAS,CAAM,CAAC,GAEf,EAAQ,KAAK,IAKhB,kBAAC,OAAD;EACE,KAAK;EACL,WAAU;EACV,OAAO;GAAE,eAAe,IAAc,SAAS;GAAQ,aAAa,IAAc,SAAS;EAAO;EAClG,gBAAe,MAAS;GAAE,AAAI,KAAa,EAAM,gBAAgB;EAAG;EACpE,UAAS,MAAS;GAAE,AAAI,KAAa,EAAM,gBAAgB;EAAG;EALhE,UAAA,CAOG,KAAW,kBAAC,OAAD;GAAK,WAAU;GAA+C,UAAA;EAAU,CAAA,GACnF,KAAS,kBAAC,OAAD;GAAK,WAAU;GAA8C,UAAA;EAAW,CAAA,CAC/E;MAbE,kBAAC,OAAD;EAAK,WAAU;EAAyB,UAAA;CAA0B,CAAA;AAe7E"}
@@ -0,0 +1,14 @@
1
+ import type { ChartMark, SceneNode } from '@tanstack/charts';
2
+ type Position = readonly [number, number];
3
+ /** Keep sparse charts' dots, but not overlapping dots in dense/multi-series lines. */
4
+ export declare function showLinePoints(rowCount: number, seriesCount: number, width: number): boolean;
5
+ /**
6
+ * First/min/max/last per two CSS plot pixels (at most ~2 vertices/pixel).
7
+ * Keep source order and extrema. Repeated/non-monotonic category positions are
8
+ * deliberately left alone: bucketing them can change backtracking geometry.
9
+ */
10
+ export declare function budgetPolyline(points: readonly Position[]): readonly Position[];
11
+ export declare function budgetChartNode(node: SceneNode): SceneNode;
12
+ /** Budget only display geometry, after full-data domains and tooltip points exist. */
13
+ export declare function withChartGeometryBudget<T extends ChartMark<any, any, any, any, any, any, any>>(mark: T): T;
14
+ export {};
@@ -0,0 +1,76 @@
1
+ //#region src/components/pro/Flow/nodes/chartGeometryBudget.ts
2
+ function e(e, t, n) {
3
+ return e * t <= Math.min(200, Math.floor(Math.max(0, n) / 6));
4
+ }
5
+ function t(e) {
6
+ if (e.length < 3) return e;
7
+ let t = -Infinity;
8
+ for (let [n, r] of e) {
9
+ if (!Number.isFinite(n) || !Number.isFinite(r) || n <= t) return e;
10
+ t = n;
11
+ }
12
+ let n = [];
13
+ for (let t = 0; t < e.length;) {
14
+ let r = Math.floor(e[t][0] / 2), i = t + 1, a = t, o = t;
15
+ for (; i < e.length && Math.floor(e[i][0] / 2) === r;) e[i][1] < e[a][1] && (a = i), e[i][1] > e[o][1] && (o = i), i++;
16
+ let s = [
17
+ t,
18
+ Math.min(a, o),
19
+ Math.max(a, o),
20
+ i - 1
21
+ ];
22
+ for (let t = 0; t < s.length; t++) (t === 0 || s[t] !== s[t - 1]) && n.push(e[s[t]]);
23
+ t = i;
24
+ }
25
+ return n.length < e.length ? n : e;
26
+ }
27
+ function n(e) {
28
+ if (e.kind === "group") return {
29
+ ...e,
30
+ children: e.children.map(n)
31
+ };
32
+ if (e.kind === "polyline" && !e.path) {
33
+ let n = t(e.points);
34
+ return n === e.points ? e : {
35
+ ...e,
36
+ points: n
37
+ };
38
+ }
39
+ if (e.kind === "area" && !e.path && !e.polygons) {
40
+ let n = e.interaction?.points?.length;
41
+ if (n && e.points.length === n * 2) {
42
+ let r = e.points.slice(0, n), i = Array.from({ length: n }, (t, n) => e.points[e.points.length - 1 - n]), a = t(r), o = t(i);
43
+ if (a !== r || o !== i) {
44
+ let t = [...a];
45
+ for (let e = o.length - 1; e >= 0; e--) t.push(o[e]);
46
+ return {
47
+ ...e,
48
+ points: t
49
+ };
50
+ }
51
+ }
52
+ }
53
+ return e;
54
+ }
55
+ function r(e) {
56
+ return {
57
+ ...e,
58
+ initialize(t) {
59
+ let r = e.initialize(t);
60
+ return {
61
+ ...r,
62
+ render(e) {
63
+ let t = r.render(e);
64
+ return {
65
+ ...t,
66
+ nodes: t.nodes.map(n)
67
+ };
68
+ }
69
+ };
70
+ }
71
+ };
72
+ }
73
+ //#endregion
74
+ export { n as budgetChartNode, t as budgetPolyline, e as showLinePoints, r as withChartGeometryBudget };
75
+
76
+ //# sourceMappingURL=chartGeometryBudget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chartGeometryBudget.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/chartGeometryBudget.ts"],"sourcesContent":["import type { ChartMark, SceneNode } from '@tanstack/charts';\n\ntype Position = readonly [number, number];\n\n/** Keep sparse charts' dots, but not overlapping dots in dense/multi-series lines. */\nexport function showLinePoints(rowCount: number, seriesCount: number, width: number) {\n return rowCount * seriesCount <= Math.min(200, Math.floor(Math.max(0, width) / 6));\n}\n\n/**\n * First/min/max/last per two CSS plot pixels (at most ~2 vertices/pixel).\n * Keep source order and extrema. Repeated/non-monotonic category positions are\n * deliberately left alone: bucketing them can change backtracking geometry.\n */\nexport function budgetPolyline(points: readonly Position[]): readonly Position[] {\n if (points.length < 3) return points;\n let previousX = -Infinity;\n for (const [x, y] of points) {\n if (!Number.isFinite(x) || !Number.isFinite(y) || x <= previousX) return points;\n previousX = x;\n }\n const result: Position[] = [];\n for (let start = 0; start < points.length;) {\n const bucket = Math.floor(points[start][0] / 2);\n let end = start + 1, min = start, max = start;\n while (end < points.length && Math.floor(points[end][0] / 2) === bucket) {\n if (points[end][1] < points[min][1]) min = end;\n if (points[end][1] > points[max][1]) max = end;\n end++;\n }\n const indices = [start, Math.min(min, max), Math.max(min, max), end - 1];\n for (let i = 0; i < indices.length; i++) {\n if (i === 0 || indices[i] !== indices[i - 1]) result.push(points[indices[i]]);\n }\n start = end;\n }\n return result.length < points.length ? result : points;\n}\n\nexport function budgetChartNode(node: SceneNode): SceneNode {\n if (node.kind === 'group') return { ...node, children: node.children.map(budgetChartNode) };\n // Never rewrite precomputed curves or arbitrary polygons. Interaction points\n // remain the full-resolution source data, separate from the painted vertices.\n if (node.kind === 'polyline' && !node.path) {\n const points = budgetPolyline(node.points);\n return points === node.points ? node : { ...node, points };\n }\n if (node.kind === 'area' && !node.path && !node.polygons) {\n const count = node.interaction?.points?.length;\n // areaY emits the upper edge then the reversed lower edge for each gap-\n // separated segment. Check this shape before applying the budget.\n if (count && node.points.length === count * 2) {\n const top = node.points.slice(0, count);\n const bottom = Array.from({ length: count }, (_, i) => node.points[node.points.length - 1 - i]);\n const upper = budgetPolyline(top), lower = budgetPolyline(bottom);\n if (upper !== top || lower !== bottom) {\n const points = [...upper];\n for (let i = lower.length - 1; i >= 0; i--) points.push(lower[i]);\n return { ...node, points };\n }\n }\n }\n return node;\n}\n\n/** Budget only display geometry, after full-data domains and tooltip points exist. */\nexport function withChartGeometryBudget<T extends ChartMark<any, any, any, any, any, any, any>>(mark: T): T {\n return {\n ...mark,\n initialize(context) {\n const initialized = mark.initialize(context);\n return {\n ...initialized,\n render(renderContext) {\n const scene = initialized.render(renderContext);\n return { ...scene, nodes: scene.nodes.map(budgetChartNode) };\n },\n };\n },\n };\n}\n"],"mappings":";AAKA,SAAgB,EAAe,GAAkB,GAAqB,GAAe;CACnF,OAAO,IAAW,KAAe,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,CAAK,IAAI,CAAC,CAAC;AACnF;AAOA,SAAgB,EAAe,GAAkD;CAC/E,IAAI,EAAO,SAAS,GAAG,OAAO;CAC9B,IAAI,IAAY;CAChB,KAAK,IAAM,CAAC,GAAG,MAAM,GAAQ;EAC3B,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,GAAW,OAAO;EACzE,IAAY;CACd;CACA,IAAM,IAAqB,CAAC;CAC5B,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAO,SAAS;EAC1C,IAAM,IAAS,KAAK,MAAM,EAAO,EAAM,CAAC,KAAK,CAAC,GAC1C,IAAM,IAAQ,GAAG,IAAM,GAAO,IAAM;EACxC,OAAO,IAAM,EAAO,UAAU,KAAK,MAAM,EAAO,EAAI,CAAC,KAAK,CAAC,MAAM,IAG/D,AAFI,EAAO,EAAI,CAAC,KAAK,EAAO,EAAI,CAAC,OAAI,IAAM,IACvC,EAAO,EAAI,CAAC,KAAK,EAAO,EAAI,CAAC,OAAI,IAAM,IAC3C;EAEF,IAAM,IAAU;GAAC;GAAO,KAAK,IAAI,GAAK,CAAG;GAAG,KAAK,IAAI,GAAK,CAAG;GAAG,IAAM;EAAC;EACvE,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAClC,CAAI,MAAM,KAAK,EAAQ,OAAO,EAAQ,IAAI,OAAI,EAAO,KAAK,EAAO,EAAQ,GAAG;EAE9E,IAAQ;CACV;CACA,OAAO,EAAO,SAAS,EAAO,SAAS,IAAS;AAClD;AAEA,SAAgB,EAAgB,GAA4B;CAC1D,IAAI,EAAK,SAAS,SAAS,OAAO;EAAE,GAAG;EAAM,UAAU,EAAK,SAAS,IAAI,CAAe;CAAE;CAG1F,IAAI,EAAK,SAAS,cAAc,CAAC,EAAK,MAAM;EAC1C,IAAM,IAAS,EAAe,EAAK,MAAM;EACzC,OAAO,MAAW,EAAK,SAAS,IAAO;GAAE,GAAG;GAAM;EAAO;CAC3D;CACA,IAAI,EAAK,SAAS,UAAU,CAAC,EAAK,QAAQ,CAAC,EAAK,UAAU;EACxD,IAAM,IAAQ,EAAK,aAAa,QAAQ;EAGxC,IAAI,KAAS,EAAK,OAAO,WAAW,IAAQ,GAAG;GAC7C,IAAM,IAAM,EAAK,OAAO,MAAM,GAAG,CAAK,GAChC,IAAS,MAAM,KAAK,EAAE,QAAQ,EAAM,IAAI,GAAG,MAAM,EAAK,OAAO,EAAK,OAAO,SAAS,IAAI,EAAE,GACxF,IAAQ,EAAe,CAAG,GAAG,IAAQ,EAAe,CAAM;GAChE,IAAI,MAAU,KAAO,MAAU,GAAQ;IACrC,IAAM,IAAS,CAAC,GAAG,CAAK;IACxB,KAAK,IAAI,IAAI,EAAM,SAAS,GAAG,KAAK,GAAG,KAAK,EAAO,KAAK,EAAM,EAAE;IAChE,OAAO;KAAE,GAAG;KAAM;IAAO;GAC3B;EACF;CACF;CACA,OAAO;AACT;AAGA,SAAgB,EAAgF,GAAY;CAC1G,OAAO;EACL,GAAG;EACH,WAAW,GAAS;GAClB,IAAM,IAAc,EAAK,WAAW,CAAO;GAC3C,OAAO;IACL,GAAG;IACH,OAAO,GAAe;KACpB,IAAM,IAAQ,EAAY,OAAO,CAAa;KAC9C,OAAO;MAAE,GAAG;MAAO,OAAO,EAAM,MAAM,IAAI,CAAe;KAAE;IAC7D;GACF;EACF;CACF;AACF"}
@@ -0,0 +1,11 @@
1
+ /** One pending frame at most; OrbitControls.update() reports when damping settles. */
2
+ export declare function createDemandRender({ update, render, request, cancel, }: {
3
+ update: () => boolean;
4
+ render: () => void;
5
+ request?: (callback: FrameRequestCallback) => number;
6
+ cancel?: (id: number) => void;
7
+ }): {
8
+ invalidate: () => void;
9
+ setActive(next: boolean): void;
10
+ dispose(): void;
11
+ };
@@ -0,0 +1,26 @@
1
+ //#region src/components/pro/Flow/nodes/demandRender.ts
2
+ function e({ update: e, render: t, request: n = requestAnimationFrame, cancel: r = cancelAnimationFrame }) {
3
+ let i = null, a = !1, o = !1, s = !1, c = !0, l = () => {
4
+ a && !o && i === null && (i = n(u));
5
+ }, u = () => {
6
+ if (i = null, !a || o) return;
7
+ s = !0;
8
+ let n = e();
9
+ s = !1, (c || n) && t(), c = !1, n && l();
10
+ }, d = () => {
11
+ s || o || (c = !0, l());
12
+ };
13
+ return {
14
+ invalidate: d,
15
+ setActive(e) {
16
+ a === e || o || (a = e, a ? d() : i !== null && (r(i), i = null));
17
+ },
18
+ dispose() {
19
+ o = !0, i !== null && r(i), i = null;
20
+ }
21
+ };
22
+ }
23
+ //#endregion
24
+ export { e as createDemandRender };
25
+
26
+ //# sourceMappingURL=demandRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demandRender.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/demandRender.ts"],"sourcesContent":["/** One pending frame at most; OrbitControls.update() reports when damping settles. */\nexport function createDemandRender({\n update,\n render,\n request = requestAnimationFrame,\n cancel = cancelAnimationFrame,\n}: {\n update: () => boolean;\n render: () => void;\n request?: (callback: FrameRequestCallback) => number;\n cancel?: (id: number) => void;\n}) {\n let frame: number | null = null;\n let active = false;\n let disposed = false;\n let updating = false;\n let dirty = true;\n\n const schedule = () => {\n if (active && !disposed && frame === null) frame = request(tick);\n };\n const tick = () => {\n frame = null;\n if (!active || disposed) return;\n updating = true;\n const changed = update();\n updating = false;\n if (dirty || changed) render();\n dirty = false;\n if (changed) schedule();\n };\n const invalidate = () => {\n // update() emits change synchronously; its boolean result already accounts\n // for that change. Scheduling here would leave an extra perpetual RAF.\n if (updating || disposed) return;\n dirty = true;\n schedule();\n };\n return {\n invalidate,\n setActive(next: boolean) {\n if (active === next || disposed) return;\n active = next;\n if (active) invalidate();\n else if (frame !== null) {\n cancel(frame);\n frame = null;\n }\n },\n dispose() {\n disposed = true;\n if (frame !== null) cancel(frame);\n frame = null;\n },\n };\n}\n"],"mappings":";AACA,SAAgB,EAAmB,EACjC,WACA,WACA,aAAU,uBACV,YAAS,wBAMR;CACD,IAAI,IAAuB,MACvB,IAAS,IACT,IAAW,IACX,IAAW,IACX,IAAQ,IAEN,UAAiB;EACrB,AAAI,KAAU,CAAC,KAAY,MAAU,SAAM,IAAQ,EAAQ,CAAI;CACjE,GACM,UAAa;EAEjB,IADA,IAAQ,MACJ,CAAC,KAAU,GAAU;EACzB,IAAW;EACX,IAAM,IAAU,EAAO;EAIvB,AAHA,IAAW,KACP,KAAS,MAAS,EAAO,GAC7B,IAAQ,IACJ,KAAS,EAAS;CACxB,GACM,UAAmB;EAGnB,KAAY,MAChB,IAAQ,IACR,EAAS;CACX;CACA,OAAO;EACL;EACA,UAAU,GAAe;GACnB,MAAW,KAAQ,MACvB,IAAS,GACL,IAAQ,EAAW,IACd,MAAU,SACjB,EAAO,CAAK,GACZ,IAAQ;EAEZ;EACA,UAAU;GAGR,AAFA,IAAW,IACP,MAAU,QAAM,EAAO,CAAK,GAChC,IAAQ;EACV;CACF;AACF"}
@@ -121,11 +121,11 @@ var c = [
121
121
  action: (e) => e
122
122
  }
123
123
  ], l = ({ editor: l }) => {
124
- let [u, d] = i(!1), [f, p] = i(""), [m, h] = i({
124
+ let [u, d] = i(!1), [f, p] = i(null), m = f?.query ?? "", [h, g] = i({
125
125
  x: 0,
126
126
  y: 0
127
- }), [g, _] = i(0), v = r(null), y = r(null), b = r(null), x = r(!1), S = e(() => {
128
- if (l.isDestroyed || !l.isEditable || l.view.composing || x.current) return null;
127
+ }), [_, v] = i(0), y = r(null), b = r(null), x = r(null), S = r(!1), C = e(() => {
128
+ if (l.isDestroyed || !l.isEditable || l.view.composing || S.current) return null;
129
129
  let e = l.state.selection;
130
130
  if (!(e instanceof s) || !e.empty || e.$from.parent.type.spec.code || e.$from.marks().some((e) => e.type.spec.code)) return null;
131
131
  let { $from: t } = e, n = t.parent.textBetween(0, t.parentOffset, "\n", (e) => e.type.name === "hardBreak" ? "\n" : ""), r = /(?:^|\s)\/([^\s/]*)$/.exec(n);
@@ -134,70 +134,80 @@ var c = [
134
134
  to: t.pos,
135
135
  query: r[1]
136
136
  } : null;
137
- }, [l]), C = f ? c.filter((e) => {
138
- let t = f.toLowerCase();
137
+ }, [l]), w = m ? c.filter((e) => {
138
+ let t = m.toLowerCase();
139
139
  return e.label.toLowerCase().includes(t) || e.description.toLowerCase().includes(t) || e.keywords?.some((e) => e.includes(t));
140
- }) : c, w = e(() => {
141
- d(!1), p("");
142
- let e = y.current;
143
- e && (b.current = `${e.from}:${e.to}:${e.query}`), y.current = null, _(0);
144
- }, []), T = e((e) => {
145
- let t = S(), n = y.current;
146
- if (!t || !n || t.from !== n.from || t.to !== n.to || t.query !== n.query) {
147
- w();
140
+ }) : c, T = e(() => {
141
+ d(!1), p(null);
142
+ let e = b.current;
143
+ e && (x.current = `${e.from}:${e.to}:${e.query}`), b.current = null, v(0);
144
+ }, []), E = e((e) => {
145
+ let t = C(), n = b.current;
146
+ if (!t || !n || !f || t.from !== f.from || t.to !== f.to || t.query !== f.query || t.from !== n.from || t.to !== n.to || t.query !== n.query) {
147
+ T();
148
148
  return;
149
149
  }
150
150
  let r = e.label === "Image" ? window.prompt("Image URL:")?.trim() : void 0;
151
151
  if (e.label === "Image" && !r) {
152
- w();
152
+ T();
153
153
  return;
154
154
  }
155
- w();
155
+ T();
156
156
  let i = l.chain().focus().deleteRange(t);
157
157
  (r ? i.setImage({ src: r }) : e.action(i)).run();
158
158
  }, [
159
159
  l,
160
- S,
161
- w
160
+ C,
161
+ T,
162
+ f
162
163
  ]);
163
164
  return t(() => {
164
165
  let e, t = () => {
165
- let e = l.isFocused ? S() : null;
166
+ let e = l.isFocused ? C() : null;
166
167
  if (!e) {
167
- y.current = null, b.current = null, d(!1);
168
+ b.current = null, x.current = null, d(!1);
168
169
  return;
169
170
  }
170
- b.current !== `${e.from}:${e.to}:${e.query}` && ((y.current?.query !== e.query || y.current?.from !== e.from) && _(0), y.current = e, p(e.query), d(!0));
171
+ x.current !== `${e.from}:${e.to}:${e.query}` && ((b.current?.query !== e.query || b.current?.from !== e.from) && v(0), b.current = e, p(e), d(!0));
171
172
  }, n = () => {
172
- x.current = !0, w();
173
+ S.current = !0, T();
173
174
  }, r = () => {
174
- x.current = !1, b.current = null, e = setTimeout(t, 0);
175
+ S.current = !1, x.current = null, e = setTimeout(t, 0);
175
176
  }, i = l.view.dom;
176
- return l.on("transaction", t), l.on("blur", w), i.addEventListener("compositionstart", n), i.addEventListener("compositionend", r), () => {
177
- clearTimeout(e), l.off("transaction", t), l.off("blur", w), i.removeEventListener("compositionstart", n), i.removeEventListener("compositionend", r);
177
+ return l.on("transaction", t), l.on("blur", T), i.addEventListener("compositionstart", n), i.addEventListener("compositionend", r), () => {
178
+ clearTimeout(e), l.off("transaction", t), l.off("blur", T), i.removeEventListener("compositionstart", n), i.removeEventListener("compositionend", r);
178
179
  };
179
180
  }, [
180
181
  l,
181
- S,
182
- w
182
+ C,
183
+ T
183
184
  ]), n(() => {
184
- if (!u || !C.length) return;
185
- let e = l.view.dom.closest(".rte-editor-wrapper"), t = v.current;
185
+ if (!u || !w.length) return;
186
+ let e = l.view.dom.closest(".rte-editor-wrapper"), t = y.current;
186
187
  if (!e || !t) return;
187
188
  let n = () => {
188
- let n = S();
189
+ let n = C();
189
190
  if (!n) {
190
- w();
191
+ T();
192
+ return;
193
+ }
194
+ let r = l.view.coordsAtPos(n.to), i = e.getBoundingClientRect(), a = Math.max(8, i.left + e.clientLeft), o = Math.min(window.innerWidth - 8, i.right), s = Math.max(8, i.top + e.clientTop), c = Math.min(window.innerHeight - 8, i.bottom);
195
+ if (o <= a || c <= s || r.bottom < s || r.top > c) {
196
+ T();
191
197
  return;
192
198
  }
193
- let r = l.view.coordsAtPos(n.to), i = e.getBoundingClientRect(), a = Math.max(8, i.left + e.clientLeft), o = Math.min(window.innerWidth - 8, i.right), s = Math.max(8, i.top + e.clientTop), c = Math.min(window.innerHeight - 8, i.bottom), u = Math.min(Math.max(r.top, s), c), d = Math.min(Math.max(r.bottom, s), c);
194
- t.style.minWidth = "0", t.style.width = `${Math.min(280, Math.max(120, o - a))}px`;
195
- let f = c - d - 4, p = u - s - 4, m = f < Math.min(300, t.scrollHeight) && p > f;
196
- t.style.maxHeight = `${Math.max(120, Math.min(300, m ? p : f))}px`;
197
- let g = Math.max(a, Math.min(r.left, o - t.offsetWidth)), _ = m ? u - t.offsetHeight - 4 : d + 4;
198
- h({
199
- x: g - i.left - e.clientLeft + e.scrollLeft,
200
- y: _ - i.top - e.clientTop + e.scrollTop
199
+ let u = Math.min(Math.max(r.top, s), c), d = Math.min(Math.max(r.bottom, s), c);
200
+ t.style.boxSizing = "border-box", t.style.minWidth = "0", t.style.width = `${Math.min(280, o - a)}px`;
201
+ let f = c - d - 4, p = u - s - 4, m = f < Math.min(300, t.scrollHeight) && p > f, h = m ? p : f;
202
+ if (h <= 0) {
203
+ T();
204
+ return;
205
+ }
206
+ t.style.maxHeight = `${Math.min(300, h)}px`;
207
+ let _ = Math.max(a, Math.min(r.left, o - t.offsetWidth)), v = m ? u - t.offsetHeight - 4 : d + 4;
208
+ g({
209
+ x: _ - i.left - e.clientLeft + e.scrollLeft,
210
+ y: v - i.top - e.clientTop + e.scrollTop
201
211
  });
202
212
  };
203
213
  return n(), window.addEventListener("scroll", n, !0), window.addEventListener("resize", n), l.on("transaction", n), () => {
@@ -206,54 +216,54 @@ var c = [
206
216
  }, [
207
217
  l,
208
218
  u,
209
- C.length,
210
- S,
211
- w
219
+ w.length,
220
+ C,
221
+ T
212
222
  ]), t(() => {
213
223
  if (!u) return;
214
- let e = v.current, t = e?.children[g];
224
+ let e = y.current, t = e?.children[_];
215
225
  e && t && (t.offsetTop < e.scrollTop ? e.scrollTop = t.offsetTop : t.offsetTop + t.offsetHeight > e.scrollTop + e.clientHeight && (e.scrollTop = t.offsetTop + t.offsetHeight - e.clientHeight));
216
- }, [g, u]), t(() => {
226
+ }, [_, u]), t(() => {
217
227
  if (!u) return;
218
228
  let e = (e) => {
219
- !l.view.dom.contains(e.target) || !l.isFocused || e.isComposing || e.keyCode === 229 || l.view.composing || x.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || (C.length || e.key === "Escape") && ([
229
+ !l.view.dom.contains(e.target) || !l.isFocused || e.isComposing || e.keyCode === 229 || l.view.composing || S.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || (w.length || e.key === "Escape") && ([
220
230
  "ArrowDown",
221
231
  "ArrowUp",
222
232
  "Enter",
223
233
  "Escape"
224
- ].includes(e.key) && e.stopImmediatePropagation(), e.key === "ArrowDown" ? (e.preventDefault(), _((e) => (e + 1) % C.length)) : e.key === "ArrowUp" ? (e.preventDefault(), _((e) => (e - 1 + C.length) % C.length)) : e.key === "Enter" ? (e.preventDefault(), C[g] && T(C[g])) : e.key === "Escape" && (e.preventDefault(), w()));
234
+ ].includes(e.key) && e.stopImmediatePropagation(), e.key === "ArrowDown" ? (e.preventDefault(), v((e) => (e + 1) % w.length)) : e.key === "ArrowUp" ? (e.preventDefault(), v((e) => (e - 1 + w.length) % w.length)) : e.key === "Enter" ? (e.preventDefault(), w[_] && E(w[_])) : e.key === "Escape" && (e.preventDefault(), T()));
225
235
  };
226
236
  return document.addEventListener("keydown", e, !0), () => document.removeEventListener("keydown", e, !0);
227
237
  }, [
228
238
  l,
229
239
  u,
230
- C,
231
- g,
232
- T,
233
- w
240
+ w,
241
+ _,
242
+ E,
243
+ T
234
244
  ]), t(() => {
235
245
  if (!u) return;
236
246
  let e = (e) => {
237
- v.current && !v.current.contains(e.target) && w();
247
+ y.current && !y.current.contains(e.target) && T();
238
248
  };
239
249
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
240
- }, [u, w]), !u || C.length === 0 ? null : /* @__PURE__ */ a("div", {
241
- ref: v,
250
+ }, [u, T]), !u || w.length === 0 ? null : /* @__PURE__ */ a("div", {
251
+ ref: y,
242
252
  className: "rte-slash-menu",
243
253
  role: "menu",
244
254
  "aria-label": "Insert block",
245
255
  style: {
246
- left: m.x,
247
- top: m.y
256
+ left: h.x,
257
+ top: h.y
248
258
  },
249
259
  onMouseDown: (e) => e.preventDefault(),
250
- children: C.map((e, t) => /* @__PURE__ */ o("button", {
260
+ children: w.map((e, t) => /* @__PURE__ */ o("button", {
251
261
  type: "button",
252
262
  role: "menuitem",
253
263
  tabIndex: -1,
254
- className: `rte-slash-menu__item ${t === g ? "rte-slash-menu__item--active" : ""}`,
255
- onClick: () => T(e),
256
- onMouseEnter: () => _(t),
264
+ className: `rte-slash-menu__item ${t === _ ? "rte-slash-menu__item--active" : ""}`,
265
+ onClick: () => E(e),
266
+ onMouseEnter: () => v(t),
257
267
  children: [/* @__PURE__ */ a("span", {
258
268
  className: "rte-slash-menu__icon",
259
269
  children: e.icon