spacenav-ws 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

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.
@@ -0,0 +1,16 @@
1
+ [ req ]
2
+ default_bits = 2048
3
+ distinguished_name = dn
4
+ req_extensions = req_ext
5
+ prompt = no
6
+
7
+ [ dn ]
8
+ # Use the IP as the “common name”
9
+ CN = 127.51.68.120
10
+
11
+ [ req_ext ]
12
+ subjectAltName = @alt_names
13
+
14
+ [ alt_names ]
15
+ # Tell OpenSSL this cert is valid for this IP
16
+ IP.1 = 127.51.68.120
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC8DCCAdigAwIBAgIUNsNCA02p2ELrmS+rvcI/otubVFwwDQYJKoZIhvcNAQEL
3
+ BQAwGDEWMBQGA1UEAwwNMTI3LjUxLjY4LjEyMDAeFw0yNTA0MjAxMTA1MDNaFw0z
4
+ NTA0MTgxMTA1MDNaMBgxFjAUBgNVBAMMDTEyNy41MS42OC4xMjAwggEiMA0GCSqG
5
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ5STIxYG9rrvueEvSx0iC3PxJR2uygu0v
6
+ BC7BziExnUleqO4RobAFgjuwN/rqiuGruuh5ptoZjfQRMRkNMXI2ZBnnoJXmP0oK
7
+ Ppqdr+8/t9YgqnClT+AUCRJ2DlTW7qA+ZBzDERWR6iAXhPMi6Cbcz9zAK/Tdqh2O
8
+ HbuDNqOB156fr8inx8FMgVWPfW0zkMvJ9og/pmV+BlMWJveXCgHcmpBCOJrknk67
9
+ 1/0gtO58T9AygSeg9yQzd5Mwh3ZIPYxR4Qx30KVG5br3zisqcD+Af+z5wcrPqXLJ
10
+ nDkTjO1y5r6Vft0vLN1SIW6xA6uqwLJ7vxdbjpsvQaF6Om4nU57NAgMBAAGjMjAw
11
+ MA8GA1UdEQQIMAaHBH8zRHgwHQYDVR0OBBYEFFwJpwEPR1TnqW86nrGyHYGhsTu0
12
+ MA0GCSqGSIb3DQEBCwUAA4IBAQC3bRa7pjwDtWsWpQJMAHXFABeuyWlUZPOpYFCv
13
+ t1W3vkjUtp921iQEkv5DCeZxYn41deSAgT1GIgKOslLlGwfZlzTOdqoZ8CnJqFZr
14
+ Ce5FZwgA7Mwm6osieppLVObWchD2HKu7vEejxgB0QnSXBTR4MM1TMO7IX180q4C/
15
+ 2KH7amqvfqAIIi+JuyueAhqPAiEdZpwzZv6CZLk1CFW1UmkZab7Ry8d+J06IFqmb
16
+ KxkIGLtSbEPgIofIYhuSGU2ItVhIO4cOjAO4aOyxuPy1gjgIXkmq0EZjtJdCXRi/
17
+ PJuq8suX/69PB3fFmjCay7Q63FEDrALyDQpFWJ5C1D+6+02G
18
+ -----END CERTIFICATE-----
@@ -0,0 +1,16 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIICfzCCAWcCAQAwGDEWMBQGA1UEAwwNMTI3LjUxLjY4LjEyMDCCASIwDQYJKoZI
3
+ hvcNAQEBBQADggEPADCCAQoCggEBAMnlJMjFgb2uu+54S9LHSILc/ElHa7KC7S8E
4
+ LsHOITGdSV6o7hGhsAWCO7A3+uqK4au66Hmm2hmN9BExGQ0xcjZkGeegleY/Sgo+
5
+ mp2v7z+31iCqcKVP4BQJEnYOVNbuoD5kHMMRFZHqIBeE8yLoJtzP3MAr9N2qHY4d
6
+ u4M2o4HXnp+vyKfHwUyBVY99bTOQy8n2iD+mZX4GUxYm95cKAdyakEI4muSeTrvX
7
+ /SC07nxP0DKBJ6D3JDN3kzCHdkg9jFHhDHfQpUbluvfOKypwP4B/7PnBys+pcsmc
8
+ OROM7XLmvpV+3S8s3VIhbrEDq6rAsnu/F1uOmy9BoXo6bidTns0CAwEAAaAiMCAG
9
+ CSqGSIb3DQEJDjETMBEwDwYDVR0RBAgwBocEfzNEeDANBgkqhkiG9w0BAQsFAAOC
10
+ AQEAlGZa1JHp9z8leCWU1tUGreQOkOy0O+wviMH3rud/6fwnCrf5//zePeU+W84c
11
+ +b2yh1nCBPY13q1yqlFOHi2oSt5fkIr1gTUMcchvKWkrKeSZr8RXYngBCPbqA281
12
+ vqZ9uqAD3pOYsL993rYJP/k6zu6KVE3NGwqoY+6zciy+F5b6pdy4zsgRkft46lvJ
13
+ e+N2A/CGyEx2KAF7+uMcr4VB8ZVZNWFl6M2okEgnQrHzPGArS5Txjiwivm0oGl67
14
+ aMqiPe4eU62hYcDSJo5YgxzBTbMTTX8XReoolkWGMrY8DDdH0XIm55Z0rAe1Iw/A
15
+ DBOYonshUw88zO6jGXGvhWlcDw==
16
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJ5STIxYG9rrvu
3
+ eEvSx0iC3PxJR2uygu0vBC7BziExnUleqO4RobAFgjuwN/rqiuGruuh5ptoZjfQR
4
+ MRkNMXI2ZBnnoJXmP0oKPpqdr+8/t9YgqnClT+AUCRJ2DlTW7qA+ZBzDERWR6iAX
5
+ hPMi6Cbcz9zAK/Tdqh2OHbuDNqOB156fr8inx8FMgVWPfW0zkMvJ9og/pmV+BlMW
6
+ JveXCgHcmpBCOJrknk671/0gtO58T9AygSeg9yQzd5Mwh3ZIPYxR4Qx30KVG5br3
7
+ zisqcD+Af+z5wcrPqXLJnDkTjO1y5r6Vft0vLN1SIW6xA6uqwLJ7vxdbjpsvQaF6
8
+ Om4nU57NAgMBAAECggEAEUlCjUMl4OMDWb9ohI9GBNhdbHvGO5ZMrwQdacAXpPsZ
9
+ 01ZE7fMJUmtsZ2HfpLHH8S9zZKkVzu7RySAKTFAhvojzE9sywnBES1zBWcN8yViY
10
+ 55qYQvs0DRsavstq1a1AQJ9LPCNsFJ52aXUbaS911l2gwb5xvIHqfmbKzYkB1mXE
11
+ EXuRu4YOdT+EZRHbQwG2mfKXCN4H5/gp89hH8id3jCZuFZ2eCeMaEUIq4Wtoa3r4
12
+ S2kUwQxjDwv/QJQb3Ym9NfzxWsNFtnqt6Np4wdtlt75IOgcqqjhTBUUOsDKwKZRv
13
+ Q+/GgAunmigCWes/KJ4OPFY3OlyJlDf+yHksIyolAQKBgQDoDy9FW5JiXhwnXXwY
14
+ ndMbH8V6rC2aHf0NF9MW4PuzAr0SVrm6Er7W0+gMlahfY2NmHhA+IdTwT7q4voCX
15
+ pGU4KmQk9+h+lmD+FmLvDU5Rox5oCknlVcb69bSS6Y2sBGeV0f9MR/aLiu+4K/mz
16
+ MhFRAiWDJ9rG8WG86XC5kx+DAQKBgQDeuU4f0DRShPZkCZhKv4J3jKF9pmb6TEoy
17
+ ruwVnRHv7YSnZnNokdujXjEa7xvw7cT+ytK+CP+vLSdEDvDZET5LnMnAW4Fu0Z9l
18
+ 3YMc+/JIyMVauGgdEozEMhyv8yoRQNjKvcVTb1H7mwbCSD4IrHT9kPvV8M683B0B
19
+ F7IxenK3zQKBgDnVVvWVHcVQKPoSjVPhOXSAFYo+ENtg7+jscBo6leAGJbLFVGIw
20
+ O8l0ZFeGkMC9F0+i3G9vpQ8C/8j9CTVBrkwyHGUuN44c0i1gzOVAzqz/1xscvU/f
21
+ ccinpYoblMgzDNHE1ThgkuwyAw5GP2PObYxf2ZN3QknkbHRVRVeqd+cBAoGBAJML
22
+ PGz8hM7GQfWh8A3JilVrX2MZbXtqysHTgsJyRNlmsuHiXed4BM5C7aCepI/YKusc
23
+ 9S3JuyToZrgkNRbar4o0JW79+uIzO02BhYKpRDiRdNqETRiEmrMdcpsnq2pgqcCQ
24
+ sap4IGRA4aF7GJmZYlPWWK3SomtF11BVWKwZ74sxAoGAEKRY2TEK6TD0/IV7pKqG
25
+ z8Qq2UaCtOh9HT5GJw+tqWmeJi6VNHppLasHkIeoZtbouLvaFnzNz0TRMT8E85uv
26
+ iyqnsyRe8lc/kUTERRRI2y6fvZ78sASN3c89koszEqIQ4RUO1StvGGK+NOkhTUs8
27
+ GyIe849AyjalPUqs6chYWks=
28
+ -----END PRIVATE KEY-----
spacenav_ws/controller.py CHANGED
@@ -7,8 +7,8 @@ from typing import Any
7
7
  import numpy as np
