@viamrobotics/motion-tools 0.5.5 → 0.6.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/color.d.ts CHANGED
@@ -7,18 +7,23 @@ import { Color, type ColorRepresentation } from 'three';
7
7
  */
8
8
  export declare const darkenColor: (value: ColorRepresentation, percent: number) => Color;
9
9
  export declare const colors: {
10
- readonly selected: string;
11
10
  readonly default: string;
12
- readonly arm: {
13
- readonly selected: string;
14
- readonly default: string;
15
- };
16
- readonly camera: {
17
- readonly selected: string;
18
- readonly default: string;
19
- };
20
- readonly gripper: {
21
- readonly selected: string;
22
- readonly default: string;
23
- };
11
+ };
12
+ export declare const resourceColors: {
13
+ readonly arm: string;
14
+ readonly camera: string;
15
+ readonly base: string;
16
+ readonly board: string;
17
+ readonly button: string;
18
+ readonly encoder: string;
19
+ readonly gantry: string;
20
+ readonly gripper: string;
21
+ readonly motor: string;
22
+ readonly movement_sensor: string;
23
+ readonly pose_tracker: string;
24
+ readonly power_sensor: string;
25
+ readonly sensor: string;
26
+ readonly servo: string;
27
+ readonly switch: string;
28
+ readonly webcam: string;
24
29
  };
package/dist/color.js CHANGED
@@ -51,19 +51,25 @@ export const darkenColor = (value, percent) => {
51
51
  hsl.l = Math.max(0, hsl.l * (1 - percent / 100));
52
52
  return new Color().setHSL(hsl.h, hsl.s, hsl.l);
53
53
  };
54
+ const darkness = '600';
54
55
  export const colors = {
55
- selected: oklchToHex(twColors.red['900']),
56
- default: oklchToHex(twColors.red['500']),
57
- arm: {
58
- selected: oklchToHex(twColors.amber['900']),
59
- default: oklchToHex(twColors.amber['500']),
60
- },
61
- camera: {
62
- selected: oklchToHex(twColors.blue['900']),
63
- default: oklchToHex(twColors.blue['500']),
64
- },
65
- gripper: {
66
- selected: oklchToHex(twColors.cyan['900']),
67
- default: oklchToHex(twColors.cyan['500']),
68
- },
56
+ default: oklchToHex(twColors.red[darkness]),
57
+ };
58
+ export const resourceColors = {
59
+ arm: oklchToHex(twColors.amber[darkness]),
60
+ camera: oklchToHex(twColors.blue[darkness]),
61
+ base: oklchToHex(twColors.slate[darkness]),
62
+ board: oklchToHex(twColors.emerald[darkness]),
63
+ button: oklchToHex(twColors.gray[darkness]),
64
+ encoder: oklchToHex(twColors.lime[darkness]),
65
+ gantry: oklchToHex(twColors.purple[darkness]),
66
+ gripper: oklchToHex(twColors.cyan[darkness]),
67
+ motor: oklchToHex(twColors.orange[darkness]),
68
+ movement_sensor: oklchToHex(twColors.indigo[darkness]),
69
+ pose_tracker: oklchToHex(twColors.rose[darkness]),
70
+ power_sensor: oklchToHex(twColors.violet[darkness]),
71
+ sensor: oklchToHex(twColors.teal[darkness]),
72
+ servo: oklchToHex(twColors.yellow[darkness]),
73
+ switch: oklchToHex(twColors.stone[darkness]),
74
+ webcam: oklchToHex(twColors.sky[darkness]),
69
75
  };
@@ -1,5 +1,16 @@
1
- <script lang="ts">
1
+ <script
2
+ module
3
+ lang="ts"
4
+ >
5
+ import { OrientationVector } from '../three/OrientationVector'
2
6
  import { Quaternion, Vector3 } from 'three'
7
+
8
+ const vec3 = new Vector3()
9
+ const quaternion = new Quaternion()
10
+ const ov = new OrientationVector()
11
+ </script>
12
+
13
+ <script lang="ts">
3
14
  import { Check, Copy } from 'lucide-svelte'
4
15
  import { Button, Icon } from '@viamrobotics/prime-core'
5
16
  import {
@@ -10,7 +21,7 @@
10
21
  useSelectedObject3d,
11
22
  } from '../hooks/useSelection.svelte'
