react-os-shell 0.1.32 → 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-X2TQ32VM.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-CZKAKVP6.js → chunk-MONP6MMC.js} +129 -181
- 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-X2TQ32VM.js +0 -6
- package/dist/chunk-CZKAKVP6.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;
|
|
@@ -729,114 +774,47 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
729
774
|
useEffect(() => {
|
|
730
775
|
const v = viewerRef.current;
|
|
731
776
|
if (!v?.viewer || loading) return;
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
if (!renderer || !scene) return;
|
|
740
|
-
if (sectionRef.current) {
|
|
741
|
-
const s = sectionRef.current;
|
|
742
|
-
for (const [mat, prev] of s.materialState.entries()) {
|
|
743
|
-
mat.clippingPlanes = prev.clippingPlanes;
|
|
744
|
-
mat.clipShadows = prev.clipShadows;
|
|
745
|
-
mat.needsUpdate = true;
|
|
746
|
-
}
|
|
747
|
-
for (const helper of s.helpers) {
|
|
748
|
-
helper.parent?.remove(helper);
|
|
749
|
-
helper.geometry?.dispose?.();
|
|
750
|
-
helper.material?.dispose?.();
|
|
751
|
-
}
|
|
752
|
-
if (s.capMesh) {
|
|
753
|
-
scene.remove(s.capMesh);
|
|
754
|
-
s.capMesh.geometry?.dispose?.();
|
|
755
|
-
s.capMesh.material?.dispose?.();
|
|
756
|
-
}
|
|
757
|
-
sectionRef.current = null;
|
|
758
|
-
}
|
|
759
|
-
if (!sectionEnabled) {
|
|
760
|
-
renderer.localClippingEnabled = false;
|
|
761
|
-
v.viewer.Render?.();
|
|
762
|
-
return;
|
|
763
|
-
}
|
|
764
|
-
const bbox = v.viewer.GetBoundingBox?.(() => true);
|
|
765
|
-
if (!bbox) return;
|
|
766
|
-
const plane = new THREE.Plane(new THREE.Vector3(0, 0, -1), 0);
|
|
767
|
-
const helpers = [];
|
|
768
|
-
const materialState = /* @__PURE__ */ new Map();
|
|
769
|
-
const applyToMaterial = (mat) => {
|
|
770
|
-
if (!mat || materialState.has(mat)) return;
|
|
771
|
-
materialState.set(mat, {
|
|
772
|
-
clippingPlanes: mat.clippingPlanes,
|
|
773
|
-
clipShadows: mat.clipShadows
|
|
774
|
-
});
|
|
775
|
-
mat.clippingPlanes = [plane];
|
|
776
|
-
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;
|
|
777
784
|
mat.needsUpdate = true;
|
|
778
|
-
};
|
|
779
|
-
const targets = [];
|
|
780
|
-
v.viewer.mainModel?.EnumerateMeshes?.((mesh) => {
|
|
781
|
-
if (mesh.userData?.__sectionHelper) return;
|
|
782
|
-
targets.push(mesh);
|
|
783
|
-
});
|
|
784
|
-
for (const mesh of targets) {
|
|
785
|
-
const mat = mesh.material;
|
|
786
|
-
if (Array.isArray(mat)) for (const m of mat) applyToMaterial(m);
|
|
787
|
-
else applyToMaterial(mat);
|
|
788
|
-
const makeStencil = (side, op) => {
|
|
789
|
-
const m = new THREE.MeshBasicMaterial({
|
|
790
|
-
depthWrite: false,
|
|
791
|
-
depthTest: false,
|
|
792
|
-
colorWrite: false,
|
|
793
|
-
stencilWrite: true,
|
|
794
|
-
stencilFunc: THREE.AlwaysStencilFunc,
|
|
795
|
-
stencilFail: op,
|
|
796
|
-
stencilZFail: op,
|
|
797
|
-
stencilZPass: op,
|
|
798
|
-
side,
|
|
799
|
-
clippingPlanes: [plane]
|
|
800
|
-
});
|
|
801
|
-
const helper = new THREE.Mesh(mesh.geometry, m);
|
|
802
|
-
helper.matrixAutoUpdate = false;
|
|
803
|
-
helper.renderOrder = 1;
|
|
804
|
-
helper.userData.__sectionHelper = true;
|
|
805
|
-
mesh.add(helper);
|
|
806
|
-
helpers.push(helper);
|
|
807
|
-
};
|
|
808
|
-
makeStencil(THREE.BackSide, THREE.IncrementWrapStencilOp);
|
|
809
|
-
makeStencil(THREE.FrontSide, THREE.DecrementWrapStencilOp);
|
|
810
785
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const capGeom = new THREE.PlaneGeometry(capSize, capSize);
|
|
816
|
-
const capMat = new THREE.MeshPhongMaterial({
|
|
817
|
-
color: 10135219,
|
|
818
|
-
side: THREE.DoubleSide,
|
|
819
|
-
stencilWrite: true,
|
|
820
|
-
stencilRef: 0,
|
|
821
|
-
stencilFunc: THREE.NotEqualStencilFunc,
|
|
822
|
-
stencilFail: THREE.ReplaceStencilOp,
|
|
823
|
-
stencilZFail: THREE.ReplaceStencilOp,
|
|
824
|
-
stencilZPass: THREE.ReplaceStencilOp
|
|
825
|
-
});
|
|
826
|
-
const capMesh = new THREE.Mesh(capGeom, capMat);
|
|
827
|
-
capMesh.renderOrder = 2;
|
|
828
|
-
capMesh.userData.__sectionHelper = true;
|
|
829
|
-
scene.add(capMesh);
|
|
830
|
-
renderer.localClippingEnabled = true;
|
|
831
|
-
sectionRef.current = { plane, capMesh, helpers, materialState, bbox };
|
|
786
|
+
sectionRef.current = null;
|
|
787
|
+
}
|
|
788
|
+
if (!sectionEnabled) {
|
|
789
|
+
renderer.localClippingEnabled = false;
|
|
832
790
|
v.viewer.Render?.();
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
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;
|
|
839
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?.();
|
|
840
818
|
}, [sectionEnabled, loading, tree]);
|
|
841
819
|
useEffect(() => {
|
|
842
820
|
const v = viewerRef.current;
|
|
@@ -849,32 +827,15 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
849
827
|
const max = [bbox.max.x, bbox.max.y, bbox.max.z][axisIdx];
|
|
850
828
|
const value = min + (max - min) * sectionPosition;
|
|
851
829
|
const dir = sectionFlip ? 1 : -1;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
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;
|
|
856
833
|
s.plane.constant = -dir * value;
|
|
857
|
-
const cx = (bbox.min.x + bbox.max.x) / 2;
|
|
858
|
-
const cy = (bbox.min.y + bbox.max.y) / 2;
|
|
859
|
-
const cz = (bbox.min.z + bbox.max.z) / 2;
|
|
860
|
-
const center = { x: cx, y: cy, z: cz };
|
|
861
|
-
const dist = nx * center.x + ny * center.y + nz * center.z + s.plane.constant;
|
|
862
|
-
const px = center.x - nx * dist;
|
|
863
|
-
const py = center.y - ny * dist;
|
|
864
|
-
const pz = center.z - nz * dist;
|
|
865
|
-
s.capMesh.position.set(px, py, pz);
|
|
866
|
-
s.capMesh.lookAt(px + nx, py + ny, pz + nz);
|
|
867
|
-
try {
|
|
868
|
-
const m = /^#?([0-9a-f]{6})$/i.exec(sectionCapColor);
|
|
869
|
-
const n = m ? parseInt(m[1], 16) : 10135219;
|
|
870
|
-
s.capMesh.material.color.setHex(n);
|
|
871
|
-
} catch {
|
|
872
|
-
}
|
|
873
834
|
v.viewer.Render?.();
|
|
874
835
|
} catch (err) {
|
|
875
836
|
console.warn("[Preview] section update failed", err);
|
|
876
837
|
}
|
|
877
|
-
}, [sectionEnabled, sectionAxis, sectionFlip, sectionPosition
|
|
838
|
+
}, [sectionEnabled, sectionAxis, sectionFlip, sectionPosition]);
|
|
878
839
|
useEffect(() => {
|
|
879
840
|
if (!showHint || loading) return;
|
|
880
841
|
const t = setTimeout(() => setShowHint(false), 5e3);
|
|
@@ -902,7 +863,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
902
863
|
const handleFit = () => {
|
|
903
864
|
try {
|
|
904
865
|
const v = viewerRef.current;
|
|
905
|
-
const sphere = v?.GetBoundingSphere?.(() => true);
|
|
866
|
+
const sphere = v?.viewer?.GetBoundingSphere?.(() => true);
|
|
906
867
|
if (sphere) v.viewer.FitSphereToWindow(sphere, true);
|
|
907
868
|
v?.viewer?.Render?.();
|
|
908
869
|
} catch {
|
|
@@ -913,7 +874,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
913
874
|
const v = viewerRef.current;
|
|
914
875
|
if (!OV || !v?.viewer) return;
|
|
915
876
|
try {
|
|
916
|
-
const sphere = v.GetBoundingSphere?.(() => true);
|
|
877
|
+
const sphere = v.viewer.GetBoundingSphere?.(() => true);
|
|
917
878
|
if (!sphere) return;
|
|
918
879
|
const c = sphere.center;
|
|
919
880
|
const r = sphere.radius || 1;
|
|
@@ -971,7 +932,6 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
971
932
|
setSectionAxis("z");
|
|
972
933
|
setSectionFlip(false);
|
|
973
934
|
setSectionPosition(0.5);
|
|
974
|
-
setSectionCapColor("#9aa6b3");
|
|
975
935
|
};
|
|
976
936
|
const handleDefaultDownload = () => {
|
|
977
937
|
const a = document.createElement("a");
|
|
@@ -988,24 +948,24 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
988
948
|
/* @__PURE__ */ jsxs(
|
|
989
949
|
"div",
|
|
990
950
|
{
|
|
991
|
-
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",
|
|
992
952
|
style: { paddingLeft: `${depth * 12 + 6}px` },
|
|
993
953
|
children: [
|
|
994
954
|
hasChildren ? /* @__PURE__ */ jsx(
|
|
995
955
|
"button",
|
|
996
956
|
{
|
|
997
957
|
onClick: () => toggleExpanded(node.id),
|
|
998
|
-
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",
|
|
999
959
|
title: isExpanded ? "Collapse" : "Expand",
|
|
1000
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" }) })
|
|
1001
961
|
}
|
|
1002
|
-
) : /* @__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" }) }),
|
|
1003
963
|
/* @__PURE__ */ jsx("span", { className: `flex-1 truncate ${isVisible ? "" : "opacity-40"}`, title: node.name, children: node.name }),
|
|
1004
964
|
/* @__PURE__ */ jsx(
|
|
1005
965
|
"button",
|
|
1006
966
|
{
|
|
1007
967
|
onClick: () => fitNode(),
|
|
1008
|
-
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",
|
|
1009
969
|
title: "Fit to view",
|
|
1010
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" }) })
|
|
1011
971
|
}
|
|
@@ -1014,7 +974,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1014
974
|
"button",
|
|
1015
975
|
{
|
|
1016
976
|
onClick: () => toggleNodeVisible(node),
|
|
1017
|
-
className: "h-4 w-4 shrink-0 text-
|
|
977
|
+
className: "h-4 w-4 shrink-0 text-gray-500 hover:text-gray-900",
|
|
1018
978
|
title: isVisible ? "Hide" : "Show",
|
|
1019
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: [
|
|
1020
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" }),
|
|
@@ -1028,12 +988,12 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1028
988
|
isExpanded && hasChildren && /* @__PURE__ */ jsx("div", { children: node.children.map((c) => renderTreeNode(c, depth + 1)) })
|
|
1029
989
|
] }, node.id);
|
|
1030
990
|
};
|
|
1031
|
-
const tBtn = "h-8 w-8 shrink-0 flex items-center justify-center rounded text-
|
|
1032
|
-
const tBtnActive = "h-8 w-8 shrink-0 flex items-center justify-center rounded bg-
|
|
1033
|
-
const tBtnSep = "h-5 w-px bg-
|
|
1034
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full bg-
|
|
1035
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 py-1.5 bg-
|
|
1036
|
-
/* @__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 }),
|
|
1037
997
|
/* @__PURE__ */ jsx("div", { className: tBtnSep }),
|
|
1038
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" }) }) }),
|
|
1039
999
|
/* @__PURE__ */ jsx("div", { className: tBtnSep }),
|
|
@@ -1057,10 +1017,10 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1057
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" }) }) })
|
|
1058
1018
|
] }),
|
|
1059
1019
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex min-h-0", children: [
|
|
1060
|
-
showMeshes && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-
|
|
1061
|
-
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-
|
|
1062
|
-
/* @__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-
|
|
1063
|
-
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` })
|
|
1064
1024
|
] }),
|
|
1065
1025
|
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0", style: { background: bgColor }, children: [
|
|
1066
1026
|
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
@@ -1081,12 +1041,12 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1081
1041
|
] }),
|
|
1082
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 })
|
|
1083
1043
|
] }),
|
|
1084
|
-
showSettings && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 bg-
|
|
1085
|
-
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-
|
|
1086
|
-
/* @__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: [
|
|
1087
1047
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1088
1048
|
/* @__PURE__ */ jsx("span", { children: "Background Color" }),
|
|
1089
|
-
/* @__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" })
|
|
1090
1050
|
] }),
|
|
1091
1051
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1092
1052
|
/* @__PURE__ */ jsx("span", { children: "Show Edges" }),
|
|
@@ -1094,7 +1054,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1094
1054
|
"button",
|
|
1095
1055
|
{
|
|
1096
1056
|
onClick: () => setShowEdges((s) => !s),
|
|
1097
|
-
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"}`,
|
|
1098
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"}` })
|
|
1099
1059
|
}
|
|
1100
1060
|
)
|
|
@@ -1108,14 +1068,14 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1108
1068
|
value: edgeColor,
|
|
1109
1069
|
onChange: (e) => setEdgeColor(e.target.value),
|
|
1110
1070
|
disabled: !showEdges,
|
|
1111
|
-
className: "h-6 w-10 rounded border border-
|
|
1071
|
+
className: "h-6 w-10 rounded border border-gray-300 bg-white disabled:opacity-40"
|
|
1112
1072
|
}
|
|
1113
1073
|
)
|
|
1114
1074
|
] }),
|
|
1115
1075
|
/* @__PURE__ */ jsxs("div", { className: showEdges ? "" : "opacity-40 pointer-events-none", children: [
|
|
1116
1076
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [
|
|
1117
1077
|
/* @__PURE__ */ jsx("span", { children: "Edge Threshold" }),
|
|
1118
|
-
/* @__PURE__ */ jsxs("span", { className: "text-
|
|
1078
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-500 tabular-nums", children: [
|
|
1119
1079
|
edgeThreshold,
|
|
1120
1080
|
"\xB0"
|
|
1121
1081
|
] })
|
|
@@ -1133,14 +1093,14 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1133
1093
|
}
|
|
1134
1094
|
)
|
|
1135
1095
|
] }),
|
|
1136
|
-
/* @__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: [
|
|
1137
1097
|
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1138
1098
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Section View" }),
|
|
1139
1099
|
/* @__PURE__ */ jsx(
|
|
1140
1100
|
"button",
|
|
1141
1101
|
{
|
|
1142
1102
|
onClick: () => setSectionEnabled((s) => !s),
|
|
1143
|
-
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"}`,
|
|
1144
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"}` })
|
|
1145
1105
|
}
|
|
1146
1106
|
)
|
|
@@ -1153,7 +1113,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1153
1113
|
"button",
|
|
1154
1114
|
{
|
|
1155
1115
|
onClick: () => setSectionFlip((f) => !f),
|
|
1156
|
-
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",
|
|
1157
1117
|
title: "Flip section direction",
|
|
1158
1118
|
children: sectionFlip ? "\u2190 flipped" : "flip \u2192"
|
|
1159
1119
|
}
|
|
@@ -1163,7 +1123,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1163
1123
|
"button",
|
|
1164
1124
|
{
|
|
1165
1125
|
onClick: () => setSectionAxis(ax),
|
|
1166
|
-
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"}`,
|
|
1167
1127
|
children: ax.toUpperCase()
|
|
1168
1128
|
},
|
|
1169
1129
|
ax
|
|
@@ -1172,7 +1132,7 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1172
1132
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1173
1133
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [
|
|
1174
1134
|
/* @__PURE__ */ jsx("span", { children: "Position" }),
|
|
1175
|
-
/* @__PURE__ */ jsxs("span", { className: "text-
|
|
1135
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-500 tabular-nums", children: [
|
|
1176
1136
|
Math.round(sectionPosition * 100),
|
|
1177
1137
|
"%"
|
|
1178
1138
|
] })
|
|
@@ -1189,27 +1149,15 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
|
|
|
1189
1149
|
className: "w-full accent-blue-500"
|
|
1190
1150
|
}
|
|
1191
1151
|
)
|
|
1192
|
-
] }),
|
|
1193
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
|
|
1194
|
-
/* @__PURE__ */ jsx("span", { children: "Cap Color" }),
|
|
1195
|
-
/* @__PURE__ */ jsx(
|
|
1196
|
-
"input",
|
|
1197
|
-
{
|
|
1198
|
-
type: "color",
|
|
1199
|
-
value: sectionCapColor,
|
|
1200
|
-
onChange: (e) => setSectionCapColor(e.target.value),
|
|
1201
|
-
className: "h-6 w-10 rounded border border-slate-600 bg-transparent"
|
|
1202
|
-
}
|
|
1203
|
-
)
|
|
1204
1152
|
] })
|
|
1205
1153
|
] })
|
|
1206
1154
|
] })
|
|
1207
1155
|
] }),
|
|
1208
|
-
/* @__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(
|
|
1209
1157
|
"button",
|
|
1210
1158
|
{
|
|
1211
1159
|
onClick: handleResetDisplay,
|
|
1212
|
-
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",
|
|
1213
1161
|
children: "Reset to Default"
|
|
1214
1162
|
}
|
|
1215
1163
|
) })
|
|
@@ -1267,5 +1215,5 @@ function ImagePanel({ url, filename, onDownload, onEmail }) {
|
|
|
1267
1215
|
}
|
|
1268
1216
|
|
|
1269
1217
|
export { Preview, setPdfPreview };
|
|
1270
|
-
//# sourceMappingURL=chunk-
|
|
1271
|
-
//# sourceMappingURL=chunk-
|
|
1218
|
+
//# sourceMappingURL=chunk-MONP6MMC.js.map
|
|
1219
|
+
//# sourceMappingURL=chunk-MONP6MMC.js.map
|