8
8
  from scipy.spatial import transform
9
9
 
10
- import spacenav_ws.spacenav
11
- import spacenav_ws.wamp
10
+ from spacenav_ws.spacenav import MotionEvent, ButtonEvent, from_message
11
+ from spacenav_ws.wamp import WampSession, Prefix, Call, Subscribe, CallResult
12
12
 
13
13
 
14
14
  class Mouse3d:
@@ -44,8 +44,9 @@ class Controller:
44
44
  def __post_init__(self):
45
45
  self.affine = np.asarray(self.affine).reshape([4, 4])
46
46
 
47
- def __init__(self, reader: asyncio.StreamReader, mouse: Mouse3d, wamp_state_handler: spacenav_ws.wamp.WampSession):
47
+ def __init__(self, reader: asyncio.StreamReader, mouse: Mouse3d, wamp_state_handler: WampSession, client_metadata: dict):
48
48
  self.id = "controller0"
49
+ self.client_metadata = client_metadata
49
50
  self.reader = reader
50
51
  self._mouse = mouse
51
52
  self.wamp_state_handler = wamp_state_handler
@@ -57,9 +58,9 @@ class Controller:
57
58
  self.coordinate_system = None
58
59
  self.subscribed = False
59
60
 
60
- async def subscribe(self):
61
+ async def subscribe(self, msg: Subscribe):
61
62
  """When a subscription request for self.controller_uri comes in we start broadcasting!"""