12
23
  import { useDraggable } from '../hooks/useDraggable.svelte'
13
- import { OrientationVector } from '../three/OrientationVector'
24
+ import { useTask } from '@threlte/core'
14
25
 
15
26
  const focused = useFocused()
16
27
  const focusedObject = useFocusedObject()
@@ -21,15 +32,42 @@
21
32
 
22
33
  const object = $derived(focusedObject.current ?? selectedObject.current)
23
34
  const object3d = $derived(focusedObject3d.current ?? selectedObject3d.current)
24
- const worldPosition = $derived(object3d?.getWorldPosition(new Vector3()))
25
- const worldQuaternion = $derived(object3d?.getWorldQuaternion(new Quaternion()))
26
- const worldOrientation = $derived(
27
- worldQuaternion ? new OrientationVector().setFromQuaternion(worldQuaternion) : undefined
28
- )
35
+ const worldPosition = $state({ x: 0, y: 0, z: 0 })
36
+ const worldOrientation = $state({ x: 0, y: 0, z: 1, th: 0 })
29
37
 
30
38
  let copied = $state(false)
31
39
 
32
40
  const draggable = useDraggable('details')
41
+
42
+ const { start, stop } = useTask(
43
+ () => {
44
+ object3d?.getWorldPosition(vec3)
45
+ if (!vec3.equals(worldPosition)) {
46
+ worldPosition.x = vec3.x
47
+ worldPosition.y = vec3.y
48
+ worldPosition.z = vec3.z
49
+ }
50
+
51
+ object3d?.getWorldQuaternion(quaternion)
52
+ ov.setFromQuaternion(quaternion)
53
+
54
+ if (!ov.equals(worldOrientation)) {
55
+ worldOrientation.x = ov.x
56
+ worldOrientation.y = ov.y
57
+ worldOrientation.z = ov.z
58
+ worldOrientation.th = ov.th
59
+ }
60
+ },
61
+ { autoStart: false }
62
+ )
63
+
64
+ $effect.pre(() => {
65
+ if (object3d) {
66
+ start()
67
+ } else {
68
+ stop()
69
+ }
70
+ })
33
71
  </script>
34
72
 
