@viamrobotics/motion-tools 0.6.2 → 0.7.0
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/components/App.svelte +5 -9
- package/dist/components/Details.svelte +4 -1
- package/dist/components/Details.svelte.d.ts +1 -1
- package/dist/components/DotSprite.svelte +44 -0
- package/dist/components/DotSprite.svelte.d.ts +9 -0
- package/dist/components/KeyboardControls.svelte +1 -1
- package/dist/components/MeasureTool.svelte +131 -0
- package/dist/components/MeasureTool.svelte.d.ts +3 -0
- package/dist/components/Scene.svelte +2 -0
- package/dist/components/Tree/TreeContainer.svelte +3 -0
- package/dist/components/Tree/TreeContainer.svelte.d.ts +1 -1
- package/dist/components/dashboard/Button.svelte +7 -2
- package/dist/components/dashboard/Button.svelte.d.ts +1 -1
- package/dist/components/dashboard/Dashboard.svelte +6 -1
- package/dist/components/dashboard/Dashboard.svelte.d.ts +4 -24
- package/dist/components/xr/XR.svelte +6 -4
- package/dist/components/xr/XR.svelte.d.ts +1 -1
- package/dist/hooks/useGeometries.svelte.js +3 -2
- package/dist/hooks/useObjectEvents.svelte.js +17 -3
- package/dist/hooks/useSettings.svelte.d.ts +1 -0
- package/dist/hooks/useSettings.svelte.js +1 -0
- package/dist/portal.d.ts +2 -0
- package/dist/portal.js +9 -0
- package/package.json +10 -10
- package/dist/components/DomPortal.svelte +0 -28
- package/dist/components/DomPortal.svelte.d.ts +0 -8
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
import TreeContainer from './Tree/TreeContainer.svelte'
|
|
6
6
|
import Details from './Details.svelte'
|
|
7
7
|
import SceneProviders from './SceneProviders.svelte'
|
|
8
|
-
import DomPortal from './DomPortal.svelte'
|
|
9
8
|
import XR from './xr/XR.svelte'
|
|
10
9
|
import { World } from '@threlte/rapier'
|
|
11
10
|
import { createPartIDContext } from '../hooks/usePartID.svelte'
|
|
12
11
|
import Dashboard from './dashboard/Dashboard.svelte'
|
|
12
|
+
import { domPortal } from '../portal'
|
|
13
13
|
|
|
14
14
|
interface Props {
|
|
15
15
|
partID?: string
|
|
@@ -35,17 +35,13 @@
|
|
|
35
35
|
{@render appChildren?.()}
|
|
36
36
|
</Scene>
|
|
37
37
|
|
|
38
|
-
<XR />
|
|
38
|
+
<XR {@attach domPortal(root)} />
|
|
39
39
|
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
<Details />
|
|
43
|
-
</DomPortal>
|
|
40
|
+
<Dashboard {@attach domPortal(root)} />
|
|
41
|
+
<Details {@attach domPortal(root)} />
|
|
44
42
|
|
|
45
43
|
{#if !focus}
|
|
46
|
-
<
|
|
47
|
-
<TreeContainer />
|
|
48
|
-
</DomPortal>
|
|
44
|
+
<TreeContainer {@attach domPortal(root)} />
|
|
49
45
|
{/if}
|
|
50
46
|
{/snippet}
|
|
51
47
|
</SceneProviders>
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
<script lang="ts">
|
|
14
14
|
import { Check, Copy } from 'lucide-svelte'
|
|
15
|
+
import { useTask } from '@threlte/core'
|
|
15
16
|
import { Button, Icon } from '@viamrobotics/prime-core'
|
|
16
17
|
import {
|
|
17
18
|
useSelectedObject,
|
|
@@ -21,7 +22,8 @@
|
|
|
21
22
|
useSelectedObject3d,
|
|
22
23
|
} from '../hooks/useSelection.svelte'
|
|
23
24
|
import { useDraggable } from '../hooks/useDraggable.svelte'
|
|
24
|
-
|
|
25
|
+
|
|
26
|
+
const { ...rest } = $props()
|
|
25
27
|
|
|
26
28
|
const focused = useFocused()
|
|
27
29
|
const focusedObject = useFocusedObject()
|
|
@@ -75,6 +77,7 @@
|
|
|
75
77
|
<div
|
|
76
78
|
class="border-medium bg-extralight absolute top-0 right-0 z-10 m-2 w-60 border p-2 text-xs"
|
|
77
79
|
style:transform="translate({draggable.current.x}px, {draggable.current.y}px)"
|
|
80
|
+
{...rest}
|
|
78
81
|
>
|
|
79
82
|
<div class="flex items-center justify-between gap-2 pb-2">
|
|
80
83
|
<div class="flex items-center gap-1">
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script
|
|
2
|
+
module
|
|
3
|
+
lang="ts"
|
|
4
|
+
>
|
|
5
|
+
import { T, type Props as ThrelteProps } from '@threlte/core'
|
|
6
|
+
import { CanvasTexture, type Sprite, type ColorRepresentation } from 'three'
|
|
7
|
+
|
|
8
|
+
const size = 128
|
|
9
|
+
const canvas = new OffscreenCanvas(size, size)
|
|
10
|
+
const ctx = canvas.getContext('2d')
|
|
11
|
+
|
|
12
|
+
if (ctx) {
|
|
13
|
+
ctx.clearRect(0, 0, size, size)
|
|
14
|
+
ctx.beginPath()
|
|
15
|
+
ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2)
|
|
16
|
+
ctx.fillStyle = 'white'
|
|
17
|
+
ctx.fill()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const map = new CanvasTexture(canvas)
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
interface Props extends ThrelteProps<typeof Sprite> {
|
|
25
|
+
color?: ColorRepresentation
|
|
26
|
+
opacity?: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { color, opacity = 1, ref = $bindable(), ...rest }: Props = $props()
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<T.Sprite
|
|
33
|
+
bind:ref
|
|
34
|
+
scale={0.05}
|
|
35
|
+
{...rest}
|
|
36
|
+
>
|
|
37
|
+
<T.SpriteMaterial
|
|
38
|
+
transparent
|
|
39
|
+
depthTest={false}
|
|
40
|
+
{map}
|
|
41
|
+
{opacity}
|
|
42
|
+
color={color ?? 'black'}
|
|
43
|
+
/>
|
|
44
|
+
</T.Sprite>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Props as ThrelteProps } from '@threlte/core';
|
|
2
|
+
import { type Sprite, type ColorRepresentation } from 'three';
|
|
3
|
+
interface Props extends ThrelteProps<typeof Sprite> {
|
|
4
|
+
color?: ColorRepresentation;
|
|
5
|
+
opacity?: number;
|
|
6
|
+
}
|
|
7
|
+
declare const DotSprite: import("svelte").Component<Props, {}, "ref">;
|
|
8
|
+
type DotSprite = ReturnType<typeof DotSprite>;
|
|
9
|
+
export default DotSprite;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte'
|
|
3
|
+
import { Raycaster, Vector2, Vector3, type Intersection } from 'three'
|
|
4
|
+
import { T, useThrelte, useTask } from '@threlte/core'
|
|
5
|
+
import { HTML, MeshLineGeometry, MeshLineMaterial, useInteractivity } from '@threlte/extras'
|
|
6
|
+
import { useSettings } from '../hooks/useSettings.svelte'
|
|
7
|
+
import Button from './dashboard/Button.svelte'
|
|
8
|
+
import Portal from './portal/Portal.svelte'
|
|
9
|
+
import DotSprite from './DotSprite.svelte'
|
|
10
|
+
|
|
11
|
+
const settings = useSettings()
|
|
12
|
+
const { camera } = useThrelte()
|
|
13
|
+
const interactivity = useInteractivity()
|
|
14
|
+
const raycaster = new Raycaster()
|
|
15
|
+
|
|
16
|
+
const htmlPosition = new Vector3()
|
|
17
|
+
const pointerDown = new Vector2()
|
|
18
|
+
const pointerUp = new Vector2()
|
|
19
|
+
|
|
20
|
+
let step: 'idle' | 'p1' | 'p2' = 'idle'
|
|
21
|
+
|
|
22
|
+
let intersection: Intersection | undefined
|
|
23
|
+
let p1 = $state.raw<Vector3>()
|
|
24
|
+
let p2 = $state.raw<Vector3>()
|
|
25
|
+
|
|
26
|
+
const enabled = $derived(settings.current.enableMeasure)
|
|
27
|
+
|
|
28
|
+
const onpointerdown = (event: PointerEvent) => {
|
|
29
|
+
pointerDown.set(event.clientX, event.clientY)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const onpointerup = (event: PointerEvent) => {
|
|
33
|
+
pointerUp.set(event.clientX, event.clientY)
|
|
34
|
+
|
|
35
|
+
if (pointerDown.distanceToSquared(pointerUp) > 0.1) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (step === 'idle' && intersection) {
|
|
40
|
+
p1 = intersection.point.clone()
|
|
41
|
+
step = 'p1'
|
|
42
|
+
} else if (step === 'p1' && intersection) {
|
|
43
|
+
p2 = intersection.point.clone()
|
|
44
|
+
step = 'p2'
|
|
45
|
+
} else if (step === 'p2') {
|
|
46
|
+
p1 = undefined
|
|
47
|
+
p2 = undefined
|
|
48
|
+
step = 'idle'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { start, stop } = useTask(
|
|
53
|
+
() => {
|
|
54
|
+
if (interactivity.hovered.size === 0) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const [, event] of interactivity.hovered) {
|
|
59
|
+
raycaster.setFromCamera(interactivity.pointer.current, camera.current)
|
|
60
|
+
intersection = raycaster.intersectObject(event.object)[0]
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{ autoStart: false }
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
$effect(() => {
|
|
67
|
+
if (!enabled) {
|
|
68
|
+
untrack(() => {
|
|
69
|
+
p1 = undefined
|
|
70
|
+
p2 = undefined
|
|
71
|
+
step = 'idle'
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
$effect(() => {
|
|
77
|
+
if (enabled) {
|
|
78
|
+
start()
|
|
79
|
+
} else {
|
|
80
|
+
stop()
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<Portal id="dashboard">
|
|
86
|
+
<fieldset>
|
|
87
|
+
<Button
|
|
88
|
+
active
|
|
89
|
+
icon="ruler"
|
|
90
|
+
class={enabled ? '' : 'text-gray-4!'}
|
|
91
|
+
description="{enabled ? 'Disable' : 'Enable'} measurement"
|
|
92
|
+
onclick={() => {
|
|
93
|
+
settings.current.enableMeasure = !settings.current.enableMeasure
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
</fieldset>
|
|
97
|
+
</Portal>
|
|
98
|
+
|
|
99
|
+
<svelte:window
|
|
100
|
+
onpointerdown={enabled ? onpointerdown : undefined}
|
|
101
|
+
onpointerup={enabled ? onpointerup : undefined}
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
{#if enabled}
|
|
105
|
+
{#if p1}
|
|
106
|
+
<DotSprite position={p1.toArray()} />
|
|
107
|
+
{/if}
|
|
108
|
+
|
|
109
|
+
{#if p2}
|
|
110
|
+
<DotSprite position={p2.toArray()} />
|
|
111
|
+
{/if}
|
|
112
|
+
|
|
113
|
+
{#if p1 && p2}
|
|
114
|
+
<T.Mesh>
|
|
115
|
+
<MeshLineGeometry points={[p1, p2]} />
|
|
116
|
+
<MeshLineMaterial
|
|
117
|
+
width={0.015}
|
|
118
|
+
depthTest={false}
|
|
119
|
+
color="black"
|
|
120
|
+
/>
|
|
121
|
+
</T.Mesh>
|
|
122
|
+
<HTML
|
|
123
|
+
center
|
|
124
|
+
position={htmlPosition.lerpVectors(p1, p2, 0.5).toArray()}
|
|
125
|
+
>
|
|
126
|
+
<div class="border border-black bg-white px-1 py-0.5 text-xs">
|
|
127
|
+
{p1.distanceTo(p2).toFixed(2)}m
|
|
128
|
+
</div>
|
|
129
|
+
</HTML>
|
|
130
|
+
{/if}
|
|
131
|
+
{/if}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { useOrigin } from './xr/useOrigin.svelte'
|
|
18
18
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
19
19
|
import CameraControls from './CameraControls.svelte'
|
|
20
|
+
import MeasureTool from './MeasureTool.svelte'
|
|
20
21
|
|
|
21
22
|
interface Props {
|
|
22
23
|
children?: Snippet
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
|
|
64
65
|
<PortalTarget id="world" />
|
|
65
66
|
|
|
67
|
+
<MeasureTool />
|
|
66
68
|
<StaticGeometries />
|
|
67
69
|
<Frames />
|
|
68
70
|
<Pointclouds />
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
import Logs from './Logs.svelte'
|
|
11
11
|
import { useDraggable } from '../../hooks/useDraggable.svelte'
|
|
12
12
|
|
|
13
|
+
const { ...rest } = $props()
|
|
14
|
+
|
|
13
15
|
provideTreeExpandedContext()
|
|
14
16
|
|
|
15
17
|
const selected = useSelected()
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
<div
|
|
36
38
|
class="bg-extralight border-medium absolute top-0 left-0 m-2 overflow-y-auto border text-xs"
|
|
37
39
|
style:transform="translate({draggable.current.x}px, {draggable.current.y}px)"
|
|
40
|
+
{...rest}
|
|
38
41
|
>
|
|
39
42
|
{#key rootNode}
|
|
40
43
|
<Tree
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Icon, type IconName, Tooltip } from '@viamrobotics/prime-core'
|
|
3
|
+
import { Ruler } from 'lucide-svelte'
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
|
-
icon: IconName
|
|
6
|
+
icon: IconName | 'ruler'
|
|
6
7
|
active?: boolean
|
|
7
8
|
description: string
|
|
8
9
|
hotkey?: string
|
|
@@ -39,7 +40,11 @@
|
|
|
39
40
|
aria-checked={active}
|
|
40
41
|
{onclick}
|
|
41
42
|
>
|
|
42
|
-
|
|
43
|
+
{#if icon === 'ruler'}
|
|
44
|
+
<Ruler size="16" />
|
|
45
|
+
{:else}
|
|
46
|
+
<Icon name={icon} />
|
|
47
|
+
{/if}
|
|
43
48
|
</button>
|
|
44
49
|
</label>
|
|
45
50
|
<p slot="description">
|
|
@@ -3,10 +3,15 @@
|
|
|
3
3
|
import PortalTarget from '../portal/PortalTarget.svelte'
|
|
4
4
|
import Button from './Button.svelte'
|
|
5
5
|
|
|
6
|
+
let { ...rest } = $props()
|
|
7
|
+
|
|
6
8
|
const settings = useSettings()
|
|
7
9
|
</script>
|
|
8
10
|
|
|
9
|
-
<div
|
|
11
|
+
<div
|
|
12
|
+
class="absolute top-2 flex w-full justify-center gap-2"
|
|
13
|
+
{...rest}
|
|
14
|
+
>
|
|
10
15
|
<!-- camera view -->
|
|
11
16
|
<fieldset class="flex">
|
|
12
17
|
<Button
|
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
export default Dashboard;
|
|
2
|
-
type Dashboard =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
}, {}> & {
|
|
7
|
-
$$bindings?: string | undefined;
|
|
2
|
+
type Dashboard = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<Record<string, any>>): void;
|
|
8
5
|
};
|
|
9
|
-
declare const Dashboard:
|
|
10
|
-
[x: string]: never;
|
|
11
|
-
}, {
|
|
12
|
-
[evt: string]: CustomEvent<any>;
|
|
13
|
-
}, {}, {}, string>;
|
|
14
|
-
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
-
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
-
$$bindings?: Bindings;
|
|
17
|
-
} & Exports;
|
|
18
|
-
(internal: unknown, props: {
|
|
19
|
-
$$events?: Events;
|
|
20
|
-
$$slots?: Slots;
|
|
21
|
-
}): Exports & {
|
|
22
|
-
$set?: any;
|
|
23
|
-
$on?: any;
|
|
24
|
-
};
|
|
25
|
-
z_$$bindings?: Bindings;
|
|
26
|
-
}
|
|
6
|
+
declare const Dashboard: import("svelte").Component<Record<string, any>, {}, "">;
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import { T } from '@threlte/core'
|
|
3
3
|
import { useXR, XR, XRButton } from '@threlte/xr'
|
|
4
4
|
import OriginMarker from './OriginMarker.svelte'
|
|
5
|
-
import DomPortal from '../DomPortal.svelte'
|
|
6
5
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
7
6
|
import Controllers from './Controllers.svelte'
|
|
8
7
|
|
|
8
|
+
const { ...rest } = $props()
|
|
9
|
+
|
|
9
10
|
const { isPresenting } = useXR()
|
|
10
11
|
const settings = useSettings()
|
|
11
12
|
const enableXR = $derived(settings.current.enableXR)
|
|
@@ -20,7 +21,8 @@
|
|
|
20
21
|
<Controllers />
|
|
21
22
|
</XR>
|
|
22
23
|
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
<XRButton
|
|
25
|
+
mode="immersive-ar"
|
|
26
|
+
{...rest}
|
|
27
|
+
/>
|
|
26
28
|
{/if}
|
|
@@ -48,9 +48,10 @@ export const provideGeometries = (partID) => {
|
|
|
48
48
|
continue;
|
|
49
49
|
for (const { center, label, geometryType } of query.data.geometries) {
|
|
50
50
|
const resourceName = resourceNames.current.find((item) => item.name === query.data.name);
|
|
51
|
-
|
|
51
|
+
const worldObject = new WorldObject(label ? label : 'Unnamed geometry', center, query.data.name, geometryType, resourceName
|
|
52
52
|
? { color: resourceColors[resourceName.subtype] }
|
|
53
|
-
: undefined)
|
|
53
|
+
: undefined);
|
|
54
|
+
results.push(worldObject);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
updateUUIDs(results);
|
|
@@ -2,26 +2,34 @@ import { useCursor } from '@threlte/extras';
|
|
|
2
2
|
import { useFocused, useSelected } from './useSelection.svelte';
|
|
3
3
|
import { useVisibility } from './useVisibility.svelte';
|
|
4
4
|
import { Vector2 } from 'three';
|
|
5
|
+
import { useSettings } from './useSettings.svelte';
|
|
5
6
|
export const useObjectEvents = (uuid) => {
|
|
6
|
-
const
|
|
7
|
+
const settings = useSettings();
|
|
7
8
|
const selected = useSelected();
|
|
8
9
|
const focused = useFocused();
|
|
9
10
|
const visibility = useVisibility();
|
|
10
11
|
const down = new Vector2();
|
|
12
|
+
const measureCursor = useCursor('crosshair');
|
|
13
|
+
const hoverCursor = useCursor();
|
|
14
|
+
const measuring = $derived(settings.current.enableMeasure);
|
|
15
|
+
const cursor = $derived(measuring ? measureCursor : hoverCursor);
|
|
11
16
|
return {
|
|
12
17
|
get visible() {
|
|
13
18
|
return visibility.get(uuid());
|
|
14
19
|
},
|
|
15
20
|
onpointerenter: (event) => {
|
|
16
21
|
event.stopPropagation();
|
|
17
|
-
onPointerEnter();
|
|
22
|
+
cursor.onPointerEnter();
|
|
18
23
|
},
|
|
19
24
|
onpointerleave: (event) => {
|
|
20
25
|
event.stopPropagation();
|
|
21
|
-
onPointerLeave();
|
|
26
|
+
cursor.onPointerLeave();
|
|
22
27
|
},
|
|
23
28
|
ondblclick: (event) => {
|
|
24
29
|
event.stopPropagation();
|
|
30
|
+
if (measuring) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
25
33
|
focused.set(uuid());
|
|
26
34
|
},
|
|
27
35
|
onpointerdown: (event) => {
|
|
@@ -29,11 +37,17 @@ export const useObjectEvents = (uuid) => {
|
|
|
29
37
|
},
|
|
30
38
|
onclick: (event) => {
|
|
31
39
|
event.stopPropagation();
|
|
40
|
+
if (measuring) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
32
43
|
if (down.distanceToSquared(event.pointer) < 0.1) {
|
|
33
44
|
selected.set(uuid());
|
|
34
45
|
}
|
|
35
46
|
},
|
|
36
47
|
onpointermissed: () => {
|
|
48
|
+
if (measuring) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
37
51
|
selected.set();
|
|
38
52
|
},
|
|
39
53
|
};
|
package/dist/portal.d.ts
ADDED
package/dist/portal.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/motion-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Motion visualization with Viam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"@threlte/extras": "9.4.2",
|
|
31
31
|
"@threlte/rapier": "3.1.4",
|
|
32
32
|
"@threlte/xr": "1.0.8",
|
|
33
|
-
"@types/bun": "1.2.
|
|
33
|
+
"@types/bun": "1.2.19",
|
|
34
34
|
"@types/lodash-es": "4.17.12",
|
|
35
35
|
"@types/three": "0.178.1",
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
37
|
-
"@typescript-eslint/parser": "8.
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "8.38.0",
|
|
37
|
+
"@typescript-eslint/parser": "8.38.0",
|
|
38
38
|
"@viamrobotics/prime-core": "0.1.5",
|
|
39
39
|
"@viamrobotics/sdk": "0.46.0",
|
|
40
|
-
"@viamrobotics/svelte-sdk": "0.4.
|
|
40
|
+
"@viamrobotics/svelte-sdk": "0.4.3",
|
|
41
41
|
"@vitejs/plugin-basic-ssl": "2.1.0",
|
|
42
|
-
"@zag-js/svelte": "1.
|
|
43
|
-
"@zag-js/tree-view": "1.
|
|
42
|
+
"@zag-js/svelte": "1.19.0",
|
|
43
|
+
"@zag-js/tree-view": "1.19.0",
|
|
44
44
|
"camera-controls": "3.1.0",
|
|
45
45
|
"eslint": "9.31.0",
|
|
46
|
-
"eslint-config-prettier": "10.1.
|
|
46
|
+
"eslint-config-prettier": "10.1.8",
|
|
47
47
|
"eslint-plugin-svelte": "3.10.1",
|
|
48
48
|
"globals": "16.3.0",
|
|
49
49
|
"idb-keyval": "6.2.2",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"prettier-plugin-tailwindcss": "0.6.14",
|
|
56
56
|
"publint": "0.3.12",
|
|
57
57
|
"runed": "0.31.0",
|
|
58
|
-
"svelte": "5.36.
|
|
58
|
+
"svelte": "5.36.13",
|
|
59
59
|
"svelte-check": "4.3.0",
|
|
60
60
|
"svelte-virtuallists": "1.4.2",
|
|
61
61
|
"tailwindcss": "4.1.11",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"threlte-uikit": "1.2.0",
|
|
64
64
|
"tsx": "4.20.3",
|
|
65
65
|
"typescript": "5.8.3",
|
|
66
|
-
"typescript-eslint": "8.
|
|
66
|
+
"typescript-eslint": "8.38.0",
|
|
67
67
|
"vite": "6.3.5",
|
|
68
68
|
"vite-plugin-devtools-json": "0.3.0",
|
|
69
69
|
"vite-plugin-mkcert": "1.17.8",
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte'
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
element?: HTMLElement
|
|
6
|
-
children: Snippet
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { children, element }: Props = $props()
|
|
10
|
-
|
|
11
|
-
let div: HTMLDivElement
|
|
12
|
-
|
|
13
|
-
$effect(() => {
|
|
14
|
-
const parent = element ?? document.body
|
|
15
|
-
parent.append(div)
|
|
16
|
-
return () => {
|
|
17
|
-
// eslint-disable-next-line svelte/no-dom-manipulating
|
|
18
|
-
div.remove()
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<div
|
|
24
|
-
style="display: contents"
|
|
25
|
-
bind:this={div}
|
|
26
|
-
>
|
|
27
|
-
{@render children()}
|
|
28
|
-
</div>
|