62
- # await self.initialize()
63
+ logging.info("handling subscribe %s", msg)
63
64
  self.subscribed = True
64
65
 
65
66
  async def client_update(self, controller_id: str, args: dict[str, Any]):
@@ -82,20 +83,25 @@ class Controller:
82
83
  while True:
83
84
  mouse_event = await self.reader.read(32)
84
85
  nums = struct.unpack("iiiiiiii", mouse_event)
85
- event = spacenav_ws.spacenav.from_message(list(nums))
86
- if isinstance(event, spacenav_ws.spacenav.ButtonEvent):
86
+ event = from_message(list(nums))
87
+ if isinstance(event, ButtonEvent):
87
88
  logging.warning("Button presses are discarded for now! %s", event)
88
- elif isinstance(event, spacenav_ws.spacenav.MotionEvent):
89
+ elif isinstance(event, MotionEvent):
89
90
  if self.subscribed:
90
- await self.send_mouse_event_to_client(event)
91
-
92
- async def send_mouse_event_to_client(self, event: spacenav_ws.spacenav.MotionEvent):
91
+ if self.client_metadata["name"] == "Onshape":
92
+ await self.update_onshape_client(event)
93
+ elif self.client_metadata["name"] == "WebThreeJS Sample":
94
+ await self.update_3dconnexion_client(event)
95
+ else:
96
+ logging.warning("Unknown client! Cannot send mouse events, client_metadata:%s", self.client_metadata)
97
+
98
+ async def update_onshape_client(self, event: MotionEvent):
93
99
  # 1) pull down the current extents and model matrix