35
73
  {#if object}
@@ -1,12 +1,14 @@
1
1
  <script lang="ts">
2
2
  import { T } from '@threlte/core'
3
3
  import { TrackballControls, Gizmo } from '@threlte/extras'
4
- import { useFocusedObject3d } from '../hooks/useSelection.svelte'
5
- import { Box3, Vector3 } from 'three'
4
+ import { Box3, type Object3D, Vector3 } from 'three'
6
5
  import Camera from './Camera.svelte'
7
6
 
8
- const focusedObject = useFocusedObject3d()
9
- const object3d = $derived(focusedObject.current)
7
+ interface Props {
8
+ object3d: Object3D
9
+ }
10
+
11
+ let { object3d }: Props = $props()
10
12
 
11
13
  const box = new Box3()
12
14
  const vec = new Vector3()
@@ -14,22 +16,18 @@
14
16
  let center = $state.raw<[number, number, number]>([0, 0, 0])
15
17
  let size = $state.raw<[number, number, number]>([0, 0, 0])
16
18
 
17
- $effect(() => {
18
- if (object3d) {
19
- box.setFromObject(object3d)
20
- size = box.getSize(vec).toArray()
21
- center = box.getCenter(vec).toArray()
22
- }
19
+ $effect.pre(() => {
20
+ box.setFromObject(object3d)
21
+ size = box.getSize(vec).toArray()
22
+ center = box.getCenter(vec).toArray()
23
23
  })
24
24
  </script>
25
25
 
26
- <Camera position={[size[0], 0, 0]}>
26
+ <Camera position={[0, 0, size[0] + 1]}>
27
27
  <TrackballControls target={center}>
28
28
  <Gizmo />
29
29
  </TrackballControls>
30
30
  </Camera>
31
31
 
32
- {#if object3d}
33
- <T is={object3d} />
34
- <T.BoxHelper args={[object3d, 'red']} />
35
- {/if}
32
+ <T is={object3d} />
33
+ <T.BoxHelper args={[object3d, 'red']} />
@@ -1,3 +1,7 @@
1
- declare const Focus: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import { type Object3D } from 'three';
2
+ interface Props {
3
+ object3d: Object3D;
4
+ }
5
+ declare const Focus: import("svelte").Component<Props, {}, "">;
2
6
  type Focus = ReturnType<typeof Focus>;
3
7
  export default Focus;
@@ -1,6 +1,11 @@
1
+ <script module>
2
+ import { Color, type Object3D } from 'three'
3
+
4
+ const colorUtil = new Color()
5
+ </script>
6
+
1
7
  <script lang="ts">
2
8
  import type { Snippet } from 'svelte'
3
- import type { Object3D } from 'three'
4
9
  import type { WorldObject } from '../WorldObject'
5
10
  import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
6
11
  import Geometry from './Geometry.svelte'
@@ -20,13 +25,15 @@
20
25
 
21
26
  const selected = useSelected()
22
27
  const events = useObjectEvents(() => uuid)
28
+
29
+ const color = $derived(rest.metadata.color ?? colors.default)
23
30
  </script>
24
31
 
25
32
  <Geometry
26
33
  {uuid}
27
34
  color={selected.current === uuid
28
- ? `#${darkenColor(rest.metadata.color ?? colors.default, 75).getHexString()}`
29
- : undefined}
35
+ ? `#${darkenColor(color, 75).getHexString()}`
36
+ : `#${colorUtil.set(color).getHexString()}`}
30
37
  {...events}
31
38
  {...rest}
32
39
  />
@@ -1,5 +1,5 @@
1
+ import { type Object3D } from 'three';
1
2
  import type { Snippet } from 'svelte';
2
- import type { Object3D } from 'three';
3
3
  import type { WorldObject } from '../WorldObject';
4
4
  interface Props {
5
5
  uuid: string;
@@ -48,7 +48,7 @@
48
48
  poseToObject3d(pose, mesh)
49
49
  })
50
50
 
51
- let geo = $state<BufferGeometry>()
51
+ let geo = $state.raw<BufferGeometry>()
52
52
 
53
53
  const oncreate = (ref: BufferGeometry) => {
54
54
  geo = ref
@@ -16,7 +16,7 @@
16
16
  import StaticGeometries from './StaticGeometries.svelte'
17
17
  import Shapes from './Shapes.svelte'
18
18
  import Camera from './Camera.svelte'
19
- import { useFocused } from '../hooks/useSelection.svelte'
19
+ import { useFocusedObject3d } from '../hooks/useSelection.svelte'
20
20
  import type { Snippet } from 'svelte'
21
21
  import { useXR } from '@threlte/xr'
22
22
  import { useTransformControls } from '../hooks/useControls.svelte'
@@ -39,10 +39,12 @@
39
39
  },
40
40
  })
41
41
 
42
- const focused = useFocused()
42
+ const focusedObject3d = useFocusedObject3d()
43
43
  const transformControls = useTransformControls()
44
44
  const origin = useOrigin()
45
45
 
46
+ const object3d = $derived(focusedObject3d.current)
47
+
46
48
  const { isPresenting } = useXR()
47
49
  </script>
48
50
 
@@ -56,7 +58,9 @@
56
58
  rotation.x={$isPresenting ? -Math.PI / 2 : 0}
57
59
  rotation.z={origin.rotation}
58
60
  >
