@kelnishi/satmouse-client 0.9.14 → 0.10.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/chunk-JTG5GEIB.cjs +65 -0
- package/dist/chunk-JTG5GEIB.cjs.map +1 -0
- package/dist/chunk-RNM322RZ.js +60 -0
- package/dist/chunk-RNM322RZ.js.map +1 -0
- package/dist/{connection-5KQFvHoJ.d.cts → connection-DQxI5qib.d.cts} +6 -0
- package/dist/{connection-5KQFvHoJ.d.ts → connection-DQxI5qib.d.ts} +6 -0
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/elements/index.cjs +84 -67
- package/dist/elements/index.cjs.map +1 -1
- package/dist/elements/index.d.cts +4 -1
- package/dist/elements/index.d.ts +4 -1
- package/dist/elements/index.js +84 -67
- package/dist/elements/index.js.map +1 -1
- package/dist/react/index.cjs +130 -236
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +35 -95
- package/dist/react/index.d.ts +35 -95
- package/dist/react/index.js +130 -236
- package/dist/react/index.js.map +1 -1
- package/dist/utils/index.cjs +102 -173
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +42 -115
- package/dist/utils/index.d.ts +42 -115
- package/dist/utils/index.js +96 -161
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-I47ZOX3M.js +0 -64
- package/dist/chunk-I47ZOX3M.js.map +0 -1
- package/dist/chunk-LDSDVYCV.cjs +0 -69
- package/dist/chunk-LDSDVYCV.cjs.map +0 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -40,6 +40,12 @@ interface DeviceInfo$1 {
|
|
|
40
40
|
productId?: number;
|
|
41
41
|
connectionType?: "usb" | "wireless" | "bluetooth" | "unknown";
|
|
42
42
|
connected?: boolean;
|
|
43
|
+
/** Axes this device provides (e.g., ["tx","ty","tz","rx","ry","rz"] or ["tx","ty","rx","ry","tz+","rz+"]) */
|
|
44
|
+
axes?: string[];
|
|
45
|
+
/** Human-readable labels for axes (same order as axes array) */
|
|
46
|
+
axisLabels?: string[];
|
|
47
|
+
/** Number of buttons this device provides */
|
|
48
|
+
buttonCount?: number;
|
|
43
49
|
}
|
|
44
50
|
type ConnectionState = "disconnected" | "connecting" | "connected" | "failed";
|
|
45
51
|
type TransportProtocol = "webtransport" | "websocket" | "none";
|
|
@@ -104,78 +110,42 @@ declare class SatMouseConnection extends TypedEmitter<SatMouseEvents> {
|
|
|
104
110
|
private clearReconnect;
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
rx: boolean;
|
|
112
|
-
ry: boolean;
|
|
113
|
-
rz: boolean;
|
|
114
|
-
}
|
|
115
|
-
interface SensitivityConfig {
|
|
116
|
-
translation: number;
|
|
117
|
-
rotation: number;
|
|
118
|
-
}
|
|
119
|
-
/** Maps each input axis to an output axis. E.g., { tx: "tz", tz: "tx" } swaps X and Z translation. */
|
|
120
|
-
type AxisMap = {
|
|
121
|
-
tx: keyof Vec3;
|
|
122
|
-
ty: keyof Vec3;
|
|
123
|
-
tz: keyof Vec3;
|
|
124
|
-
rx: keyof Vec3;
|
|
125
|
-
ry: keyof Vec3;
|
|
126
|
-
rz: keyof Vec3;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
/** Input axis identifier */
|
|
130
|
-
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
|
|
131
|
-
/** A single action binding — maps one input axis to a named output */
|
|
132
|
-
interface ActionBinding {
|
|
133
|
-
/** Which input axis drives this action */
|
|
113
|
+
/** Axis identifier — full or half */
|
|
114
|
+
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz" | "tx+" | "ty+" | "tz+" | "rx+" | "ry+" | "rz+" | "tx-" | "ty-" | "tz-" | "rx-" | "ry-" | "rz-";
|
|
115
|
+
/** A single axis route — reads from source, writes to target */
|
|
116
|
+
interface AxisRoute {
|
|
134
117
|
source: InputAxis;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
invert?: boolean;
|
|
118
|
+
target: InputAxis;
|
|
119
|
+
/** Negate the value (default: false) */
|
|
120
|
+
flip?: boolean;
|
|
139
121
|
}
|
|
140
|
-
/**
|
|
141
|
-
* ActionMap defines how raw 6DOF axes map to named output actions.
|
|
142
|
-
*
|
|
143
|
-
* Client apps declare the actions they support and how device axes
|
|
144
|
-
* feed into them. Users can reassign axes via the settings UI.
|
|
145
|
-
*
|
|
146
|
-
* Default: 6 actions matching the 6 input axes (passthrough).
|
|
147
|
-
*/
|
|
148
|
-
type ActionMap = Record<string, ActionBinding>;
|
|
149
|
-
/** Result of applying an ActionMap to spatial data */
|
|
150
|
-
type ActionValues = Record<string, number>;
|
|
151
122
|
|
|
152
|
-
/** Per-device
|
|
123
|
+
/** Per-device configuration */
|
|
153
124
|
interface DeviceConfig {
|
|
154
|
-
|
|
155
|
-
|
|
125
|
+
/** Axis routing — each entry maps a device input to an output with optional flip */
|
|
126
|
+
routes?: AxisRoute[];
|
|
127
|
+
/** Scale multiplier applied to all axes (default: 1) */
|
|
128
|
+
scale?: number;
|
|
129
|
+
/** Dead zone threshold (0-1). Values below this are zeroed. */
|
|
156
130
|
deadZone?: number;
|
|
131
|
+
/** Only pass the strongest axis, zero all others */
|
|
157
132
|
dominant?: boolean;
|
|
158
|
-
axisRemap?: Partial<AxisMap>;
|
|
159
|
-
actionMap?: ActionMap;
|
|
160
|
-
lockPosition?: boolean;
|
|
161
|
-
lockRotation?: boolean;
|
|
162
133
|
}
|
|
134
|
+
/** Global configuration */
|
|
163
135
|
interface InputConfig {
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
|
|
136
|
+
/** Default axis routes (used when device has no override) */
|
|
137
|
+
routes: AxisRoute[];
|
|
138
|
+
/** Default scale */
|
|
139
|
+
scale: number;
|
|
140
|
+
/** Dead zone threshold */
|
|
167
141
|
deadZone: number;
|
|
142
|
+
/** Dominant axis mode */
|
|
168
143
|
dominant: boolean;
|
|
169
|
-
|
|
144
|
+
/** Lock translation to zero */
|
|
170
145
|
lockPosition: boolean;
|
|
146
|
+
/** Lock rotation to zero */
|
|
171
147
|
lockRotation: boolean;
|
|
172
|
-
/**
|
|
173
|
-
actionMap: ActionMap;
|
|
174
|
-
/**
|
|
175
|
-
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
176
|
-
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
177
|
-
* Values override global defaults for matching devices.
|
|
178
|
-
*/
|
|
148
|
+
/** Per-device overrides keyed by device ID or pattern (e.g., "cnx-*") */
|
|
179
149
|
devices: Record<string, DeviceConfig>;
|
|
180
150
|
}
|
|
181
151
|
|
|
@@ -185,36 +155,17 @@ interface StorageAdapter {
|
|
|
185
155
|
}
|
|
186
156
|
|
|
187
157
|
interface InputManagerEvents {
|
|
188
|
-
/** Processed spatial data (after all transforms + action map) */
|
|
189
158
|
spatialData: (data: SpatialData) => void;
|
|
190
|
-
/** Named action values from the action map */
|
|
191
|
-
actionValues: (values: ActionValues) => void;
|
|
192
|
-
/** Raw spatial data (before transforms) */
|
|
193
159
|
rawSpatialData: (data: SpatialData) => void;
|
|
194
|
-
/** Button event (pass-through from connection) */
|
|
195
160
|
buttonEvent: (data: ButtonEvent) => void;
|
|
196
|
-
/** Connection state changed */
|
|
197
161
|
stateChange: (state: ConnectionState, protocol: TransportProtocol) => void;
|
|
198
|
-
/** Device connected/disconnected */
|
|
199
162
|
deviceStatus: (event: "connected" | "disconnected", device: DeviceInfo$1) => void;
|
|
200
|
-
/** Configuration changed */
|
|
201
163
|
configChange: (config: InputConfig) => void;
|
|
202
164
|
}
|
|
203
|
-
/** A connected device paired with its resolved configuration */
|
|
204
165
|
interface DeviceWithConfig {
|
|
205
166
|
device: DeviceInfo$1;
|
|
206
167
|
config: DeviceConfig;
|
|
207
168
|
}
|
|
208
|
-
/**
|
|
209
|
-
* Unified device service that wraps one or more SatMouseConnections
|
|
210
|
-
* and provides a single processed event stream.
|
|
211
|
-
*
|
|
212
|
-
* Applies a configurable transform pipeline per-device:
|
|
213
|
-
* deadZone → dominant → flip → axisRemap → sensitivity → lock
|
|
214
|
-
*
|
|
215
|
-
* Per-device overrides are resolved from InputConfig.devices using
|
|
216
|
-
* device ID matching (exact or pattern with wildcard "*").
|
|
217
|
-
*/
|
|
218
169
|
declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
219
170
|
private connections;
|
|
220
171
|
private storage?;
|
|
@@ -225,36 +176,25 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
225
176
|
private _config;
|
|
226
177
|
get config(): InputConfig;
|
|
227
178
|
constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
|
|
228
|
-
/** Add a connection to the managed set */
|
|
229
179
|
addConnection(connection: SatMouseConnection): void;
|
|
230
|
-
/** Remove a connection */
|
|
231
180
|
removeConnection(connection: SatMouseConnection): void;
|
|
232
|
-
/** Connect all managed connections */
|
|
233
181
|
connect(): Promise<void>;
|
|
234
|
-
/** Disconnect all managed connections */
|
|
235
182
|
disconnect(): void;
|
|
236
|
-
/** Fetch device info from all connections */
|
|
237
183
|
fetchDeviceInfo(): Promise<DeviceInfo$1[]>;
|
|
238
|
-
/** Get all known connected devices paired with their resolved config */
|
|
239
184
|
getDevicesWithConfig(): DeviceWithConfig[];
|
|
240
|
-
/** Get the resolved per-device config (global defaults + device overrides) */
|
|
241
185
|
getDeviceConfig(deviceId: string): DeviceConfig;
|
|
242
|
-
/** Update global configuration. Persists by default. */
|
|
243
186
|
updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
|
|
244
|
-
/** Update configuration for a specific device. Persists by default. */
|
|
245
187
|
updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
|
|
246
|
-
|
|
188
|
+
resetDeviceConfig(deviceId: string, persist?: boolean): void;
|
|
189
|
+
resetAllConfig(): void;
|
|
247
190
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
248
|
-
/** Register a callback for button events. Returns unsubscribe function. */
|
|
249
191
|
onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
|
|
250
|
-
/** Register a callback for action values. Returns unsubscribe function. */
|
|
251
|
-
onActionValues(callback: (values: ActionValues) => void): () => void;
|
|
252
192
|
private wireConnection;
|
|
253
193
|
private flushAccumulator;
|
|
254
|
-
/** Per-device
|
|
194
|
+
/** Per-device: deadZone → dominant → routes (flip + scale + remap in one pass) */
|
|
255
195
|
private processPerDevice;
|
|
256
|
-
/**
|
|
257
|
-
private
|
|
196
|
+
/** Get the effective routes for a device: device config override > device axes metadata > global default */
|
|
197
|
+
private resolveRoutes;
|
|
258
198
|
}
|
|
259
199
|
|
|
260
200
|
interface SatMouseContextValue {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -40,6 +40,12 @@ interface DeviceInfo$1 {
|
|
|
40
40
|
productId?: number;
|
|
41
41
|
connectionType?: "usb" | "wireless" | "bluetooth" | "unknown";
|
|
42
42
|
connected?: boolean;
|
|
43
|
+
/** Axes this device provides (e.g., ["tx","ty","tz","rx","ry","rz"] or ["tx","ty","rx","ry","tz+","rz+"]) */
|
|
44
|
+
axes?: string[];
|
|
45
|
+
/** Human-readable labels for axes (same order as axes array) */
|
|
46
|
+
axisLabels?: string[];
|
|
47
|
+
/** Number of buttons this device provides */
|
|
48
|
+
buttonCount?: number;
|
|
43
49
|
}
|
|
44
50
|
type ConnectionState = "disconnected" | "connecting" | "connected" | "failed";
|
|
45
51
|
type TransportProtocol = "webtransport" | "websocket" | "none";
|
|
@@ -104,78 +110,42 @@ declare class SatMouseConnection extends TypedEmitter<SatMouseEvents> {
|
|
|
104
110
|
private clearReconnect;
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
rx: boolean;
|
|
112
|
-
ry: boolean;
|
|
113
|
-
rz: boolean;
|
|
114
|
-
}
|
|
115
|
-
interface SensitivityConfig {
|
|
116
|
-
translation: number;
|
|
117
|
-
rotation: number;
|
|
118
|
-
}
|
|
119
|
-
/** Maps each input axis to an output axis. E.g., { tx: "tz", tz: "tx" } swaps X and Z translation. */
|
|
120
|
-
type AxisMap = {
|
|
121
|
-
tx: keyof Vec3;
|
|
122
|
-
ty: keyof Vec3;
|
|
123
|
-
tz: keyof Vec3;
|
|
124
|
-
rx: keyof Vec3;
|
|
125
|
-
ry: keyof Vec3;
|
|
126
|
-
rz: keyof Vec3;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
/** Input axis identifier */
|
|
130
|
-
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
|
|
131
|
-
/** A single action binding — maps one input axis to a named output */
|
|
132
|
-
interface ActionBinding {
|
|
133
|
-
/** Which input axis drives this action */
|
|
113
|
+
/** Axis identifier — full or half */
|
|
114
|
+
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz" | "tx+" | "ty+" | "tz+" | "rx+" | "ry+" | "rz+" | "tx-" | "ty-" | "tz-" | "rx-" | "ry-" | "rz-";
|
|
115
|
+
/** A single axis route — reads from source, writes to target */
|
|
116
|
+
interface AxisRoute {
|
|
134
117
|
source: InputAxis;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
invert?: boolean;
|
|
118
|
+
target: InputAxis;
|
|
119
|
+
/** Negate the value (default: false) */
|
|
120
|
+
flip?: boolean;
|
|
139
121
|
}
|
|
140
|
-
/**
|
|
141
|
-
* ActionMap defines how raw 6DOF axes map to named output actions.
|
|
142
|
-
*
|
|
143
|
-
* Client apps declare the actions they support and how device axes
|
|
144
|
-
* feed into them. Users can reassign axes via the settings UI.
|
|
145
|
-
*
|
|
146
|
-
* Default: 6 actions matching the 6 input axes (passthrough).
|
|
147
|
-
*/
|
|
148
|
-
type ActionMap = Record<string, ActionBinding>;
|
|
149
|
-
/** Result of applying an ActionMap to spatial data */
|
|
150
|
-
type ActionValues = Record<string, number>;
|
|
151
122
|
|
|
152
|
-
/** Per-device
|
|
123
|
+
/** Per-device configuration */
|
|
153
124
|
interface DeviceConfig {
|
|
154
|
-
|
|
155
|
-
|
|
125
|
+
/** Axis routing — each entry maps a device input to an output with optional flip */
|
|
126
|
+
routes?: AxisRoute[];
|
|
127
|
+
/** Scale multiplier applied to all axes (default: 1) */
|
|
128
|
+
scale?: number;
|
|
129
|
+
/** Dead zone threshold (0-1). Values below this are zeroed. */
|
|
156
130
|
deadZone?: number;
|
|
131
|
+
/** Only pass the strongest axis, zero all others */
|
|
157
132
|
dominant?: boolean;
|
|
158
|
-
axisRemap?: Partial<AxisMap>;
|
|
159
|
-
actionMap?: ActionMap;
|
|
160
|
-
lockPosition?: boolean;
|
|
161
|
-
lockRotation?: boolean;
|
|
162
133
|
}
|
|
134
|
+
/** Global configuration */
|
|
163
135
|
interface InputConfig {
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
|
|
136
|
+
/** Default axis routes (used when device has no override) */
|
|
137
|
+
routes: AxisRoute[];
|
|
138
|
+
/** Default scale */
|
|
139
|
+
scale: number;
|
|
140
|
+
/** Dead zone threshold */
|
|
167
141
|
deadZone: number;
|
|
142
|
+
/** Dominant axis mode */
|
|
168
143
|
dominant: boolean;
|
|
169
|
-
|
|
144
|
+
/** Lock translation to zero */
|
|
170
145
|
lockPosition: boolean;
|
|
146
|
+
/** Lock rotation to zero */
|
|
171
147
|
lockRotation: boolean;
|
|
172
|
-
/**
|
|
173
|
-
actionMap: ActionMap;
|
|
174
|
-
/**
|
|
175
|
-
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
176
|
-
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
177
|
-
* Values override global defaults for matching devices.
|
|
178
|
-
*/
|
|
148
|
+
/** Per-device overrides keyed by device ID or pattern (e.g., "cnx-*") */
|
|
179
149
|
devices: Record<string, DeviceConfig>;
|
|
180
150
|
}
|
|
181
151
|
|
|
@@ -185,36 +155,17 @@ interface StorageAdapter {
|
|
|
185
155
|
}
|
|
186
156
|
|
|
187
157
|
interface InputManagerEvents {
|
|
188
|
-
/** Processed spatial data (after all transforms + action map) */
|
|
189
158
|
spatialData: (data: SpatialData) => void;
|
|
190
|
-
/** Named action values from the action map */
|
|
191
|
-
actionValues: (values: ActionValues) => void;
|
|
192
|
-
/** Raw spatial data (before transforms) */
|
|
193
159
|
rawSpatialData: (data: SpatialData) => void;
|
|
194
|
-
/** Button event (pass-through from connection) */
|
|
195
160
|
buttonEvent: (data: ButtonEvent) => void;
|
|
196
|
-
/** Connection state changed */
|
|
197
161
|
stateChange: (state: ConnectionState, protocol: TransportProtocol) => void;
|
|
198
|
-
/** Device connected/disconnected */
|
|
199
162
|
deviceStatus: (event: "connected" | "disconnected", device: DeviceInfo$1) => void;
|
|
200
|
-
/** Configuration changed */
|
|
201
163
|
configChange: (config: InputConfig) => void;
|
|
202
164
|
}
|
|
203
|
-
/** A connected device paired with its resolved configuration */
|
|
204
165
|
interface DeviceWithConfig {
|
|
205
166
|
device: DeviceInfo$1;
|
|
206
167
|
config: DeviceConfig;
|
|
207
168
|
}
|
|
208
|
-
/**
|
|
209
|
-
* Unified device service that wraps one or more SatMouseConnections
|
|
210
|
-
* and provides a single processed event stream.
|
|
211
|
-
*
|
|
212
|
-
* Applies a configurable transform pipeline per-device:
|
|
213
|
-
* deadZone → dominant → flip → axisRemap → sensitivity → lock
|
|
214
|
-
*
|
|
215
|
-
* Per-device overrides are resolved from InputConfig.devices using
|
|
216
|
-
* device ID matching (exact or pattern with wildcard "*").
|
|
217
|
-
*/
|
|
218
169
|
declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
219
170
|
private connections;
|
|
220
171
|
private storage?;
|
|
@@ -225,36 +176,25 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
225
176
|
private _config;
|
|
226
177
|
get config(): InputConfig;
|
|
227
178
|
constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
|
|
228
|
-
/** Add a connection to the managed set */
|
|
229
179
|
addConnection(connection: SatMouseConnection): void;
|
|
230
|
-
/** Remove a connection */
|
|
231
180
|
removeConnection(connection: SatMouseConnection): void;
|
|
232
|
-
/** Connect all managed connections */
|
|
233
181
|
connect(): Promise<void>;
|
|
234
|
-
/** Disconnect all managed connections */
|
|
235
182
|
disconnect(): void;
|
|
236
|
-
/** Fetch device info from all connections */
|
|
237
183
|
fetchDeviceInfo(): Promise<DeviceInfo$1[]>;
|
|
238
|
-
/** Get all known connected devices paired with their resolved config */
|
|
239
184
|
getDevicesWithConfig(): DeviceWithConfig[];
|
|
240
|
-
/** Get the resolved per-device config (global defaults + device overrides) */
|
|
241
185
|
getDeviceConfig(deviceId: string): DeviceConfig;
|
|
242
|
-
/** Update global configuration. Persists by default. */
|
|
243
186
|
updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
|
|
244
|
-
/** Update configuration for a specific device. Persists by default. */
|
|
245
187
|
updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
|
|
246
|
-
|
|
188
|
+
resetDeviceConfig(deviceId: string, persist?: boolean): void;
|
|
189
|
+
resetAllConfig(): void;
|
|
247
190
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
248
|
-
/** Register a callback for button events. Returns unsubscribe function. */
|
|
249
191
|
onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
|
|
250
|
-
/** Register a callback for action values. Returns unsubscribe function. */
|
|
251
|
-
onActionValues(callback: (values: ActionValues) => void): () => void;
|
|
252
192
|
private wireConnection;
|
|
253
193
|
private flushAccumulator;
|
|
254
|
-
/** Per-device
|
|
194
|
+
/** Per-device: deadZone → dominant → routes (flip + scale + remap in one pass) */
|
|
255
195
|
private processPerDevice;
|
|
256
|
-
/**
|
|
257
|
-
private
|
|
196
|
+
/** Get the effective routes for a device: device config override > device axes metadata > global default */
|
|
197
|
+
private resolveRoutes;
|
|
258
198
|
}
|
|
259
199
|
|
|
260
200
|
interface SatMouseContextValue {
|