94
100
  extents = await self.remote_read("view.extents")
95
101
  flat = await self.remote_read("view.affine")
96
102
  curr_affine = np.asarray(flat, dtype=np.float32).reshape(4, 4)
97
103
 
98
- # TODO:
104
+ # TODO: This is not correct
99
105
  # 2) Handle rotation
100
106
  angles = np.array([event.pitch, event.yaw, -event.roll], dtype=np.float32) * 0.008
101
107
  rot_cam = transform.Rotation.from_euler("xyz", angles, degrees=True).as_matrix()
@@ -125,29 +131,59 @@ class Controller:
125
131
  await self.remote_write("view.affine", new_affine.reshape(-1).tolist())
126
132
  await self.remote_write("view.extents", new_extents)
127
133
 
134
+ async def update_3dconnexion_client(self, event: MotionEvent):
135
+ # 1) pull down the current extents and model matrix
136
+ flat = await self.remote_read("view.affine")
137
+ curr_affine = np.asarray(flat, dtype=np.float32).reshape(4, 4)
138
+
139
+ # 2) Handle rotation
140
+ # Rotate the model in the cameras perspective
141
+ # angles = np.array([event.pitch, event.yaw, -event.roll], dtype=np.float32) * 0.008
142
+ # rot_cam = transform.Rotation.from_euler("xyz", angles, degrees=True).as_matrix()
143
+ # rot_delta = np.eye(4, dtype=np.float32)
144
+ # rot_delta[:3, :3] = rot_cam
145
+ # rotated = rot_delta @ curr_affine
146
+
147
+ # Rotate the model from _its_ perspective
148
+ angles = np.array([event.pitch, event.yaw, -event.roll], dtype=np.float32) * 0.008
149
+ rot_cam = transform.Rotation.from_euler("xyz", angles, degrees=True).as_matrix()
150
+ rot_delta = np.eye(4, dtype=np.float32)
151
+ rot_delta[:3, :3] = rot_cam
152
+ rotated = curr_affine @ rot_delta
153
+
154
+ # 3) Handle translations
155
+ trans_delta = np.eye(4, dtype=np.float32)
156
+ # Probably event.y doesn't do anything at all here!
157
+ trans_delta[3, :3] = np.array([-event.x, -event.z, event.y], dtype=np.float32) * 0.001
158
+ new_affine = trans_delta @ rotated
159
+
160
+ # Write back changes
161
+ await self.remote_write("motion", True)
162
+ await self.remote_write("view.affine", new_affine.reshape(-1).tolist())
163
+
128
164
 
129
- async def create_mouse_controller(wamp_state_handler: spacenav_ws.wamp.WampSession, spacenav_reader: asyncio.StreamReader):
165
+ async def create_mouse_controller(wamp_state_handler: WampSession, spacenav_reader: asyncio.StreamReader):
130
166
  await wamp_state_handler.wamp.begin()
131
167
  # The first three messages are typically prefix setters!
132
168
  msg = await wamp_state_handler.wamp.next_message()
133
- while isinstance(msg, spacenav_ws.wamp.Prefix):
169
+ while isinstance(msg, Prefix):
134
170
  await wamp_state_handler.wamp.run_message_handler(msg)
135
171
  msg = await wamp_state_handler.wamp.next_message()
136
172
 
137
173
  # The first call after the prefixes must be 'create mouse'
138
- assert isinstance(msg, spacenav_ws.wamp.Call)
174
+ assert isinstance(msg, Call)
139
175
  assert msg.proc_uri == "3dx_rpc:create" and msg.args[0] == "3dconnexion:3dmouse"
140
176
  mouse = Mouse3d()
