@viamrobotics/test-widgets 0.11.0 → 0.11.2
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/widgets/arm/arm.svelte +67 -65
- package/dist/components/widgets/base/base.svelte +39 -37
- package/dist/components/widgets/base/move-straight.svelte +1 -1
- package/dist/components/widgets/base/set-power.svelte +1 -1
- package/dist/components/widgets/base/set-velocity.svelte +1 -1
- package/dist/components/widgets/base/spin.svelte +1 -1
- package/dist/components/widgets/camera/live-or-polling-video.svelte +1 -1
- package/dist/components/widgets/encoder/encoder.svelte +36 -34
- package/dist/components/widgets/gantry/gantry.svelte +102 -98
- package/dist/components/widgets/gantry/move-to-position.svelte +1 -1
- package/dist/components/widgets/input-controller/input-controller.svelte +1 -1
- package/dist/components/widgets/ml-model-service/ml-model-service.svelte +1 -1
- package/dist/components/widgets/motor/go-for.svelte +1 -1
- package/dist/components/widgets/motor/go-to.svelte +1 -1
- package/dist/components/widgets/motor/motor.svelte +88 -86
- package/dist/components/widgets/operations-and-sessions/operations-table.svelte +53 -44
- package/dist/components/widgets/operations-and-sessions/sessions-table.svelte +45 -36
- package/dist/components/widgets/power-sensor/power-sensor.svelte +42 -40
- package/package.json +16 -6
|
@@ -57,75 +57,77 @@
|
|
|
57
57
|
|
|
58
58
|
<ConnectionStatus {partID}>
|
|
59
59
|
{#snippet connected()}
|
|
60
|
-
<div class="
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<ApiSection
|
|
66
|
-
title="GetJointPositions"
|
|
67
|
-
api="rdk:component:arm"
|
|
68
|
-
bottomText="Updates automatically"
|
|
60
|
+
<div class="@container">
|
|
61
|
+
<div class="flex flex-col gap-4 @2xl:flex-row @2xl:gap-0 @2xl:divide-x">
|
|
62
|
+
<!-- Main control sections -->
|
|
63
|
+
<div
|
|
64
|
+
class="flex flex-col gap-4 @2xl:grid @2xl:grow @2xl:grid-cols-2 @2xl:gap-0 @2xl:divide-x @4xl:grid-cols-3"
|
|
69
65
|
>
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
66
|
+
<ApiSection
|
|
67
|
+
title="GetJointPositions"
|
|
68
|
+
api="rdk:component:arm"
|
|
69
|
+
bottomText="Updates automatically"
|
|
70
|
+
>
|
|
71
|
+
<Query query={jointPositionsQuery}>
|
|
72
|
+
{#if jointPositionsQuery.data}
|
|
73
|
+
<GetJointPositions positions={jointPositionsQuery.data.values} />
|
|
74
|
+
{/if}
|
|
75
|
+
</Query>
|
|
76
|
+
</ApiSection>
|
|
77
|
+
<ApiSection
|
|
78
|
+
title="MoveToJointPositions"
|
|
79
|
+
api="rdk:component:arm"
|
|
80
|
+
>
|
|
81
|
+
<Query query={jointPositionsQuery}>
|
|
82
|
+
{#if jointPositionsQuery.data}
|
|
83
|
+
<MoveToJointPositions
|
|
84
|
+
positions={jointPositionsQuery.data.values}
|
|
85
|
+
{moveToJointPositions}
|
|
86
|
+
lastError={moveToJointPosMutation.error}
|
|
87
|
+
{jointLimitsDegrees}
|
|
88
|
+
isMoving={isMovingQuery.data ?? false}
|
|
89
|
+
/>
|
|
90
|
+
{/if}
|
|
91
|
+
</Query>
|
|
92
|
+
</ApiSection>
|
|
93
|
+
<ApiSection
|
|
94
|
+
title="MoveToPosition"
|
|
95
|
+
api="rdk:component:arm"
|
|
96
|
+
>
|
|
97
|
+
<Query query={endPositionQuery}>
|
|
98
|
+
{#if endPositionQuery.data}
|
|
99
|
+
<MoveToPosition
|
|
100
|
+
endPosition={endPositionQuery.data}
|
|
101
|
+
{moveToPosition}
|
|
102
|
+
lastError={moveToPosMutation.error}
|
|
103
|
+
/>
|
|
104
|
+
{/if}
|
|
105
|
+
</Query>
|
|
106
|
+
</ApiSection>
|
|
107
|
+
</div>
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
>
|
|
112
|
-
<ApiSection
|
|
113
|
-
title="Stop"
|
|
114
|
-
api="rdk:component:arm"
|
|
109
|
+
<!-- Control actions sidebar -->
|
|
110
|
+
<div
|
|
111
|
+
class="flex flex-row gap-4 @2xl:ml-auto @2xl:w-full @2xl:max-w-40 @2xl:flex-col @2xl:gap-0 @2xl:divide-y"
|
|
115
112
|
>
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
113
|
+
<ApiSection
|
|
114
|
+
title="Stop"
|
|
115
|
+
api="rdk:component:arm"
|
|
116
|
+
>
|
|
117
|
+
<StopButton
|
|
118
|
+
error={stopMutation.error}
|
|
119
|
+
onStop={() => {
|
|
120
|
+
stopMutation.mutate([], {})
|
|
121
|
+
}}
|
|
122
|
+
/>
|
|
123
|
+
</ApiSection>
|
|
124
|
+
<IsMoving
|
|
125
|
+
client={ArmClient}
|
|
126
|
+
api="rdk:component:arm"
|
|
127
|
+
{partID}
|
|
128
|
+
{resourceName}
|
|
121
129
|
/>
|
|
122
|
-
</
|
|
123
|
-
<IsMoving
|
|
124
|
-
client={ArmClient}
|
|
125
|
-
api="rdk:component:arm"
|
|
126
|
-
{partID}
|
|
127
|
-
{resourceName}
|
|
128
|
-
/>
|
|
130
|
+
</div>
|
|
129
131
|
</div>
|
|
130
132
|
</div>
|
|
131
133
|
{/snippet}
|
|
@@ -60,46 +60,48 @@
|
|
|
60
60
|
|
|
61
61
|
<ConnectionStatus {partID}>
|
|
62
62
|
{#snippet connected()}
|
|
63
|
-
<div class="
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
<div class="@container">
|
|
64
|
+
<div class="flex flex-col divide-y @4xl:flex-row @4xl:divide-x @4xl:divide-y-0">
|
|
65
|
+
<MutationSection
|
|
66
|
+
title="Quick move"
|
|
67
|
+
lastError={quickSetPowerMutation.error}
|
|
68
|
+
>
|
|
69
|
+
{#snippet titleInput()}
|
|
70
|
+
<Label>
|
|
71
|
+
Keyboard control
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
<Switch
|
|
74
|
+
slot="input"
|
|
75
|
+
on={quickMoveKeyboardControl}
|
|
76
|
+
on:change={() => (quickMoveKeyboardControl = !quickMoveKeyboardControl)}
|
|
77
|
+
/>
|
|
78
|
+
</Label>
|
|
79
|
+
{/snippet}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
<QuickMove
|
|
82
|
+
isKeyboardEnabled={quickMoveKeyboardControl}
|
|
83
|
+
setPower={quickSetPower}
|
|
84
|
+
/>
|
|
85
|
+
</MutationSection>
|
|
86
|
+
<div class="flex grow flex-col divide-y @4xl:ml-auto @4xl:w-full @4xl:max-w-40">
|
|
87
|
+
<ApiSection
|
|
88
|
+
title="Stop"
|
|
89
|
+
api="rdk:component:base"
|
|
90
|
+
>
|
|
91
|
+
<StopButton
|
|
92
|
+
error={stopMutation.error}
|
|
93
|
+
onStop={() => {
|
|
94
|
+
stopMutation.mutate([])
|
|
95
|
+
}}
|
|
96
|
+
/>
|
|
97
|
+
</ApiSection>
|
|
98
|
+
<IsMoving
|
|
99
|
+
client={BaseClient}
|
|
100
|
+
api="rdk:component:base"
|
|
101
|
+
{partID}
|
|
102
|
+
{resourceName}
|
|
95
103
|
/>
|
|
96
|
-
</
|
|
97
|
-
<IsMoving
|
|
98
|
-
client={BaseClient}
|
|
99
|
-
api="rdk:component:base"
|
|
100
|
-
{partID}
|
|
101
|
-
{resourceName}
|
|
102
|
-
/>
|
|
104
|
+
</div>
|
|
103
105
|
</div>
|
|
104
106
|
</div>
|
|
105
107
|
<MutationSection
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
let angularPower = $state<Vector3>({ x: 0, y: 0, z: 0.75 })
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
|
-
<div class="flex flex-
|
|
18
|
+
<div class="flex flex-wrap gap-4">
|
|
19
19
|
<Vec3Builder
|
|
20
20
|
title="Linear power"
|
|
21
21
|
titleTooltip="The percentage of max power of the base’s linear propulsion. In the range of –1.0 to 1.0, with 1.0 meaning 100% power."
|
|
@@ -405,7 +405,7 @@
|
|
|
405
405
|
lastError={resolutionMutation.error}
|
|
406
406
|
class="-m-4 mt-4"
|
|
407
407
|
>
|
|
408
|
-
<div class="flex w-full flex-
|
|
408
|
+
<div class="flex w-full flex-wrap justify-between gap-2">
|
|
409
409
|
<Label cx="max-w-[96px] gap-1 text-xs">
|
|
410
410
|
<span class="flex gap-1 whitespace-nowrap">
|
|
411
411
|
Resolution
|
|
@@ -61,42 +61,44 @@
|
|
|
61
61
|
/>
|
|
62
62
|
</div>
|
|
63
63
|
|
|
64
|
-
<div class="
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
<div class="@container">
|
|
65
|
+
<div class="grid w-full grid-cols-1 divide-y @lg:grid-cols-2 @lg:divide-x @lg:divide-y-0">
|
|
66
|
+
<ApiSection
|
|
67
|
+
title="GetPosition"
|
|
68
|
+
api="rdk:component:encoder"
|
|
69
|
+
tooltip="Relative encoders return ticks since last zeroing. Absolute encoders return degrees."
|
|
70
|
+
class="gap-3"
|
|
71
|
+
>
|
|
72
|
+
<Queries queries={[propertiesQuery, positionQuery]}>
|
|
73
|
+
{#if positionQuery.data !== undefined}
|
|
74
|
+
{@const [position, encoderPositionType] = positionQuery.data}
|
|
75
|
+
<div class="font-roboto-mono flex flex-col gap-2 text-sm">
|
|
76
|
+
<Position
|
|
77
|
+
{position}
|
|
78
|
+
{encoderPositionType}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
82
|
+
</Queries>
|
|
83
|
+
</ApiSection>
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
>
|
|
89
|
-
<Button
|
|
90
|
-
icon="play-circle-outline"
|
|
91
|
-
class="w-fit"
|
|
92
|
-
onclick={() => {
|
|
93
|
-
resetMutation.mutate([], {})
|
|
94
|
-
}}
|
|
85
|
+
<ApiSection
|
|
86
|
+
title="ResetPosition"
|
|
87
|
+
api="rdk:component:encoder"
|
|
88
|
+
description="Set the current position as the new zero position"
|
|
95
89
|
>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
<Button
|
|
91
|
+
icon="play-circle-outline"
|
|
92
|
+
class="w-fit"
|
|
93
|
+
onclick={() => {
|
|
94
|
+
resetMutation.mutate([], {})
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
Execute
|
|
98
|
+
</Button>
|
|
99
|
+
<ErrorDisplay lastError={resetMutation.error} />
|
|
100
|
+
</ApiSection>
|
|
101
|
+
</div>
|
|
100
102
|
</div>
|
|
101
103
|
{/snippet}
|
|
102
104
|
</ConnectionStatus>
|
|
@@ -45,113 +45,117 @@
|
|
|
45
45
|
|
|
46
46
|
<ConnectionStatus {partID}>
|
|
47
47
|
{#snippet connected()}
|
|
48
|
-
<div class="
|
|
49
|
-
<div class="flex
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class="text-subtle-2 flex flex-row items-center gap-1 text-sm"
|
|
56
|
-
id={positionHeadingID}
|
|
57
|
-
>
|
|
58
|
-
<a
|
|
59
|
-
href={apiDocsHref('rdk:component:gantry', 'getPosition')}
|
|
60
|
-
target="_blank"
|
|
61
|
-
rel="noopener noreferrer external"
|
|
62
|
-
class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
|
|
48
|
+
<div class="@container">
|
|
49
|
+
<div class="flex flex-col divide-y @4xl:flex-row @4xl:divide-x @4xl:divide-y-0">
|
|
50
|
+
<div class="@container grow">
|
|
51
|
+
<div class="flex flex-col divide-y @2xl:flex-row @2xl:divide-x @2xl:divide-y-0">
|
|
52
|
+
<ApiSection
|
|
53
|
+
bottomText="Updates automatically"
|
|
54
|
+
aria-labelledby={positionHeadingID}
|
|
63
55
|
>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
56
|
+
<h3
|
|
57
|
+
class="text-subtle-2 flex flex-row items-center gap-1 text-sm"
|
|
58
|
+
id={positionHeadingID}
|
|
59
|
+
>
|
|
60
|
+
<a
|
|
61
|
+
href={apiDocsHref('rdk:component:gantry', 'getPosition')}
|
|
62
|
+
target="_blank"
|
|
63
|
+
rel="noopener noreferrer external"
|
|
64
|
+
class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
|
|
65
|
+
>
|
|
66
|
+
GetPosition
|
|
67
|
+
</a>
|
|
68
|
+
and
|
|
69
|
+
<a
|
|
70
|
+
href={apiDocsHref('rdk:component:gantry', 'getLengths')}
|
|
71
|
+
target="_blank"
|
|
72
|
+
rel="noopener noreferrer external"
|
|
73
|
+
class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
|
|
74
|
+
>
|
|
75
|
+
GetLengths
|
|
76
|
+
</a>
|
|
77
|
+
</h3>
|
|
78
|
+
<Queries queries={[positionQuery, lengthsQuery]}>
|
|
79
|
+
{@const positions = positionQuery.data}
|
|
80
|
+
{@const lengths = lengthsQuery.data ?? []}
|
|
81
|
+
{#if positions !== undefined}
|
|
82
|
+
<PositionAndLengths
|
|
83
|
+
{positions}
|
|
84
|
+
{lengths}
|
|
85
|
+
/>
|
|
86
|
+
{/if}
|
|
87
|
+
</Queries>
|
|
88
|
+
</ApiSection>
|
|
89
|
+
<ApiSection
|
|
90
|
+
title="MoveToPosition"
|
|
91
|
+
api="rdk:component:gantry"
|
|
72
92
|
>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<QuickMove
|
|
116
|
-
{positions}
|
|
117
|
-
lastError={quickMoveMutation.error}
|
|
118
|
-
moveTo={(newPos: number[], speeds: number[]) => {
|
|
119
|
-
quickMoveMutation.mutate([newPos, speeds], {})
|
|
120
|
-
}}
|
|
93
|
+
<Query query={positionQuery}>
|
|
94
|
+
{@const positions = positionQuery.data}
|
|
95
|
+
{#if positions !== undefined}
|
|
96
|
+
<MoveToPosition
|
|
97
|
+
{positions}
|
|
98
|
+
lastError={moveMutation.error}
|
|
99
|
+
moveTo={(newPos: number[], speeds: number[]) => {
|
|
100
|
+
moveMutation.mutate([newPos, speeds], {})
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
{/if}
|
|
104
|
+
</Query>
|
|
105
|
+
</ApiSection>
|
|
106
|
+
<div class="flex grow flex-col divide-y">
|
|
107
|
+
<ApiSection
|
|
108
|
+
title="Quick move"
|
|
109
|
+
bottomText="Press a button to execute"
|
|
110
|
+
>
|
|
111
|
+
<Query
|
|
112
|
+
query={positionQuery}
|
|
113
|
+
contentCx="h-6"
|
|
114
|
+
>
|
|
115
|
+
{@const positions = positionQuery.data}
|
|
116
|
+
{#if positions !== undefined}
|
|
117
|
+
<QuickMove
|
|
118
|
+
{positions}
|
|
119
|
+
lastError={quickMoveMutation.error}
|
|
120
|
+
moveTo={(newPos: number[], speeds: number[]) => {
|
|
121
|
+
quickMoveMutation.mutate([newPos, speeds], {})
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
{/if}
|
|
125
|
+
</Query>
|
|
126
|
+
</ApiSection>
|
|
127
|
+
<ApiSection
|
|
128
|
+
title="Home"
|
|
129
|
+
api="rdk:component:gantry"
|
|
130
|
+
description="Run the homing sequence"
|
|
131
|
+
>
|
|
132
|
+
<Home
|
|
133
|
+
{partID}
|
|
134
|
+
{resourceName}
|
|
121
135
|
/>
|
|
122
|
-
|
|
123
|
-
</
|
|
124
|
-
</
|
|
136
|
+
</ApiSection>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="flex flex-col divide-y @4xl:ml-auto @4xl:w-full @4xl:max-w-40">
|
|
125
141
|
<ApiSection
|
|
126
|
-
title="
|
|
142
|
+
title="Stop"
|
|
127
143
|
api="rdk:component:gantry"
|
|
128
|
-
description="Run the homing sequence"
|
|
129
144
|
>
|
|
130
|
-
<
|
|
131
|
-
{
|
|
132
|
-
{
|
|
145
|
+
<StopButton
|
|
146
|
+
error={stopMutation.error}
|
|
147
|
+
onStop={() => {
|
|
148
|
+
stopMutation.mutate([])
|
|
149
|
+
}}
|
|
133
150
|
/>
|
|
134
151
|
</ApiSection>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
api="rdk:component:gantry"
|
|
141
|
-
>
|
|
142
|
-
<StopButton
|
|
143
|
-
error={stopMutation.error}
|
|
144
|
-
onStop={() => {
|
|
145
|
-
stopMutation.mutate([])
|
|
146
|
-
}}
|
|
152
|
+
<IsMoving
|
|
153
|
+
client={GantryClient}
|
|
154
|
+
api="rdk:component:gantry"
|
|
155
|
+
{partID}
|
|
156
|
+
{resourceName}
|
|
147
157
|
/>
|
|
148
|
-
</
|
|
149
|
-
<IsMoving
|
|
150
|
-
client={GantryClient}
|
|
151
|
-
api="rdk:component:gantry"
|
|
152
|
-
{partID}
|
|
153
|
-
{resourceName}
|
|
154
|
-
/>
|
|
158
|
+
</div>
|
|
155
159
|
</div>
|
|
156
160
|
</div>
|
|
157
161
|
{/snippet}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
<ConnectionStatus {partID}>
|
|
41
41
|
{#snippet connected()}
|
|
42
|
-
<div class="flex flex-
|
|
42
|
+
<div class="flex flex-wrap items-center justify-between gap-2 p-4 pb-3">
|
|
43
43
|
<RefetchController
|
|
44
44
|
{refetchInterval}
|
|
45
45
|
queries={[eventsQuery]}
|
|
@@ -76,107 +76,109 @@
|
|
|
76
76
|
|
|
77
77
|
<ConnectionStatus {partID}>
|
|
78
78
|
{#snippet connected()}
|
|
79
|
-
<div class="
|
|
80
|
-
<div class="flex
|
|
81
|
-
<
|
|
82
|
-
title="Quick move"
|
|
83
|
-
lastError={quickSetPowerMutation.error}
|
|
84
|
-
>
|
|
85
|
-
<QuickMove setPower={quickSetPower} />
|
|
86
|
-
</MutationSection>
|
|
87
|
-
<MutationSection
|
|
88
|
-
title="SetPower"
|
|
89
|
-
api="rdk:component:motor"
|
|
90
|
-
description="Move continuously"
|
|
91
|
-
lastError={setPowerMutation.error}
|
|
92
|
-
>
|
|
93
|
-
<SetPower {setPower} />
|
|
94
|
-
</MutationSection>
|
|
95
|
-
{#if propertiesQuery.data?.positionReporting}
|
|
79
|
+
<div class="@container">
|
|
80
|
+
<div class="flex flex-col divide-y @2xl:flex-row @2xl:divide-x @2xl:divide-y-0">
|
|
81
|
+
<div class="flex w-full flex-col divide-y">
|
|
96
82
|
<MutationSection
|
|
97
|
-
title="
|
|
98
|
-
|
|
99
|
-
description="Move indefinitely at a specified speed."
|
|
100
|
-
lastError={setRPMMutation.error}
|
|
101
|
-
>
|
|
102
|
-
<SetRPM {setRPM} />
|
|
103
|
-
</MutationSection>
|
|
104
|
-
<MutationSection
|
|
105
|
-
title="GoFor"
|
|
106
|
-
api="rdk:component:motor"
|
|
107
|
-
description="Move a specified number of revolutions"
|
|
108
|
-
lastError={goForMutation.error}
|
|
83
|
+
title="Quick move"
|
|
84
|
+
lastError={quickSetPowerMutation.error}
|
|
109
85
|
>
|
|
110
|
-
<
|
|
86
|
+
<QuickMove setPower={quickSetPower} />
|
|
111
87
|
</MutationSection>
|
|
112
88
|
<MutationSection
|
|
113
|
-
title="
|
|
89
|
+
title="SetPower"
|
|
114
90
|
api="rdk:component:motor"
|
|
115
|
-
description="
|
|
116
|
-
lastError={
|
|
91
|
+
description="Move continuously"
|
|
92
|
+
lastError={setPowerMutation.error}
|
|
117
93
|
>
|
|
118
|
-
<
|
|
94
|
+
<SetPower {setPower} />
|
|
119
95
|
</MutationSection>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<div class="ml-auto flex w-full max-w-1/2 flex-col divide-y sm:max-w-1/3">
|
|
124
|
-
<ApiSection
|
|
125
|
-
title="Stop"
|
|
126
|
-
api="rdk:component:motor"
|
|
127
|
-
>
|
|
128
|
-
<StopButton
|
|
129
|
-
error={stopMutation.error}
|
|
130
|
-
onStop={() => {
|
|
131
|
-
stopMutation.mutate([])
|
|
132
|
-
}}
|
|
133
|
-
/>
|
|
134
|
-
</ApiSection>
|
|
135
|
-
<IsMoving
|
|
136
|
-
client={MotorClient}
|
|
137
|
-
api="rdk:component:motor"
|
|
138
|
-
{partID}
|
|
139
|
-
{resourceName}
|
|
140
|
-
>
|
|
141
|
-
<div class="flex flex-col gap-6 pt-2">
|
|
142
|
-
<ApiSection
|
|
143
|
-
title="IsPowered"
|
|
96
|
+
{#if propertiesQuery.data?.positionReporting}
|
|
97
|
+
<MutationSection
|
|
98
|
+
title="SetRPM"
|
|
144
99
|
api="rdk:component:motor"
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Stepper motors will report ”true” if they are being powered while holding
|
|
149
|
-
a position and while they are turning."
|
|
100
|
+
description="Move indefinitely at a specified speed."
|
|
101
|
+
lastError={setRPMMutation.error}
|
|
150
102
|
>
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
103
|
+
<SetRPM {setRPM} />
|
|
104
|
+
</MutationSection>
|
|
105
|
+
<MutationSection
|
|
106
|
+
title="GoFor"
|
|
107
|
+
api="rdk:component:motor"
|
|
108
|
+
description="Move a specified number of revolutions"
|
|
109
|
+
lastError={goForMutation.error}
|
|
110
|
+
>
|
|
111
|
+
<GoFor {goFor} />
|
|
112
|
+
</MutationSection>
|
|
113
|
+
<MutationSection
|
|
114
|
+
title="GoTo"
|
|
115
|
+
api="rdk:component:motor"
|
|
116
|
+
description="Turn to a specified position"
|
|
117
|
+
lastError={goToMutation.error}
|
|
118
|
+
>
|
|
119
|
+
<GoTo {goTo} />
|
|
120
|
+
</MutationSection>
|
|
121
|
+
{/if}
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="flex w-full flex-col divide-y @2xl:ml-auto @2xl:max-w-1/2 @4xl:max-w-1/3">
|
|
125
|
+
<ApiSection
|
|
126
|
+
title="Stop"
|
|
127
|
+
api="rdk:component:motor"
|
|
128
|
+
>
|
|
129
|
+
<StopButton
|
|
130
|
+
error={stopMutation.error}
|
|
131
|
+
onStop={() => {
|
|
132
|
+
stopMutation.mutate([])
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
</ApiSection>
|
|
136
|
+
<IsMoving
|
|
137
|
+
client={MotorClient}
|
|
138
|
+
api="rdk:component:motor"
|
|
139
|
+
{partID}
|
|
140
|
+
{resourceName}
|
|
141
|
+
>
|
|
142
|
+
<div class="flex flex-col gap-6 pt-2">
|
|
165
143
|
<ApiSection
|
|
166
|
-
title="
|
|
144
|
+
title="IsPowered"
|
|
167
145
|
api="rdk:component:motor"
|
|
168
146
|
class="gap-3 p-0"
|
|
169
|
-
tooltip="
|
|
147
|
+
tooltip="Returns whether or not the motor is running and the current portion of max power.
|
|
148
|
+
|
|
149
|
+
Stepper motors will report ”true” if they are being powered while holding
|
|
150
|
+
a position and while they are turning."
|
|
170
151
|
>
|
|
171
|
-
<Query query={
|
|
172
|
-
|
|
173
|
-
{
|
|
174
|
-
|
|
152
|
+
<Query query={isPoweredQuery}>
|
|
153
|
+
{#if isPoweredQuery.data !== undefined}
|
|
154
|
+
{@const [isPowered, powerPct] = isPoweredQuery.data}
|
|
155
|
+
<span class="font-roboto-mono flex flex-row gap-1 text-xs">
|
|
156
|
+
<p class="text-default">{isPowered}</p>
|
|
157
|
+
<p class="text-disabled">/</p>
|
|
158
|
+
<p class="text-subtle-1">
|
|
159
|
+
{formatNumeric(powerPct * 100, 1)}%
|
|
160
|
+
</p>
|
|
161
|
+
</span>
|
|
162
|
+
{/if}
|
|
175
163
|
</Query>
|
|
176
164
|
</ApiSection>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
165
|
+
{#if propertiesQuery.data?.positionReporting === true}
|
|
166
|
+
<ApiSection
|
|
167
|
+
title="GetPosition"
|
|
168
|
+
api="rdk:component:motor"
|
|
169
|
+
class="gap-3 p-0"
|
|
170
|
+
tooltip="Reports the position of an encoded motor in revolutions from zero/home."
|
|
171
|
+
>
|
|
172
|
+
<Query query={positionQuery}>
|
|
173
|
+
<p class="font-roboto-mono text-default text-xs">
|
|
174
|
+
{formatNumeric(positionQuery.data, 4)}
|
|
175
|
+
</p>
|
|
176
|
+
</Query>
|
|
177
|
+
</ApiSection>
|
|
178
|
+
{/if}
|
|
179
|
+
</div>
|
|
180
|
+
</IsMoving>
|
|
181
|
+
</div>
|
|
180
182
|
</div>
|
|
181
183
|
</div>
|
|
182
184
|
{/snippet}
|
|
@@ -34,49 +34,58 @@
|
|
|
34
34
|
{#if formattedOperations.length === 0}
|
|
35
35
|
<p class="text-subtle-2 text-xs">No operations currently available</p>
|
|
36
36
|
{:else}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
>{operation.id}
|
|
54
|
-
</td>
|
|
55
|
-
<td
|
|
56
|
-
class="truncate p-2"
|
|
57
|
-
title={operation.sessionId}
|
|
58
|
-
>{operation.sessionId}
|
|
59
|
-
</td>
|
|
60
|
-
<td
|
|
61
|
-
class="truncate p-2"
|
|
62
|
-
title={operation.method}
|
|
63
|
-
>{operation.method}
|
|
64
|
-
</td>
|
|
65
|
-
<td
|
|
66
|
-
class="truncate p-2"
|
|
67
|
-
title={`${formatNumeric(operation.elapsedTime, 0)} ms`}
|
|
68
|
-
>
|
|
69
|
-
{formatNumeric(operation.elapsedTime, 0)} ms
|
|
70
|
-
</td>
|
|
71
|
-
<td class="p-2">
|
|
72
|
-
<Tooltip hoverDelayMS={500}>
|
|
73
|
-
<Button onclick={() => cancelOperation(operation.id)}>Kill</Button>
|
|
74
|
-
|
|
75
|
-
<span slot="description"> Request cancellation of the operation. </span>
|
|
76
|
-
</Tooltip>
|
|
77
|
-
</td>
|
|
37
|
+
<!-- Scroll region: keyboard users need focus on the wrapper to scroll the overflow (WCAG 2.1.1). -->
|
|
38
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
39
|
+
<div
|
|
40
|
+
class="overflow-x-auto"
|
|
41
|
+
role="region"
|
|
42
|
+
aria-label="Operations"
|
|
43
|
+
tabindex="0"
|
|
44
|
+
>
|
|
45
|
+
<table class="w-full min-w-md table-fixed">
|
|
46
|
+
<thead>
|
|
47
|
+
<tr class="bg-light text-subtle-1 border text-left text-xs">
|
|
48
|
+
<th class="w-1/4 p-2 font-normal">ID</th>
|
|
49
|
+
<th class="w-1/4 p-2 font-normal">Session</th>
|
|
50
|
+
<th class="w-1/4 p-2 font-normal">Method</th>
|
|
51
|
+
<th class="w-1/6 p-2 font-normal">Elapsed Time</th>
|
|
52
|
+
<th class="w-16"></th>
|
|
78
53
|
</tr>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
54
|
+
</thead>
|
|
55
|
+
<tbody class="text-xs">
|
|
56
|
+
{#each formattedOperations as operation (operation.id)}
|
|
57
|
+
<tr class="border border-b text-left">
|
|
58
|
+
<td
|
|
59
|
+
class="truncate p-2"
|
|
60
|
+
title={operation.id}
|
|
61
|
+
>{operation.id}
|
|
62
|
+
</td>
|
|
63
|
+
<td
|
|
64
|
+
class="truncate p-2"
|
|
65
|
+
title={operation.sessionId}
|
|
66
|
+
>{operation.sessionId}
|
|
67
|
+
</td>
|
|
68
|
+
<td
|
|
69
|
+
class="truncate p-2"
|
|
70
|
+
title={operation.method}
|
|
71
|
+
>{operation.method}
|
|
72
|
+
</td>
|
|
73
|
+
<td
|
|
74
|
+
class="truncate p-2"
|
|
75
|
+
title={`${formatNumeric(operation.elapsedTime, 0)} ms`}
|
|
76
|
+
>
|
|
77
|
+
{formatNumeric(operation.elapsedTime, 0)} ms
|
|
78
|
+
</td>
|
|
79
|
+
<td class="p-2">
|
|
80
|
+
<Tooltip hoverDelayMS={500}>
|
|
81
|
+
<Button onclick={() => cancelOperation(operation.id)}>Kill</Button>
|
|
82
|
+
|
|
83
|
+
<span slot="description"> Request cancellation of the operation. </span>
|
|
84
|
+
</Tooltip>
|
|
85
|
+
</td>
|
|
86
|
+
</tr>
|
|
87
|
+
{/each}
|
|
88
|
+
</tbody>
|
|
89
|
+
</table>
|
|
90
|
+
</div>
|
|
82
91
|
{/if}
|
|
@@ -38,41 +38,50 @@
|
|
|
38
38
|
{#if flattenedSessions.length === 0}
|
|
39
39
|
<p class="text-subtle-2 text-xs">No sessions currently available</p>
|
|
40
40
|
{:else}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
>
|
|
57
|
-
{session.id}
|
|
58
|
-
{#if session.id === ourSessionId}
|
|
59
|
-
<div class="text-subtle-2 text-xs">(Ours)</div>
|
|
60
|
-
{/if}
|
|
61
|
-
</td>
|
|
62
|
-
<td class="truncate p-2">{session.typeString}</td>
|
|
63
|
-
<td
|
|
64
|
-
class="truncate p-2"
|
|
65
|
-
title={session.remoteAddress}
|
|
66
|
-
>{session.remoteAddress}
|
|
67
|
-
</td>
|
|
68
|
-
<td
|
|
69
|
-
class="truncate p-2"
|
|
70
|
-
title={session.localAddress}
|
|
71
|
-
>
|
|
72
|
-
{session.localAddress}
|
|
73
|
-
</td>
|
|
41
|
+
<!-- Scroll region: keyboard users need focus on the wrapper to scroll the overflow (WCAG 2.1.1). -->
|
|
42
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
43
|
+
<div
|
|
44
|
+
class="overflow-x-auto"
|
|
45
|
+
role="region"
|
|
46
|
+
aria-label="Sessions"
|
|
47
|
+
tabindex="0"
|
|
48
|
+
>
|
|
49
|
+
<table class="w-full min-w-md table-fixed">
|
|
50
|
+
<thead>
|
|
51
|
+
<tr class="bg-light text-subtle-1 border text-left text-xs">
|
|
52
|
+
<th class="w-1/4 p-2 font-normal">ID</th>
|
|
53
|
+
<th class="w-1/8 p-2 font-normal">Type</th>
|
|
54
|
+
<th class="w-1/4 p-2 font-normal">Remote Address</th>
|
|
55
|
+
<th class="w-1/4 p-2 font-normal">Local Address</th>
|
|
74
56
|
</tr>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
</thead>
|
|
58
|
+
<tbody class="text-xs">
|
|
59
|
+
{#each flattenedSessions as session (session.id)}
|
|
60
|
+
<tr class="border border-b text-left">
|
|
61
|
+
<td
|
|
62
|
+
class="truncate p-2 text-left"
|
|
63
|
+
title={session.id}
|
|
64
|
+
>
|
|
65
|
+
{session.id}
|
|
66
|
+
{#if session.id === ourSessionId}
|
|
67
|
+
<div class="text-subtle-2 text-xs">(Ours)</div>
|
|
68
|
+
{/if}
|
|
69
|
+
</td>
|
|
70
|
+
<td class="truncate p-2">{session.typeString}</td>
|
|
71
|
+
<td
|
|
72
|
+
class="truncate p-2"
|
|
73
|
+
title={session.remoteAddress}
|
|
74
|
+
>{session.remoteAddress}
|
|
75
|
+
</td>
|
|
76
|
+
<td
|
|
77
|
+
class="truncate p-2"
|
|
78
|
+
title={session.localAddress}
|
|
79
|
+
>
|
|
80
|
+
{session.localAddress}
|
|
81
|
+
</td>
|
|
82
|
+
</tr>
|
|
83
|
+
{/each}
|
|
84
|
+
</tbody>
|
|
85
|
+
</table>
|
|
86
|
+
</div>
|
|
78
87
|
{/if}
|
|
@@ -63,49 +63,51 @@
|
|
|
63
63
|
/>
|
|
64
64
|
</div>
|
|
65
65
|
|
|
66
|
-
<div class="
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<Query
|
|
73
|
-
query={currentQuery}
|
|
74
|
-
contentCx="h-6"
|
|
66
|
+
<div class="@container">
|
|
67
|
+
<div class="grid w-full grid-cols-1 divide-y @2xl:grid-cols-3 @2xl:divide-x @2xl:divide-y-0">
|
|
68
|
+
<ApiSection
|
|
69
|
+
title="GetCurrent"
|
|
70
|
+
api="rdk:component:power_sensor"
|
|
71
|
+
class="pb-5"
|
|
75
72
|
>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
<Query
|
|
74
|
+
query={currentQuery}
|
|
75
|
+
contentCx="h-6"
|
|
76
|
+
>
|
|
77
|
+
{#if currentQuery.data !== undefined}
|
|
78
|
+
<CurrentReading data={currentQuery.data} />
|
|
79
|
+
{/if}
|
|
80
|
+
</Query>
|
|
81
|
+
</ApiSection>
|
|
82
|
+
<ApiSection
|
|
83
|
+
title="GetVoltage"
|
|
84
|
+
api="rdk:component:power_sensor"
|
|
85
|
+
class="pb-5"
|
|
89
86
|
>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
87
|
+
<Query
|
|
88
|
+
query={voltageQuery}
|
|
89
|
+
contentCx="h-6"
|
|
90
|
+
>
|
|
91
|
+
{#if voltageQuery.data !== undefined}
|
|
92
|
+
<VoltageReading data={voltageQuery.data} />
|
|
93
|
+
{/if}
|
|
94
|
+
</Query>
|
|
95
|
+
</ApiSection>
|
|
96
|
+
<ApiSection
|
|
97
|
+
title="GetPower"
|
|
98
|
+
api="rdk:component:power_sensor"
|
|
99
|
+
class="pb-5"
|
|
103
100
|
>
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
<Query
|
|
102
|
+
query={powerQuery}
|
|
103
|
+
contentCx="h-6"
|
|
104
|
+
>
|
|
105
|
+
{#if powerQuery.data !== undefined}
|
|
106
|
+
<PowerReading data={powerQuery.data} />
|
|
107
|
+
{/if}
|
|
108
|
+
</Query>
|
|
109
|
+
</ApiSection>
|
|
110
|
+
</div>
|
|
109
111
|
</div>
|
|
110
112
|
|
|
111
113
|
<ApiSection
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/test-widgets",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"wireit": {
|
|
@@ -103,7 +103,8 @@
|
|
|
103
103
|
"!coverage/**",
|
|
104
104
|
"!test-results/**",
|
|
105
105
|
"!.env*",
|
|
106
|
-
"!**/*.tgz"
|
|
106
|
+
"!**/*.tgz",
|
|
107
|
+
"!.claude/**"
|
|
107
108
|
],
|
|
108
109
|
"output": [],
|
|
109
110
|
"packageLocks": [
|
|
@@ -120,7 +121,8 @@
|
|
|
120
121
|
"!coverage/**",
|
|
121
122
|
"!test-results/**",
|
|
122
123
|
"!.env*",
|
|
123
|
-
"!**/*.tgz"
|
|
124
|
+
"!**/*.tgz",
|
|
125
|
+
"!.claude/**"
|
|
124
126
|
],
|
|
125
127
|
"output": [],
|
|
126
128
|
"packageLocks": [
|
|
@@ -216,18 +218,27 @@
|
|
|
216
218
|
"@fontsource-variable/public-sans": "^5.2.7",
|
|
217
219
|
"@fontsource-variable/roboto-mono": "^5.2.8",
|
|
218
220
|
"@fontsource-variable/space-grotesk": "^5.2.10",
|
|
221
|
+
"@houserules/cli": "^0.4.1",
|
|
222
|
+
"@houserules/plugin-accessibility": "^0.1.3",
|
|
223
|
+
"@houserules/plugin-changesets": "^0.2.2",
|
|
224
|
+
"@houserules/plugin-design": "^0.2.2",
|
|
225
|
+
"@houserules/plugin-prose": "^0.1.4",
|
|
226
|
+
"@houserules/plugin-svelte": "^0.1.2",
|
|
227
|
+
"@houserules/plugin-testing": "^0.2.1",
|
|
228
|
+
"@houserules/plugin-three": "^0.2.1",
|
|
229
|
+
"@houserules/plugin-typescript": "^0.1.2",
|
|
219
230
|
"@playwright/test": "^1.59.1",
|
|
220
231
|
"@sentry/svelte": "^10.50.0",
|
|
221
232
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
222
233
|
"@sveltejs/kit": "^2.69.1",
|
|
223
234
|
"@sveltejs/package": "^2.5.7",
|
|
224
235
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
236
|
+
"@tailwindcss/oxide": "^4.2.4",
|
|
225
237
|
"@tailwindcss/postcss": "^4.2.4",
|
|
226
238
|
"@tailwindcss/vite": "^4.2.4",
|
|
227
239
|
"@tanstack/svelte-query": "^6.1.25",
|
|
228
240
|
"@tanstack/svelte-query-devtools": "^6.1.25",
|
|
229
241
|
"@testing-library/dom": "^10.4.1",
|
|
230
|
-
"@testing-library/jest-dom": "^6.9.1",
|
|
231
242
|
"@testing-library/svelte": "^5.3.1",
|
|
232
243
|
"@testing-library/user-event": "^14.6.1",
|
|
233
244
|
"@threlte/core": "^8.5.9",
|
|
@@ -239,7 +250,7 @@
|
|
|
239
250
|
"@viamrobotics/prime-core": "^0.1.22",
|
|
240
251
|
"@viamrobotics/sdk": "^0.69.0",
|
|
241
252
|
"@viamrobotics/svelte-sdk": "^1.2.1",
|
|
242
|
-
"@viamrobotics/tailwind-config": "^1.
|
|
253
|
+
"@viamrobotics/tailwind-config": "^1.2.0",
|
|
243
254
|
"@vitest/browser": "^4.1.10",
|
|
244
255
|
"@vitest/browser-playwright": "^4.1.5",
|
|
245
256
|
"@vitest/coverage-v8": "^4.1.5",
|
|
@@ -252,7 +263,6 @@
|
|
|
252
263
|
"globals": "^17.5.0",
|
|
253
264
|
"lodash-es": "^4.18.1",
|
|
254
265
|
"maplibre-gl": "^5.24.0",
|
|
255
|
-
"mock-match-media": "^1.0.3",
|
|
256
266
|
"playwright": "^1.59.1",
|
|
257
267
|
"prettier": "^3.8.3",
|
|
258
268
|
"prettier-plugin-svelte": "^3.5.1",
|