59
- {#if focused.current === undefined}
61
+ {#if object3d}
62
+ <Focus {object3d} />
63
+ {:else}
60
64
  {#if !$isPresenting}
61
65
  <Camera position={[3, 3, 3]}>
62
66
  <CameraControls enabled={!transformControls.active}>
@@ -88,8 +92,6 @@
88
92
  fadeDistance={25}
89
93
  />
90
94
  {/if}
91
- {:else}
92
- <Focus />
93
95
  {/if}
94
96
 
95
97
  {@render children?.()}
@@ -39,7 +39,9 @@
39
39
  <TransformControls
40
40
  object={ref}
41
41
  {mode}
42
- onmouseDown={() => transformControls.setActive(true)}
42
+ onmouseDown={() => {
43
+ transformControls.setActive(true)
44
+ }}
43
45
  onmouseUp={() => {
44
46
  transformControls.setActive(false)
45
47
 
@@ -1,11 +1,13 @@
1
1
  import { getContext, setContext, untrack } from 'svelte';
2
- import { useRobotClient, createRobotQuery, useMachineStatus } from '@viamrobotics/svelte-sdk';
2
+ import { useRobotClient, createRobotQuery, useMachineStatus, useResourceNames, } from '@viamrobotics/svelte-sdk';
3
3
  import { WorldObject } from '../WorldObject';
4
4
  import { useRefreshRates } from './useRefreshRates.svelte';
5
5
  import { observe } from '@threlte/core';
6
6
  import { useLogs } from './useLogs.svelte';
7
+ import { resourceColors } from '../color';
7
8
  const key = Symbol('frames-context');
8
9
  export const provideFrames = (partID) => {
10
+ const resourceNames = useResourceNames(partID);
9
11
  const client = useRobotClient(partID);
10
12
  const machineStatus = useMachineStatus(partID);
11
13
  const logs = useLogs();
@@ -28,9 +30,15 @@ export const provideFrames = (partID) => {
28
30
  return objects;
29
31
  }
30
32
  for (const { frame } of query.current.data ?? []) {
31
- if (frame) {
32
- objects.push(new WorldObject(frame.referenceFrame ? frame.referenceFrame : 'Unnamed frame', frame.poseInObserverFrame?.pose, frame.poseInObserverFrame?.referenceFrame, frame.physicalObject?.geometryType));
33
+ if (frame === undefined) {
34
+ continue;
33
35
  }
36
+ const resourceName = resourceNames.current.find((item) => item.name === frame.referenceFrame);
37
+ objects.push(new WorldObject(frame.referenceFrame ? frame.referenceFrame : 'Unnamed frame', frame.poseInObserverFrame?.pose, frame.poseInObserverFrame?.referenceFrame, frame.physicalObject?.geometryType, resourceName
38
+ ? {
39
+ color: resourceColors[resourceName.subtype],
40
+ }
41
+ : undefined));
34
42
  }
35
43
  return objects;
36
44
  });
@@ -7,13 +7,15 @@ import { useRefreshRates } from './useRefreshRates.svelte';
7
7
  import { WorldObject } from '../WorldObject';
8
8
  import { usePersistentUUIDs } from './usePersistentUUIDs.svelte';
9
9
  import { useLogs } from './useLogs.svelte';
10
+ import { resourceColors } from '../color';
10
11
  const key = Symbol('geometries-context');
11
12
  export const provideGeometries = (partID) => {
12
- const logs = useLogs();
13
- const refreshRates = useRefreshRates();
13
+ const resourceNames = useResourceNames(partID);
14
14
  const arms = useResourceNames(partID, 'arm');
15
15
  const cameras = useResourceNames(partID, 'camera');
16
16
  const grippers = useResourceNames(partID, 'gripper');
17
+ const logs = useLogs();
18
+ const refreshRates = useRefreshRates();
17
19
  const armClients = $derived(arms.current.map((arm) => createResourceClient(ArmClient, partID, () => arm.name)));
18
20
  const gripperClients = $derived(grippers.current.map((gripper) => createResourceClient(GripperClient, partID, () => gripper.name)));
19
21
  const cameraClients = $derived(cameras.current.map((camera) => createResourceClient(CameraClient, partID, () => camera.name)));
@@ -45,7 +47,10 @@ export const provideGeometries = (partID) => {
45
47
  if (!query.data)
46
48
  continue;
47
49
  for (const { center, label, geometryType } of query.data.geometries) {
48
- results.push(new WorldObject(label ? label : 'Unnamed geometry', center, query.data.name, geometryType));
50
+ const resourceName = resourceNames.current.find((item) => item.name === query.data.name);
51
+ results.push(new WorldObject(label ? label : 'Unnamed geometry', center, query.data.name, geometryType, resourceName
52
+ ? { color: resourceColors[resourceName.subtype] }
53
+ : undefined));
49
54
  }
50
55
  }
51
56
  updateUUIDs(results);
@@ -33,6 +33,8 @@ export const useObjectEvents = (uuid) => {
33
33
  selected.set(uuid());
34
34
  }
35
35
  },
36
- onpointermissed: () => selected.set(),
36
+ onpointermissed: () => {
37
+ selected.set();
38
+ },
37
39
  };
38
40
  };
@@ -7,6 +7,7 @@ const selectionKey = Symbol('selection-context');
7
7
  const focusKey = Symbol('focus-context');
8
8
  const selectedObjectKey = Symbol('selected-frame-context');
9
9
  const focusedObjectKey = Symbol('focused-frame-context');
10
+ const focusedObject3dKey = Symbol('focused-object-3d-context');
10
11
  export const provideSelection = () => {
11
12
  let selected = $state();
12
13
  let focused = $state();
@@ -46,13 +47,21 @@ export const provideSelection = () => {
46
47
  },
47
48
  };
48
49
  setContext(selectedObjectKey, selectedObjectContext);
49
- const focusedFrame = $derived(objects.current.find((object) => object.uuid === focused));
50
- const focusedFrameContext = {
50
+ const focusedObject = $derived(objects.current.find((object) => object.uuid === focused));
51
+ const focusedObjectContext = {
51
52
  get current() {
52
- return focusedFrame;
53
+ return focusedObject;
53
54
  },
54
55
  };
55
- setContext(focusedObjectKey, focusedFrameContext);
56
+ setContext(focusedObjectKey, focusedObjectContext);
57
+ const { scene } = useThrelte();
58
+ const uuid = $derived(focusedObject?.uuid);
59
+ const focusedObject3d = $derived(uuid ? scene.getObjectByProperty('uuid', uuid)?.clone() : undefined);
60
+ setContext(focusedObject3dKey, {
61
+ get current() {
62
+ return focusedObject3d;
63
+ },
64
+ });
56
65
  return {
57
66
  selection: selectionContext,
58
67
  focus: focusContext,
@@ -72,16 +81,7 @@ export const useSelectedObject = () => {
72
81
  return getContext(selectedObjectKey);
73
82
  };
74
83
  export const useFocusedObject3d = () => {
75
- const focusedObject = useFocusedObject();
76
- const { scene } = useThrelte();
77
- const object = $derived(focusedObject.current
78
- ? scene.getObjectByProperty('uuid', focusedObject.current.uuid)?.clone()
79
- : undefined);
80
- return {
81
- get current() {
82
- return object;
83
- },
84
- };
84
+ return getContext(focusedObject3dKey);
85
85
  };
86
86
  const matrix = new Matrix4();
87
87
  export const useSelectedObject3d = () => {
@@ -1,5 +1,11 @@
1
1
  import { Euler, Quaternion } from 'three';
2
2
  export declare const EPSILON = 0.0001;
3
+ type OrientationVectorLike = OrientationVector | {
4
+ x: number;
5
+ y: number;
6
+ z: number;
7
+ th: number;
8
+ };
3
9
  /**
4
10
  * Golang: https://github.com/viamrobotics/rdk/blob/main/spatialmath/orientationVector.go
5
11
  * Rust: https://github.com/viamrobotics/rust-utils/blob/main/src/spatialmath/utils.rs
@@ -62,6 +68,7 @@ export declare class OrientationVector {
62
68
  * Copies value of ov to this orientation vector.
63
69
  */
64
70
  copy(ov: OrientationVector): this;
71
+ equals(orientationVector: OrientationVectorLike): boolean;
65
72
  fromArray(array: number[], offset?: number): this;
66
73
  toArray(array?: number[], offset?: number): number[];
67
74
  toJson(): number[];
@@ -69,3 +76,4 @@ export declare class OrientationVector {
69
76
  toQuaternion(dest: Quaternion): Quaternion;
70
77
  toEuler(dest: Euler): Euler;
71
78
  }
79
+ export {};
@@ -151,6 +151,12 @@ export class OrientationVector {
151
151
  this.#onChangeCallback?.();
152
152
  return this;
153
153
  }
154
+ equals(orientationVector) {
155
+ return (this.x === orientationVector.x &&
156
+ this.y === orientationVector.y &&
157
+ this.z === orientationVector.z &&
158
+ this.th === orientationVector.th);
159
+ }
154
160
  fromArray(array, offset = 0) {
155
161
  this.#vec.set(array[offset] ?? 0, array[offset + 1] ?? 0, array[offset + 2] ?? 0);
156
162
  this.th = array[offset + 3] ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viamrobotics/motion-tools",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
4
4
  "description": "Motion visualization with Viam",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,38 +11,38 @@
11
11
  "@changesets/cli": "2.29.5",
12
12
  "@dimforge/rapier3d-compat": "0.17.3",
13
13
  "@eslint/compat": "1.3.1",
14
- "@eslint/js": "9.30.1",
15
- "@playwright/test": "1.53.2",
16
- "@sentry/sveltekit": "9.34.0",
17
- "@skeletonlabs/skeleton": "3.1.3",
18
- "@skeletonlabs/skeleton-svelte": "1.2.3",
14
+ "@eslint/js": "9.31.0",
15
+ "@playwright/test": "1.54.1",
16
+ "@sentry/sveltekit": "9.39.0",
17
+ "@skeletonlabs/skeleton": "3.1.7",
18
+ "@skeletonlabs/skeleton-svelte": "1.3.0",
19
19
  "@sveltejs/adapter-static": "3.0.8",
20
- "@sveltejs/kit": "2.22.2",
21
- "@sveltejs/package": "2.3.12",
22
- "@sveltejs/vite-plugin-svelte": "5.1.0",
20
+ "@sveltejs/kit": "2.24.0",
21
+ "@sveltejs/package": "2.4.0",
22
+ "@sveltejs/vite-plugin-svelte": "6.1.0",
23
23
  "@tailwindcss/forms": "0.5.10",
24
24
  "@tailwindcss/vite": "4.1.11",
25
- "@tanstack/svelte-query": "5.81.5",
26
- "@tanstack/svelte-query-devtools": "5.81.5",
25
+ "@tanstack/svelte-query": "5.83.0",
26
+ "@tanstack/svelte-query-devtools": "5.83.0",
27
27
  "@testing-library/jest-dom": "6.6.3",
28
28
  "@testing-library/svelte": "5.2.8",
29
- "@threlte/core": "8.0.5",
30
- "@threlte/extras": "9.4.0",
29
+ "@threlte/core": "8.1.3",
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.17",
33
+ "@types/bun": "1.2.18",
34
34
  "@types/lodash-es": "4.17.12",
35
- "@types/three": "0.178.0",
36
- "@typescript-eslint/eslint-plugin": "8.35.1",
37
- "@typescript-eslint/parser": "8.35.1",
35
+ "@types/three": "0.178.1",
36
+ "@typescript-eslint/eslint-plugin": "8.37.0",
37
+ "@typescript-eslint/parser": "8.37.0",
38
38
  "@viamrobotics/prime-core": "0.1.5",
39
- "@viamrobotics/sdk": "0.45.0",
40
- "@viamrobotics/svelte-sdk": "0.4.1",
39
+ "@viamrobotics/sdk": "0.46.0",
40
+ "@viamrobotics/svelte-sdk": "0.4.3",
41
41
  "@vitejs/plugin-basic-ssl": "2.1.0",
42
- "@zag-js/svelte": "1.18.1",
43
- "@zag-js/tree-view": "1.18.1",
44
- "camera-controls": "2.10.1",
45
- "eslint": "9.30.1",
42
+ "@zag-js/svelte": "1.18.3",
43
+ "@zag-js/tree-view": "1.18.3",
44
+ "camera-controls": "3.1.0",
45
+ "eslint": "9.31.0",
46
46
  "eslint-config-prettier": "10.1.5",
47
47
  "eslint-plugin-svelte": "3.10.1",
48
48
  "globals": "16.3.0",
@@ -52,10 +52,10 @@
52
52
  "lucide-svelte": "0.525.0",
53
53
  "prettier": "3.6.2",
54
54
  "prettier-plugin-svelte": "3.4.0",
55
- "prettier-plugin-tailwindcss": "0.6.13",
55
+ "prettier-plugin-tailwindcss": "0.6.14",
56
56
  "publint": "0.3.12",
57
- "runed": "0.29.1",
58
- "svelte": "5.34.8",
57
+ "runed": "0.31.0",
58
+ "svelte": "5.36.1",
59
59
  "svelte-check": "4.2.2",
60
60
  "svelte-virtuallists": "1.4.2",
61
61
  "tailwindcss": "4.1.11",
@@ -63,9 +63,9 @@
63
63
  "threlte-uikit": "1.2.0",
64
64
  "tsx": "4.20.3",
65
65
  "typescript": "5.8.3",
66
- "typescript-eslint": "8.35.1",
66
+ "typescript-eslint": "8.37.0",
67
67
  "vite": "6.3.5",
68
- "vite-plugin-devtools-json": "0.2.1",
68
+ "vite-plugin-devtools-json": "0.3.0",
69
69
  "vite-plugin-mkcert": "1.17.8",
70
70
  "vitest": "3.2.4"
71
71
  },