141
177
  logging.info(f'Created 3d mouse "{mouse.id}" for version {msg.args[1]}')
142
- await wamp_state_handler.wamp.send_message(spacenav_ws.wamp.CallResult(msg.call_id, {"connexion": mouse.id}))
178
+ await wamp_state_handler.wamp.send_message(CallResult(msg.call_id, {"connexion": mouse.id}))
143
179
 
144
180
  # And the second call after the prefixes must be 'create controller'
145
181
  msg = await wamp_state_handler.wamp.next_message()
146
- assert isinstance(msg, spacenav_ws.wamp.Call)
182
+ assert isinstance(msg, Call)
147
183
  assert msg.proc_uri == "3dx_rpc:create" and msg.args[0] == "3dconnexion:3dcontroller" and msg.args[1] == mouse.id
148
184
  metadata = msg.args[2]
149
- ctrl = Controller(spacenav_reader, mouse, wamp_state_handler)
185
+ ctrl = Controller(spacenav_reader, mouse, wamp_state_handler, metadata)
150
186
  logging.info(f'Created controller "{ctrl.id}" for mouse "{mouse.id}", for client "{metadata["name"]}", version "{metadata["version"]}"')
151
187
 
152
- await wamp_state_handler.wamp.send_message(spacenav_ws.wamp.CallResult(msg.call_id, {"instance": ctrl.id}))
188
+ await wamp_state_handler.wamp.send_message(CallResult(msg.call_id, {"instance": ctrl.id}))
153
189
  return ctrl
spacenav_ws/main.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  import struct
4
+ from pathlib import Path
4
5
 
5
6
  import typer
6
7
  import uvicorn
@@ -22,8 +23,8 @@ ORIGINS = [
22
23
  "https://cad.onshape.com",
23
24
  ]
24
25
 
25
- CERT_FILE = "certs/ip.crt"
26
- KEY_FILE = "certs/ip.key"
26
+ CERT_FILE = Path(__file__).parent / "certs" / "ip.crt"
27
+ KEY_FILE = Path(__file__).parent / "certs" / "ip.key"
27
28
 
28
29
  cli = typer.Typer()
29
30
  app = FastAPI()
@@ -102,7 +103,7 @@ async def read_mouse_stream():
102
103
  logging.info("Start moving your mouse!")
103
104
  async for event in get_mouse_event_generator():
104
105
  logging.info(event.strip())
105
-
106
+
106
107
 
107
108
  @cli.command()
108
109
  def read_mouse():
spacenav_ws/spacenav.py CHANGED
@@ -17,9 +17,9 @@ def get_sync_spacenav_socket():
17
17
  async def get_async_spacenav_socket_reader() -> tuple[asyncio.StreamReader, asyncio.StreamWriter]:
18
18
  try:
19
19
  return await asyncio.open_unix_connection(SPACENAV_SOCKET_PATH)
20
- except FileNotFoundError as e:
20
+ except (FileNotFoundError, ConnectionRefusedError):
21
21
  logging.exception("Space mouse not found!")
22
- raise RuntimeError from e
22
+ exit(1)
23
23
 
24
24
 
25
25
  @dataclass
spacenav_ws/wamp.py CHANGED
@@ -5,7 +5,8 @@ import logging
5
5
  import random
6
6
  import string
7
7
  from enum import IntEnum
8
- from typing import Any, ClassVar, Dict, NamedTuple, Optional, Type
8
+ from types import CoroutineType
9
+ from typing import Any, ClassVar, Dict, NamedTuple, Optional, Type, Callable
9
10
 
10
11
  from fastapi import WebSocket
11
12
 
@@ -102,8 +103,8 @@ class WampProtocol:
102
103
  self._session_id = _rand_id(16)
103
104
 
104
105
  self.prefixes = {}
105
- self.call_handlers = {}
106
- self.subscribe_handlers = {}
106
+ self.call_handlers: dict[str, Callable[..., CoroutineType[Any, Any, None]]] = {}
107
+ self.subscribe_handlers: dict[str, Callable[[Subscribe], CoroutineType[Any, Any, None]]] = {}
107
108
 
108
109
  async def begin(self):
