react-os-shell 0.1.31 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Calculator-ZZMTB7Y7.js → Calculator-VZM3FSTQ.js} +4 -4
- package/dist/{Calculator-ZZMTB7Y7.js.map → Calculator-VZM3FSTQ.js.map} +1 -1
- package/dist/{Calendar-RQVSPJAJ.js → Calendar-7DNNMOKO.js} +3 -3
- package/dist/{Calendar-RQVSPJAJ.js.map → Calendar-7DNNMOKO.js.map} +1 -1
- package/dist/{CurrencyConverter-S37JTKKZ.js → CurrencyConverter-XFIGUZ46.js} +4 -4
- package/dist/{CurrencyConverter-S37JTKKZ.js.map → CurrencyConverter-XFIGUZ46.js.map} +1 -1
- package/dist/{Documents-3P6JKOLE.js → Documents-PK7QFWGR.js} +3 -3
- package/dist/{Documents-3P6JKOLE.js.map → Documents-PK7QFWGR.js.map} +1 -1
- package/dist/{Email-UCNJ53MV.js → Email-66BDCI2Q.js} +3 -3
- package/dist/{Email-UCNJ53MV.js.map → Email-66BDCI2Q.js.map} +1 -1
- package/dist/{Minesweeper-KAOD327F.js → Minesweeper-7OGCUAKF.js} +3 -3
- package/dist/{Minesweeper-KAOD327F.js.map → Minesweeper-7OGCUAKF.js.map} +1 -1
- package/dist/{Notepad-C453L2M2.js → Notepad-MNDA6AHQ.js} +3 -3
- package/dist/{Notepad-C453L2M2.js.map → Notepad-MNDA6AHQ.js.map} +1 -1
- package/dist/{PomodoroTimer-ZZUXEFM6.js → PomodoroTimer-6DHC3H6X.js} +4 -4
- package/dist/{PomodoroTimer-ZZUXEFM6.js.map → PomodoroTimer-6DHC3H6X.js.map} +1 -1
- package/dist/Preview-NK4LOF3L.js +6 -0
- package/dist/{Preview-DO7KHVKG.js.map → Preview-NK4LOF3L.js.map} +1 -1
- package/dist/{Spreadsheet-SOJL4SQA.js → Spreadsheet-JT4TIKCY.js} +3 -3
- package/dist/{Spreadsheet-SOJL4SQA.js.map → Spreadsheet-JT4TIKCY.js.map} +1 -1
- package/dist/{Weather-H7R7YVRB.js → Weather-A6MEC4PN.js} +4 -4
- package/dist/{Weather-H7R7YVRB.js.map → Weather-A6MEC4PN.js.map} +1 -1
- package/dist/apps/index.js +13 -13
- package/dist/{chunk-AKZTZLKP.js → chunk-44AH2OXU.js} +3 -3
- package/dist/{chunk-AKZTZLKP.js.map → chunk-44AH2OXU.js.map} +1 -1
- package/dist/{chunk-RGYSM6P5.js → chunk-MONP6MMC.js} +131 -176
- package/dist/chunk-MONP6MMC.js.map +1 -0
- package/dist/{chunk-D7UDGZIH.js → chunk-UUJLLTV4.js} +3 -3
- package/dist/{chunk-D7UDGZIH.js.map → chunk-UUJLLTV4.js.map} +1 -1
- package/dist/index.js +4 -4
- package/package.json +1 -1
- package/dist/Preview-DO7KHVKG.js +0 -6
- package/dist/chunk-RGYSM6P5.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
2
|
-
import { WindowTitle } from './chunk-
|
|
2
|
+
import { WindowTitle, getActiveModalId } from './chunk-44AH2OXU.js';
|
|
3
3
|
import { useState, useEffect, useRef } from 'react';
|
|
4
4
|
import * as pdfjsLib from 'pdfjs-dist';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -43,19 +43,49 @@ function Preview() {
|
|
|
43
43
|
}, []);
|
|
44
44
|
const titleName = data?.filename ? truncateForTitle(data.filename) : "Untitled";
|
|
45
45
|
const fileRef = useRef(null);
|
|
46
|
+
const rootRef = useRef(null);
|
|
46
47
|
const [isDragging, setIsDragging] = useState(false);
|
|
48
|
+
const dragDepthRef = useRef(0);
|
|
47
49
|
const handlePick = () => fileRef.current?.click();
|
|
50
|
+
const resetDrag = () => {
|
|
51
|
+
dragDepthRef.current = 0;
|
|
52
|
+
setIsDragging(false);
|
|
53
|
+
};
|
|
54
|
+
const isActiveWindow = (el) => {
|
|
55
|
+
const myModal = el.closest("[data-modal-id]");
|
|
56
|
+
if (!myModal) return true;
|
|
57
|
+
return getActiveModalId() === myModal.dataset.modalId;
|
|
58
|
+
};
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const onWindowDragEnd = () => resetDrag();
|
|
61
|
+
const onWindowDrop = () => resetDrag();
|
|
62
|
+
const onKey = (e) => {
|
|
63
|
+
if (e.key === "Escape") resetDrag();
|
|
64
|
+
};
|
|
65
|
+
window.addEventListener("dragend", onWindowDragEnd);
|
|
66
|
+
window.addEventListener("drop", onWindowDrop);
|
|
67
|
+
window.addEventListener("keydown", onKey);
|
|
68
|
+
return () => {
|
|
69
|
+
window.removeEventListener("dragend", onWindowDragEnd);
|
|
70
|
+
window.removeEventListener("drop", onWindowDrop);
|
|
71
|
+
window.removeEventListener("keydown", onKey);
|
|
72
|
+
};
|
|
73
|
+
}, []);
|
|
48
74
|
const ingestFile = (file) => {
|
|
49
|
-
const url = URL.createObjectURL(file);
|
|
50
75
|
const ext = (file.name.split(".").pop() || "").toLowerCase();
|
|
51
76
|
const kind = ext === "pdf" ? "pdf" : ext === "dxf" ? "dxf" : ["jpg", "jpeg", "png", "gif", "webp", "svg", "avif", "bmp"].includes(ext) ? "image" : ["stp", "step", "stl", "obj", "gltf", "glb", "3mf", "iges", "igs", "ply", "fbx"].includes(ext) ? "3d" : void 0;
|
|
52
77
|
if (!kind) {
|
|
53
|
-
URL.revokeObjectURL(url);
|
|
54
78
|
if (ext === "dwg") toast_default.error("DWG files need server-side conversion. Convert to PDF or DXF first.");
|
|
55
79
|
else toast_default.error(`Unsupported file type: .${ext || "unknown"}`);
|
|
56
80
|
return;
|
|
57
81
|
}
|
|
58
|
-
|
|
82
|
+
const url = URL.createObjectURL(file);
|
|
83
|
+
setData((prev) => {
|
|
84
|
+
if (prev?.url?.startsWith("blob:") && prev.url !== url) {
|
|
85
|
+
URL.revokeObjectURL(prev.url);
|
|
86
|
+
}
|
|
87
|
+
return { url, filename: file.name, kind };
|
|
88
|
+
});
|
|
59
89
|
};
|
|
60
90
|
const handleFile = (e) => {
|
|
61
91
|
const file = e.target.files?.[0];
|
|
@@ -64,7 +94,7 @@ function Preview() {
|
|
|
64
94
|
};
|
|
65
95
|
const handleDrop = (e) => {
|
|
66
96
|
e.preventDefault();
|
|
67
|
-
|
|
97
|
+
resetDrag();
|
|
68
98
|
const file = e.dataTransfer.files?.[0];
|
|
69
99
|
if (file) ingestFile(file);
|
|
70
100
|
};
|
|
@@ -147,14 +177,30 @@ function Preview() {
|
|
|
147
177
|
"div",
|
|
148
178
|
{
|
|
149
179
|
className: "relative flex flex-col h-full",
|
|
150
|
-
|
|
180
|
+
ref: rootRef,
|
|
181
|
+
onDragEnter: (e) => {
|
|
182
|
+
if (!e.dataTransfer?.types?.includes?.("Files")) return;
|
|
183
|
+
if (!isActiveWindow(e.currentTarget)) return;
|
|
151
184
|
e.preventDefault();
|
|
185
|
+
dragDepthRef.current++;
|
|
152
186
|
if (!isDragging) setIsDragging(true);
|
|
153
187
|
},
|
|
154
|
-
|
|
155
|
-
if (e.
|
|
188
|
+
onDragOver: (e) => {
|
|
189
|
+
if (!e.dataTransfer?.types?.includes?.("Files")) return;
|
|
190
|
+
if (!isActiveWindow(e.currentTarget)) return;
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
},
|
|
193
|
+
onDragLeave: () => {
|
|
194
|
+
if (dragDepthRef.current > 0) dragDepthRef.current--;
|
|
195
|
+
if (dragDepthRef.current === 0) setIsDragging(false);
|
|
196
|
+
},
|
|
197
|
+
onDrop: (e) => {
|
|
198
|
+
if (!isActiveWindow(e.currentTarget)) {
|
|
199
|
+
resetDrag();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
handleDrop(e);
|
|
156
203
|
},
|
|
157
|
-
onDrop: handleDrop,
|
|
158
204
|
children: [
|
|
159
205
|
/* @__PURE__ */ jsx(WindowTitle, { title: `${titleName} - Preview` }),
|
|
160
206
|
Toolbar,
|
|
@@ -604,7 +650,6 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
604
650
|
const [sectionAxis, setSectionAxis] = useState("z");
|
|
605
651
|
const [sectionFlip, setSectionFlip] = useState(false);
|
|
606
652
|
const [sectionPosition, setSectionPosition] = useState(0.5);
|
|
607
|
-
const [sectionCapColor, setSectionCapColor] = useState("#9aa6b3");
|
|
608
653
|
const sectionRef = useRef(null);
|
|
609
654
|
useEffect(() => {
|
|
610
655
|
let cancelled = false;
|
|
@@ -691,6 +736,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
691
736
|
if (!v?.viewer) return;
|
|
692
737
|
try {
|
|
693
738
|
const visit = (mesh) => {
|
|
739
|
+
if (mesh.userData?.__sectionHelper) return;
|
|
694
740
|
const ud = mesh.userData?.originalMeshInstance ?? mesh.userData;
|
|
695
741
|
const nodeId = ud?.id?.nodeId ?? ud?.nodeId;
|
|
696
742
|
if (typeof nodeId === "number") {
|
|
@@ -728,108 +774,47 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
728
774
|
useEffect(() => {
|
|
729
775
|
const v = viewerRef.current;
|
|
730
776
|
if (!v?.viewer || loading) return;
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
const
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (!renderer || !scene) return;
|
|
739
|
-
if (sectionRef.current) {
|
|
740
|
-
const s = sectionRef.current;
|
|
741
|
-
for (const [mat, prev] of s.materialState.entries()) {
|
|
742
|
-
mat.clippingPlanes = prev.clippingPlanes;
|
|
743
|
-
mat.clipShadows = prev.clipShadows;
|
|
744
|
-
mat.needsUpdate = true;
|
|
745
|
-
}
|
|
746
|
-
for (const helper of s.helpers) {
|
|
747
|
-
helper.parent?.remove(helper);
|
|
748
|
-
helper.geometry?.dispose?.();
|
|
749
|
-
helper.material?.dispose?.();
|
|
750
|
-
}
|
|
751
|
-
if (s.capMesh) {
|
|
752
|
-
scene.remove(s.capMesh);
|
|
753
|
-
s.capMesh.geometry?.dispose?.();
|
|
754
|
-
s.capMesh.material?.dispose?.();
|
|
755
|
-
}
|
|
756
|
-
sectionRef.current = null;
|
|
757
|
-
}
|
|
758
|
-
if (!sectionEnabled) {
|
|
759
|
-
renderer.localClippingEnabled = false;
|
|
760
|
-
v.viewer.Render?.();
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
const bbox = v.viewer.GetBoundingBox?.(() => true);
|
|
764
|
-
if (!bbox) return;
|
|
765
|
-
const plane = new THREE.Plane(new THREE.Vector3(0, 0, -1), 0);
|
|
766
|
-
const helpers = [];
|
|
767
|
-
const materialState = /* @__PURE__ */ new Map();
|
|
768
|
-
const applyToMaterial = (mat) => {
|
|
769
|
-
if (!mat || materialState.has(mat)) return;
|
|
770
|
-
materialState.set(mat, {
|
|
771
|
-
clippingPlanes: mat.clippingPlanes,
|
|
772
|
-
clipShadows: mat.clipShadows
|
|
773
|
-
});
|
|
774
|
-
mat.clippingPlanes = [plane];
|
|
775
|
-
mat.clipShadows = true;
|
|
777
|
+
const renderer = v.viewer.renderer;
|
|
778
|
+
if (!renderer) return;
|
|
779
|
+
if (sectionRef.current) {
|
|
780
|
+
const s = sectionRef.current;
|
|
781
|
+
for (const [mat, prev] of s.materialState.entries()) {
|
|
782
|
+
mat.clippingPlanes = prev.clippingPlanes;
|
|
783
|
+
mat.clipShadows = prev.clipShadows;
|
|
776
784
|
mat.needsUpdate = true;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
const makeStencil = (side, op) => {
|
|
783
|
-
const m = new THREE.MeshBasicMaterial({
|
|
784
|
-
depthWrite: false,
|
|
785
|
-
depthTest: false,
|
|
786
|
-
colorWrite: false,
|
|
787
|
-
stencilWrite: true,
|
|
788
|
-
stencilFunc: THREE.AlwaysStencilFunc,
|
|
789
|
-
stencilFail: op,
|
|
790
|
-
stencilZFail: op,
|
|
791
|
-
stencilZPass: op,
|
|
792
|
-
side,
|
|
793
|
-
clippingPlanes: [plane]
|
|
794
|
-
});
|
|
795
|
-
const helper = new THREE.Mesh(mesh.geometry, m);
|
|
796
|
-
helper.matrixAutoUpdate = false;
|
|
797
|
-
helper.renderOrder = 1;
|
|
798
|
-
helper.userData.__sectionHelper = true;
|
|
799
|
-
mesh.add(helper);
|
|
800
|
-
helpers.push(helper);
|
|
801
|
-
};
|
|
802
|
-
makeStencil(THREE.BackSide, THREE.IncrementWrapStencilOp);
|
|
803
|
-
makeStencil(THREE.FrontSide, THREE.DecrementWrapStencilOp);
|
|
804
|
-
});
|
|
805
|
-
const dx = bbox.max.x - bbox.min.x;
|
|
806
|
-
const dy = bbox.max.y - bbox.min.y;
|
|
807
|
-
const dz = bbox.max.z - bbox.min.z;
|
|
808
|
-
const capSize = Math.max(dx, dy, dz) * 2 || 1;
|
|
809
|
-
const capGeom = new THREE.PlaneGeometry(capSize, capSize);
|
|
810
|
-
const capMat = new THREE.MeshPhongMaterial({
|
|
811
|
-
color: 10135219,
|
|
812
|
-
side: THREE.DoubleSide,
|
|
813
|
-
stencilWrite: true,
|
|
814
|
-
stencilRef: 0,
|
|
815
|
-
stencilFunc: THREE.NotEqualStencilFunc,
|
|
816
|
-
stencilFail: THREE.ReplaceStencilOp,
|
|
817
|
-
stencilZFail: THREE.ReplaceStencilOp,
|
|
818
|
-
stencilZPass: THREE.ReplaceStencilOp
|
|
819
|
-
});
|
|
820
|
-
const capMesh = new THREE.Mesh(capGeom, capMat);
|
|
821
|
-
capMesh.renderOrder = 2;
|
|
822
|
-
scene.add(capMesh);
|
|
823
|
-
renderer.localClippingEnabled = true;
|
|
824
|
-
sectionRef.current = { plane, capMesh, helpers, materialState, bbox };
|
|
785
|
+
}
|
|
786
|
+
sectionRef.current = null;
|
|
787
|
+
}
|
|
788
|
+
if (!sectionEnabled) {
|
|
789
|
+
renderer.localClippingEnabled = false;
|
|
825
790
|
v.viewer.Render?.();
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
const bbox = v.viewer.GetBoundingBox?.(() => true);
|
|
794
|
+
if (!bbox) return;
|
|
795
|
+
const plane = { normal: { x: 0, y: 0, z: -1 }, constant: 0 };
|
|
796
|
+
const materialState = /* @__PURE__ */ new Map();
|
|
797
|
+
const applyToMaterial = (mat) => {
|
|
798
|
+
if (!mat || materialState.has(mat)) return;
|
|
799
|
+
materialState.set(mat, { clippingPlanes: mat.clippingPlanes, clipShadows: mat.clipShadows });
|
|
800
|
+
mat.clippingPlanes = [plane];
|
|
801
|
+
mat.clipShadows = true;
|
|
802
|
+
mat.needsUpdate = true;
|
|
832
803
|
};
|
|
804
|
+
v.viewer.mainModel?.EnumerateMeshes?.((mesh) => {
|
|
805
|
+
if (mesh.userData?.__sectionHelper) return;
|
|
806
|
+
const mat = mesh.material;
|
|
807
|
+
if (Array.isArray(mat)) for (const m of mat) applyToMaterial(m);
|
|
808
|
+
else applyToMaterial(mat);
|
|
809
|
+
});
|
|
810
|
+
v.viewer.mainModel?.EnumerateEdges?.((edge) => {
|
|
811
|
+
const mat = edge.material;
|
|
812
|
+
if (Array.isArray(mat)) for (const m of mat) applyToMaterial(m);
|
|
813
|
+
else applyToMaterial(mat);
|
|
814
|
+
});
|
|
815
|
+
renderer.localClippingEnabled = true;
|
|
816
|
+
sectionRef.current = { plane, capMesh: null, helpers: [], materialState, bbox };
|
|
817
|
+
v.viewer.Render?.();
|
|
833
818
|
}, [sectionEnabled, loading, tree]);
|
|
834
819
|
useEffect(() => {
|
|
835
820
|
const v = viewerRef.current;
|
|
@@ -842,32 +827,15 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
842
827
|
const max = [bbox.max.x, bbox.max.y, bbox.max.z][axisIdx];
|
|
843
828
|
const value = min + (max - min) * sectionPosition;
|
|
844
829
|
const dir = sectionFlip ? 1 : -1;
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
s.plane.normal.set(nx, ny, nz);
|
|
830
|
+
s.plane.normal.x = sectionAxis === "x" ? dir : 0;
|
|
831
|
+
s.plane.normal.y = sectionAxis === "y" ? dir : 0;
|
|
832
|
+
s.plane.normal.z = sectionAxis === "z" ? dir : 0;
|
|
849
833
|
s.plane.constant = -dir * value;
|
|
850
|
-
const cx = (bbox.min.x + bbox.max.x) / 2;
|
|
851
|
-
const cy = (bbox.min.y + bbox.max.y) / 2;
|
|
852
|
-
const cz = (bbox.min.z + bbox.max.z) / 2;
|
|
853
|
-
const center = { x: cx, y: cy, z: cz };
|
|
854
|
-
const dist = nx * center.x + ny * center.y + nz * center.z + s.plane.constant;
|
|
855
|
-
const px = center.x - nx * dist;
|
|
856
|
-
const py = center.y - ny * dist;
|
|
857
|
-
const pz = center.z - nz * dist;
|
|
858
|
-
s.capMesh.position.set(px, py, pz);
|
|
859
|
-
s.capMesh.lookAt(px + nx, py + ny, pz + nz);
|
|
860
|
-
try {
|
|
861
|
-
const m = /^#?([0-9a-f]{6})$/i.exec(sectionCapColor);
|
|
862
|
-
const n = m ? parseInt(m[1], 16) : 10135219;
|
|
863
|
-
s.capMesh.material.color.setHex(n);
|
|
864
|
-
} catch {
|
|
865
|
-
}
|
|
866
834
|
v.viewer.Render?.();
|
|
867
835
|
} catch (err) {
|
|
868
836
|
console.warn("[Preview] section update failed", err);
|
|
869
837
|
}
|
|
870
|
-
}, [sectionEnabled, sectionAxis, sectionFlip, sectionPosition
|
|
838
|
+
}, [sectionEnabled, sectionAxis, sectionFlip, sectionPosition]);
|
|
871
839
|
useEffect(() => {
|
|
872
840
|
if (!showHint || loading) return;
|
|
873
841
|
const t = setTimeout(() => setShowHint(false), 5e3);
|
|
@@ -895,7 +863,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
895
863
|
const handleFit = () => {
|
|
896
864
|
try {
|
|
897
865
|
const v = viewerRef.current;
|
|
898
|
-
const sphere = v?.GetBoundingSphere?.(() => true);
|
|
866
|
+
const sphere = v?.viewer?.GetBoundingSphere?.(() => true);
|
|
899
867
|
if (sphere) v.viewer.FitSphereToWindow(sphere, true);
|
|
900
868
|
v?.viewer?.Render?.();
|
|
901
869
|
} catch {
|
|
@@ -906,7 +874,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
906
874
|
const v = viewerRef.current;
|
|
907
875
|
if (!OV || !v?.viewer) return;
|
|
908
876
|
try {
|
|
909
|
-
const sphere = v.GetBoundingSphere?.(() => true);
|
|
877
|
+
const sphere = v.viewer.GetBoundingSphere?.(() => true);
|
|
910
878
|
if (!sphere) return;
|
|
911
879
|
const c = sphere.center;
|
|
912
880
|
const r = sphere.radius || 1;
|
|
@@ -964,7 +932,6 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
964
932
|
setSectionAxis("z");
|
|
965
933
|
setSectionFlip(false);
|
|
966
934
|
setSectionPosition(0.5);
|
|
967
|
-
setSectionCapColor("#9aa6b3");
|
|
968
935
|
};
|
|
969
936
|
const handleDefaultDownload = () => {
|
|
970
937
|
const a = document.createElement("a");
|
|
@@ -981,24 +948,24 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
981
948
|
/* @__PURE__ */ jsxs(
|
|
982
949
|
"div",
|
|
983
950
|
{
|
|
984
|
-
className: "group flex items-center gap-1 px-1.5 py-1 hover:bg-
|
|
951
|
+
className: "group flex items-center gap-1 px-1.5 py-1 hover:bg-gray-100 cursor-default text-[12px] text-gray-700",
|
|
985
952
|
style: { paddingLeft: `${depth * 12 + 6}px` },
|
|
986
953
|
children: [
|
|
987
954
|
hasChildren ? /* @__PURE__ */ jsx(
|
|
988
955
|
"button",
|
|
989
956
|
{
|
|
990
957
|
onClick: () => toggleExpanded(node.id),
|
|
991
|
-
className: "h-4 w-4 shrink-0 flex items-center justify-center text-
|
|
958
|
+
className: "h-4 w-4 shrink-0 flex items-center justify-center text-gray-500 hover:text-gray-900",
|
|
992
959
|
title: isExpanded ? "Collapse" : "Expand",
|
|
993
960
|
children: /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: isExpanded ? "M19.5 8.25l-7.5 7.5-7.5-7.5" : "M8.25 4.5l7.5 7.5-7.5 7.5" }) })
|
|
994
961
|
}
|
|
995
|
-
) : /* @__PURE__ */ jsx("span", { className: "h-4 w-4 shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "h-1 w-1 rounded-full bg-
|
|
962
|
+
) : /* @__PURE__ */ jsx("span", { className: "h-4 w-4 shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "h-1 w-1 rounded-full bg-gray-400" }) }),
|
|
996
963
|
/* @__PURE__ */ jsx("span", { className: `flex-1 truncate ${isVisible ? "" : "opacity-40"}`, title: node.name, children: node.name }),
|
|
997
964
|
/* @__PURE__ */ jsx(
|
|
998
965
|
"button",
|
|
999
966
|
{
|
|
1000
967
|
onClick: () => fitNode(),
|
|
1001
|
-
className: "h-4 w-4 shrink-0 text-
|
|
968
|
+
className: "h-4 w-4 shrink-0 text-gray-400 hover:text-gray-900 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
1002
969
|
title: "Fit to view",
|
|
1003
970
|
children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" }) })
|
|
1004
971
|
}
|
|
@@ -1007,7 +974,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1007
974
|
"button",
|
|
1008
975
|
{
|
|
1009
976
|
onClick: () => toggleNodeVisible(node),
|
|
1010
|
-
className: "h-4 w-4 shrink-0 text-
|
|
977
|
+
className: "h-4 w-4 shrink-0 text-gray-500 hover:text-gray-900",
|
|
1011
978
|
title: isVisible ? "Hide" : "Show",
|
|
1012
979
|
children: isVisible ? /* @__PURE__ */ jsxs("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: [
|
|
1013
980
|
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" }),
|
|
@@ -1021,12 +988,12 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1021
988
|
isExpanded && hasChildren && /* @__PURE__ */ jsx("div", { children: node.children.map((c) => renderTreeNode(c, depth + 1)) })
|
|
1022
989
|
] }, node.id);
|
|
1023
990
|
};
|
|
1024
|
-
const tBtn = "h-8 w-8 shrink-0 flex items-center justify-center rounded text-
|
|
1025
|
-
const tBtnActive = "h-8 w-8 shrink-0 flex items-center justify-center rounded bg-
|
|
1026
|
-
const tBtnSep = "h-5 w-px bg-
|
|
1027
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full bg-
|
|
1028
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 py-1.5 bg-
|
|
1029
|
-
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold tracking-wide text-
|
|
991
|
+
const tBtn = "h-8 w-8 shrink-0 flex items-center justify-center rounded text-gray-600 hover:bg-gray-200 hover:text-gray-900 transition-colors";
|
|
992
|
+
const tBtnActive = "h-8 w-8 shrink-0 flex items-center justify-center rounded bg-gray-200 text-gray-900";
|
|
993
|
+
const tBtnSep = "h-5 w-px bg-gray-300 mx-1";
|
|
994
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full bg-white", children: [
|
|
995
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 py-1.5 bg-gray-50 border-b border-gray-200 shrink-0", children: [
|
|
996
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold tracking-wide text-gray-700 px-2 truncate max-w-xs", title: filename, children: filename }),
|
|
1030
997
|
/* @__PURE__ */ jsx("div", { className: tBtnSep }),
|
|
1031
998
|
/* @__PURE__ */ jsx("button", { onClick: handleFit, className: tBtn, title: "Fit to view", children: /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" }) }) }),
|
|
1032
999
|
/* @__PURE__ */ jsx("div", { className: tBtnSep }),
|
|
@@ -1050,10 +1017,10 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1050
1017
|
onEmail && /* @__PURE__ */ jsx("button", { onClick: onEmail, className: tBtn, title: "Email", children: /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" }) }) })
|
|
1051
1018
|
] }),
|
|
1052
1019
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex min-h-0", children: [
|
|
1053
|
-
showMeshes && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-
|
|
1054
|
-
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-
|
|
1055
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto py-1", children: tree ? renderTreeNode(tree) : /* @__PURE__ */ jsx("div", { className: "px-3 py-3 text-[11px] text-
|
|
1056
|
-
tree && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-[10px] text-
|
|
1020
|
+
showMeshes && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-gray-50 border-r border-gray-200 flex flex-col", children: [
|
|
1021
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500 border-b border-gray-200", children: "Meshes" }),
|
|
1022
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto py-1", children: tree ? renderTreeNode(tree) : /* @__PURE__ */ jsx("div", { className: "px-3 py-3 text-[11px] text-gray-500 italic", children: loading ? "Reading model\u2026" : "No structure available" }) }),
|
|
1023
|
+
tree && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-[10px] text-gray-500 border-t border-gray-200", children: hidden.size === 0 ? "All visible" : `${hidden.size} hidden` })
|
|
1057
1024
|
] }),
|
|
1058
1025
|
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0", style: { background: bgColor }, children: [
|
|
1059
1026
|
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
@@ -1074,12 +1041,12 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1074
1041
|
] }),
|
|
1075
1042
|
error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center text-sm text-red-600 px-6 text-center bg-white/85", children: error })
|
|
1076
1043
|
] }),
|
|
1077
|
-
showSettings && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-
|
|
1078
|
-
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-
|
|
1079
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-3 text-[12px] text-
|
|
1044
|
+
showSettings && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-gray-50 border-l border-gray-200 flex flex-col", children: [
|
|
1045
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500 border-b border-gray-200", children: "Model Display" }),
|
|
1046
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-3 text-[12px] text-gray-700", children: [
|
|
1080
1047
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1081
1048
|
/* @__PURE__ */ jsx("span", { children: "Background Color" }),
|
|
1082
|
-
/* @__PURE__ */ jsx("input", { type: "color", value: bgColor, onChange: (e) => setBgColor(e.target.value), className: "h-6 w-10 rounded border border-
|
|
1049
|
+
/* @__PURE__ */ jsx("input", { type: "color", value: bgColor, onChange: (e) => setBgColor(e.target.value), className: "h-6 w-10 rounded border border-gray-300 bg-white" })
|
|
1083
1050
|
] }),
|
|
1084
1051
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1085
1052
|
/* @__PURE__ */ jsx("span", { children: "Show Edges" }),
|
|
@@ -1087,7 +1054,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1087
1054
|
"button",
|
|
1088
1055
|
{
|
|
1089
1056
|
onClick: () => setShowEdges((s) => !s),
|
|
1090
|
-
className: `relative h-5 w-9 rounded-full transition-colors ${showEdges ? "bg-blue-500" : "bg-
|
|
1057
|
+
className: `relative h-5 w-9 rounded-full transition-colors ${showEdges ? "bg-blue-500" : "bg-gray-300"}`,
|
|
1091
1058
|
children: /* @__PURE__ */ jsx("span", { className: `absolute top-0.5 h-4 w-4 rounded-full bg-white transition-transform ${showEdges ? "translate-x-4" : "translate-x-0.5"}` })
|
|
1092
1059
|
}
|
|
1093
1060
|
)
|
|
@@ -1101,14 +1068,14 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1101
1068
|
value: edgeColor,
|
|
1102
1069
|
onChange: (e) => setEdgeColor(e.target.value),
|
|
1103
1070
|
disabled: !showEdges,
|
|
1104
|
-
className: "h-6 w-10 rounded border border-
|
|
1071
|
+
className: "h-6 w-10 rounded border border-gray-300 bg-white disabled:opacity-40"
|
|
1105
1072
|
}
|
|
1106
1073
|
)
|
|
1107
1074
|
] }),
|
|
1108
1075
|
/* @__PURE__ */ jsxs("div", { className: showEdges ? "" : "opacity-40 pointer-events-none", children: [
|
|
1109
1076
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [
|
|
1110
1077
|
/* @__PURE__ */ jsx("span", { children: "Edge Threshold" }),
|
|
1111
|
-
/* @__PURE__ */ jsxs("span", { className: "text-
|
|
1078
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-500 tabular-nums", children: [
|
|
1112
1079
|
edgeThreshold,
|
|
1113
1080
|
"\xB0"
|
|
1114
1081
|
] })
|
|
@@ -1126,14 +1093,14 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1126
1093
|
}
|
|
1127
1094
|
)
|
|
1128
1095
|
] }),
|
|
1129
|
-
/* @__PURE__ */ jsxs("div", { className: "border-t border-
|
|
1096
|
+
/* @__PURE__ */ jsxs("div", { className: "border-t border-gray-200 -mx-3 px-3 pt-3 mt-1", children: [
|
|
1130
1097
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1131
1098
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Section View" }),
|
|
1132
1099
|
/* @__PURE__ */ jsx(
|
|
1133
1100
|
"button",
|
|
1134
1101
|
{
|
|
1135
1102
|
onClick: () => setSectionEnabled((s) => !s),
|
|
1136
|
-
className: `relative h-5 w-9 rounded-full transition-colors ${sectionEnabled ? "bg-blue-500" : "bg-
|
|
1103
|
+
className: `relative h-5 w-9 rounded-full transition-colors ${sectionEnabled ? "bg-blue-500" : "bg-gray-300"}`,
|
|
1137
1104
|
children: /* @__PURE__ */ jsx("span", { className: `absolute top-0.5 h-4 w-4 rounded-full bg-white transition-transform ${sectionEnabled ? "translate-x-4" : "translate-x-0.5"}` })
|
|
1138
1105
|
}
|
|
1139
1106
|
)
|
|
@@ -1146,7 +1113,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1146
1113
|
"button",
|
|
1147
1114
|
{
|
|
1148
1115
|
onClick: () => setSectionFlip((f) => !f),
|
|
1149
|
-
className: "text-[10px] text-
|
|
1116
|
+
className: "text-[10px] text-gray-600 hover:text-gray-900 px-1.5 py-0.5 rounded bg-gray-100 hover:bg-gray-200",
|
|
1150
1117
|
title: "Flip section direction",
|
|
1151
1118
|
children: sectionFlip ? "\u2190 flipped" : "flip \u2192"
|
|
1152
1119
|
}
|
|
@@ -1156,7 +1123,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1156
1123
|
"button",
|
|
1157
1124
|
{
|
|
1158
1125
|
onClick: () => setSectionAxis(ax),
|
|
1159
|
-
className: `py-1 rounded text-[11px] font-semibold ${sectionAxis === ax ? "bg-blue-500 text-white" : "bg-
|
|
1126
|
+
className: `py-1 rounded text-[11px] font-semibold ${sectionAxis === ax ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-700 hover:bg-gray-200"}`,
|
|
1160
1127
|
children: ax.toUpperCase()
|
|
1161
1128
|
},
|
|
1162
1129
|
ax
|
|
@@ -1165,7 +1132,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1165
1132
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1166
1133
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [
|
|
1167
1134
|
/* @__PURE__ */ jsx("span", { children: "Position" }),
|
|
1168
|
-
/* @__PURE__ */ jsxs("span", { className: "text-
|
|
1135
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-500 tabular-nums", children: [
|
|
1169
1136
|
Math.round(sectionPosition * 100),
|
|
1170
1137
|
"%"
|
|
1171
1138
|
] })
|
|
@@ -1182,27 +1149,15 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1182
1149
|
className: "w-full accent-blue-500"
|
|
1183
1150
|
}
|
|
1184
1151
|
)
|
|
1185
|
-
] }),
|
|
1186
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1187
|
-
/* @__PURE__ */ jsx("span", { children: "Cap Color" }),
|
|
1188
|
-
/* @__PURE__ */ jsx(
|
|
1189
|
-
"input",
|
|
1190
|
-
{
|
|
1191
|
-
type: "color",
|
|
1192
|
-
value: sectionCapColor,
|
|
1193
|
-
onChange: (e) => setSectionCapColor(e.target.value),
|
|
1194
|
-
className: "h-6 w-10 rounded border border-slate-600 bg-transparent"
|
|
1195
|
-
}
|
|
1196
|
-
)
|
|
1197
1152
|
] })
|
|
1198
1153
|
] })
|
|
1199
1154
|
] })
|
|
1200
1155
|
] }),
|
|
1201
|
-
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-t border-
|
|
1156
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-t border-gray-200", children: /* @__PURE__ */ jsx(
|
|
1202
1157
|
"button",
|
|
1203
1158
|
{
|
|
1204
1159
|
onClick: handleResetDisplay,
|
|
1205
|
-
className: "w-full text-[11px] text-
|
|
1160
|
+
className: "w-full text-[11px] text-gray-700 bg-gray-100 hover:bg-gray-200 rounded py-1.5 transition-colors",
|
|
1206
1161
|
children: "Reset to Default"
|
|
1207
1162
|
}
|
|
1208
1163
|
) })
|
|
@@ -1260,5 +1215,5 @@ function ImagePanel({ url, filename, onDownload, onEmail }) {
|
|
|
1260
1215
|
}
|
|
1261
1216
|
|
|
1262
1217
|
export { Preview, setPdfPreview };
|
|
1263
|
-
//# sourceMappingURL=chunk-
|
|
1264
|
-
//# sourceMappingURL=chunk-
|
|
1218
|
+
//# sourceMappingURL=chunk-MONP6MMC.js.map
|
|
1219
|
+
//# sourceMappingURL=chunk-MONP6MMC.js.map
|