109
110
  await self._socket.accept(subprotocol="wamp")
@@ -148,7 +149,7 @@ class WampProtocol:
148
149
  logging.warning("Unknown subscribable: %s", topic)
149
150
  else:
150
151
  logging.debug(f"handle subscribe to '{topic}' by calling: {handler}")
151
- await handler()
152
+ await handler(msg)
152
153
 
153
154
  async def handle_callresult(self, msg: CallResult):
154
155
  logging.warning("No callresult handler for msg: %s", msg)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spacenav-ws
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: SpaceNav WebSocket Bridge for using a 3dConnexion spacemouse with onshape
5
5
  Author-email: RmStorm <roaldstorm@gmail.com>
6
6
  License-File: LICENSE
@@ -28,4 +28,9 @@ Simply run `uvx spacenav-ws`
28
28
  todo
29
29
 
30
30
  # Deploying to pypi
31
- todo
31
+ Just run
32
+
33
+ ```bash
34
+ uv build
35
+ uv publish
36
+ ```
@@ -0,0 +1,14 @@
1
+ spacenav_ws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ spacenav_ws/controller.py,sha256=hrMNZ-MbbngD0gYV5OrCSAYEAOm7DOlwehlXHuJaU9w,8448
3
+ spacenav_ws/main.py,sha256=SrDCSuyoPiFRC-7uIxLzcx_FkdsSzJC6vXBEJpqIn_c,3796
4
+ spacenav_ws/spacenav.py,sha256=DeoCa-J35e7CXBqEMaWtScTVu9uJ3mbGt0dnDH3Df9k,1376
5
+ spacenav_ws/wamp.py,sha256=bFdRmyCofd51fsywNGW5Qv21JCea27K2LOIRZYHtS8c,7979
6
+ spacenav_ws/certs/ip.cnf,sha256=0iqBE5mEYouB9vB3EiEF4JCJV-Code6ByGdTvQo9m_4,299
7
+ spacenav_ws/certs/ip.crt,sha256=BsvZSE5dovQwTqC3SzhjUdHKT5LWb12HrgR3qe-x0dU,1078
8
+ spacenav_ws/certs/ip.csr,sha256=JdBTVIBq_IIo05MU_sGXZvlJX7VLUCPvSLPQgfHBUNU,944
9
+ spacenav_ws/certs/ip.key,sha256=8V78lQyBt7HRu7glxm-9RhiG4CoakYiCEDXhv-0x1jc,1704
10
+ spacenav_ws-0.1.2.dist-info/METADATA,sha256=qALEw8-jTYVzDSM2BP6q20he8Cfl7yLnMT6f0kF0VxI,816
11
+ spacenav_ws-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ spacenav_ws-0.1.2.dist-info/entry_points.txt,sha256=3V0mY2nK5u51q0YI8jKqR8hF6KKR3ev7bGJbEayc250,53
13
+ spacenav_ws-0.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ spacenav_ws-0.1.2.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- spacenav_ws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- spacenav_ws/controller.py,sha256=2_xZF_WvYHO7EKEafyQcheLipUGBMABiSgZTAwnMAX4,6614
3
- spacenav_ws/main.py,sha256=OvUeznzw6pS1ff2qHD4H_fMjXAjzAEegskN_FPCQZGI,3711
4
- spacenav_ws/spacenav.py,sha256=2Y8Gbxo__Xcc2dQeUzF2Shgrm-n35tUbK3KrrDmV4AY,1373
5
- spacenav_ws/wamp.py,sha256=900OpbQCHluoiH4ThhDQTVf6UhWl898bA2WKHTEq55w,7812
6
- spacenav_ws-0.1.0.dist-info/METADATA,sha256=VzpfugdgfRhaaeSFhRjOy-swobsYZXJ-nZsX4H01bDM,779
7
- spacenav_ws-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
- spacenav_ws-0.1.0.dist-info/entry_points.txt,sha256=3V0mY2nK5u51q0YI8jKqR8hF6KKR3ev7bGJbEayc250,53
9
- spacenav_ws-0.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
10
- spacenav_ws-0.1.0.dist-info/RECORD,,