qlsdk2 0.6.0a11__py3-none-any.whl → 0.6.0a12__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.
@@ -56,19 +56,13 @@ class RscPacket(Packet):
56
56
  return packet
57
57
 
58
58
  def __str__(self):
59
- return f"""
60
- time_stamp: {self.time_stamp}
61
- pkg_id: {self.pkg_id}
62
- origin_sample_rate: {self.origin_sample_rate}
63
- sample_rate: {self.sample_rate}
64
- sample_num: {self.sample_num}
65
- resolution: {self.resolution}
66
- filter: {self.filter}
67
- channels: {self.channels}
68
- data len: {self.data_len}
69
- trigger: {self.trigger}
70
- eeg: {self.eeg}
71
- """
59
+ return f"""[
60
+ "time_stamp": {self.time_stamp}
61
+ "pkg_id": {self.pkg_id}
62
+ "channels": {self.channels}
63
+ "trigger": {self.trigger}
64
+ "eeg": {self.eeg}
65
+ ]"""
72
66
 
73
67
  class ImpedancePacket(Packet):
74
68
  def __init__(self):
@@ -97,12 +91,12 @@ class ImpedancePacket(Packet):
97
91
  return packet
98
92
 
99
93
  def __str__(self):
100
- return f"""
101
- time_stamp: {self.time_stamp}
102
- pkg_id: {self.pkg_id}
103
- channels: {self.channels}
104
- impedance: {self.impedance}
105
- """
94
+ return f"""[
95
+ "time_stamp": {self.time_stamp}
96
+ "pkg_id": {self.pkg_id}
97
+ "channels": {self.channels}
98
+ "impedance": {self.impedance}
99
+ ]"""
106
100
 
107
101
 
108
102
  class C256RSPacket(Packet):
@@ -48,8 +48,9 @@ class DeviceCommand(abc.ABC):
48
48
  """构建消息体"""
49
49
  return b''
50
50
  def pack_header(self, body_len: int) -> bytes:
51
- device_id = int(self.device.device_id) if self.device and self.device.device_id else 0
51
+ # device_id = int(self.device.device_id) if self.device and self.device.device_id else 0
52
52
  device_type = int(self.device.device_type) if self.device and self.device.device_type else 0
53
+ device_id = bytes.fromhex(self.device.device_id)[::-1] if self.device.device_id else bytes.fromhex('00000000')
53
54
 
54
55
  #兼容设计
55
56
  b_device_type = None
@@ -61,7 +62,7 @@ class DeviceCommand(abc.ABC):
61
62
  DeviceCommand.HEADER_PREFIX
62
63
  + int(2).to_bytes(1, 'little') # pkgType
63
64
  + device_type.to_bytes(1, 'little')
64
- + device_id.to_bytes(4, 'little')
65
+ + device_id
65
66
  + (DeviceCommand.HEADER_LEN + body_len + 2).to_bytes(4, 'little') # +1 for checksum
66
67
  + self.cmd_code.to_bytes(2, 'little')
67
68
  )
@@ -204,6 +205,15 @@ class StopAcquisitionCommand(DeviceCommand):
204
205
  class SetImpedanceParamCommand(DeviceCommand):
205
206
  cmd_code = 0x411
206
207
  cmd_desc = "设置阻抗测量参数"
208
+ def pack_body(self):
209
+
210
+ return self.device.gen_set_impedance_param()
211
+ def parse_body(self, body):
212
+ result = body[8]
213
+ if result == 0x00:
214
+ logger.info("阻抗测量参数设置成功")
215
+ else:
216
+ logger.warning(f"阻抗测量参数设置失败: {int(result)}")
207
217
 
208
218
  # 启动阻抗测量
209
219
  class StartImpedanceCommand(DeviceCommand):
@@ -211,13 +221,16 @@ class StartImpedanceCommand(DeviceCommand):
211
221
  cmd_desc = "启动阻抗测量"
212
222
  def pack_body(self):
213
223
  body = bytes.fromhex('0000')
214
- body += to_bytes(self.device.acq_channels)
224
+ body += to_bytes(self.device.get_impedance_channels())
215
225
  body += bytes.fromhex('0000000000000000') # 8字节占位符
216
226
  return body
217
227
 
218
228
  def parse_body(self, body):
219
- logger.info(f"Received StartImpedance response: {body.hex()}")
220
- return super().parse_body(body)
229
+ result = body[8]
230
+ if result == 0x00:
231
+ logger.info("阻抗测量启动成功")
232
+ else:
233
+ logger.warning(f"阻抗测量启动失败: {int(result)}")
221
234
 
222
235
 
223
236
  # 停止阻抗测量
@@ -170,6 +170,22 @@ class ARSKindling(QLBaseDevice):
170
170
  self._sample_rate = sample_rate
171
171
  self._sample_range = sample_range
172
172
 
173
+ # 设置阻抗通道
174
+ # {'A': [1,2,3], 'B':[1,2,3]}
175
+ def set_impedance_channels(self, channels):
176
+
177
+ arr = []
178
+
179
+ # 根据映射关系做通道转换
180
+ for k in channels.keys():
181
+ if isinstance(channels[k], list):
182
+ temp = [k + str(i) for i in channels[k]]
183
+ arr += [self.channel_mapping.get(c, 1) for c in temp]
184
+ else:
185
+ arr += [k + str(channels[k])]
186
+
187
+ self._impedance_channels = arr
188
+
173
189
  @property
174
190
  def acq_channels(self):
175
191
  if self._acq_channels is None:
@@ -184,7 +200,7 @@ class ARSKindling(QLBaseDevice):
184
200
  def _produce_impedance(self, body: bytes):
185
201
  # 分发阻抗数据包给订阅者
186
202
  if len(self._impedance_consumer) > 0:
187
- packet = ImpedancePacket.transfer(body)
203
+ packet = self._impedance_wrapper(body)
188
204
  real_data = self.__impedance_transfer(packet)
189
205
  for topic, q in self._impedance_consumer.items():
190
206
  try:
qlsdk/rsc/device/base.py CHANGED
@@ -8,11 +8,27 @@ import numpy as np
8
8
  from qlsdk.core.entity import RscPacket, ImpedancePacket
9
9
  from qlsdk.core.utils import to_bytes
10
10
  from qlsdk.rsc.interface import IDevice, IParser
11
- from qlsdk.rsc.command import StartImpedanceCommand, StopImpedanceCommand, StartStimulationCommand, StopStimulationCommand, SetAcquisitionParamCommand, StartAcquisitionCommand, StopAcquisitionCommand
11
+ from qlsdk.rsc.command import SetImpedanceParamCommand, StartImpedanceCommand, StopImpedanceCommand, StartStimulationCommand, StopStimulationCommand, SetAcquisitionParamCommand, StartAcquisitionCommand, StopAcquisitionCommand
12
12
  from qlsdk.rsc.paradigm import StimulationParadigm
13
13
  from qlsdk.rsc.parser.base import TcpMessageParser
14
14
 
15
+
16
+ def intersection_positions(A, B):
17
+ setB = set(B)
18
+ seen = set()
19
+ return [idx for idx, elem in enumerate(A)
20
+ if elem in setB and elem not in seen and not seen.add(elem)]
21
+
15
22
  class QLBaseDevice(IDevice):
23
+
24
+ __TRIGGER_MAPPING = {
25
+ 0x3E8: "Start of stimulation",
26
+ 0x3E9: "End of stimulation",
27
+ 0x3EA: "Ascending end of stimulation",
28
+ 0x3EB: "Descending start of stimulation ",
29
+ 0x3EC: "刺激参数有误",
30
+ 0x3ED: "End of stimulation (by force)",
31
+ }
16
32
  def __init__(self, socket):
17
33
  self.socket = socket
18
34
 
@@ -62,35 +78,9 @@ class QLBaseDevice(IDevice):
62
78
  "channels": [],
63
79
  }
64
80
 
65
- self._stim_param = {
66
- "stim_type": 0, # 刺激类型:0-所有通道参数相同, 1: 通道参数不同
67
- "channels": [],
68
- "param": [{
69
- "channel_id": 0, #通道号 从0开始 -- 必填
70
- "waveform": 3, #波形类型:0-直流,1-交流 2-方波 3-脉冲 -- 必填
71
- "current": 1, #电流强度(mA) -- 必填
72
- "duration": 30, #平稳阶段持续时间(s) -- 必填
73
- "ramp_up": 5, #上升时间(s) 默认0
74
- "ramp_down": 5, #下降时间(s) 默认0
75
- "frequency": 500, #频率(Hz) -- 非直流必填
76
- "phase_position": 0, #相位 -- 默认0
77
- "duration_delay": "0", #延迟启动时间(s) -- 默认0
78
- "pulse_width": 0, #脉冲宽度(us) -- 仅脉冲类型电流有效, 默认100us
79
- },
80
- {
81
- "channel_id": 1, #通道号 从0开始 -- 必填
82
- "waveform": 3, #波形类型:0-直流,1-交流 2-方波 3-脉冲 -- 必填
83
- "current": 1, #电流强度(mA) -- 必填
84
- "duration": 30, #平稳阶段持续时间(s) -- 必填
85
- "ramp_up": 5, #上升时间(s) 默认0
86
- "ramp_down": 5, #下降时间(s) 默认0
87
- "frequency": 500, #频率(Hz) -- 非直流必填
88
- "phase_position": 0, #相位 -- 默认0
89
- "duration_delay": "0", #延迟启动时间(s) -- 默认0
90
- "pulse_width": 0, #脉冲宽度(us) -- 仅脉冲类型电流有效, 默认100us
91
- }
92
- ]
93
- }
81
+ self._stim_param = None
82
+
83
+ self._impedance_channels = []
94
84
 
95
85
  self.stim_paradigm: StimulationParadigm = None
96
86
  # 信号采集状态
@@ -116,6 +106,7 @@ class QLBaseDevice(IDevice):
116
106
  self._signal_cache: Queue = None
117
107
  self._recording = False
118
108
 
109
+
119
110
  def parser(self) -> IParser:
120
111
  return self._parser
121
112
 
@@ -132,9 +123,9 @@ class QLBaseDevice(IDevice):
132
123
  self._produce_impedance(body)
133
124
 
134
125
  def _produce_impedance(self, body: bytes):
135
- packet = ImpedancePacket.transfer(body)
136
126
  # 分发阻抗数据包给订阅者
137
127
  if len(self._impedance_consumer) > 0:
128
+ packet = self._impedance_wrapper(body)
138
129
  for topic, q in self._impedance_consumer.items():
139
130
  try:
140
131
  # 队列满了就丢弃最早的数据
@@ -178,7 +169,17 @@ class QLBaseDevice(IDevice):
178
169
  if q.full():
179
170
  q.get()
180
171
 
181
- q.put(data)
172
+ q.put(data)
173
+
174
+ def _impedance_wrapper(self, body: bytes):
175
+ packet = ImpedancePacket().transfer(body)
176
+ if self._impedance_channels is not None and len(self._impedance_channels) > 0:
177
+ # 只保留设置的阻抗通道
178
+ channel_pos = intersection_positions(packet.channels, self._impedance_channels)
179
+ packet.impedance = [packet.impedance[i] for i in channel_pos]
180
+ packet.channels = [packet.channels[i] for i in channel_pos]
181
+
182
+ return packet
182
183
 
183
184
  # 信号数据转换
184
185
  def _signal_wrapper(self, body: bytes):
@@ -252,6 +253,12 @@ class QLBaseDevice(IDevice):
252
253
  def device_type(self) -> int:
253
254
  return self._device_type
254
255
 
256
+ def set_impedance_channels(self, channels):
257
+ self._impedance_channels = channels
258
+
259
+ def get_impedance_channels(self):
260
+ return self._impedance_channels
261
+
255
262
  def start_message_parser(self) -> None:
256
263
  self._parser = TcpMessageParser(self)
257
264
  self._parser.start()
@@ -387,9 +394,17 @@ class QLBaseDevice(IDevice):
387
394
 
388
395
  def start_impedance(self):
389
396
  logger.info(f"[设备-{self.device_no}]启动阻抗测量")
390
- msg = StartImpedanceCommand.build(self).pack()
391
- logger.trace(f"start_impedance message is {msg.hex()}")
392
- self.socket.sendall(msg)
397
+ # 设置数据采集参数
398
+ # set_param_msg = SetImpedanceParamCommand.build(self).pack()
399
+ device_id = bytes.fromhex(self.device_id)[::-1].hex() if self.device_id else '00000000'
400
+ set_param_msg = bytes.fromhex(f'5aa50239{device_id}3f0000001104ffffffffffffffff000000000000000000000000000000000000000000000000e8030000fa00000010000164000000745c5aa50239390045243a00000012040000000000000000000000000000000000000000000000000000000000000000000001000000000000004c2a')
401
+ logger.debug(f"set_param_msg message is {set_param_msg.hex()}")
402
+ self.socket.sendall(set_param_msg)
403
+ sleep(0.5)
404
+
405
+ impedance_start_msg = StartImpedanceCommand.build(self).pack()
406
+ logger.debug(f"start_impedance message is {impedance_start_msg.hex()}")
407
+ self.socket.sendall(impedance_start_msg)
393
408
 
394
409
  def stop_impedance(self):
395
410
  logger.info(f"[设备{self.device_no}]停止阻抗测量")
@@ -493,6 +508,7 @@ class QLBaseDevice(IDevice):
493
508
  else:
494
509
  logger.info("已关闭文件记录,不会记录trigger信息")
495
510
 
511
+ # 设置信号采集参数
496
512
  def gen_set_acquirement_param(self) -> bytes:
497
513
 
498
514
  body = to_bytes(self.acq_channels)
@@ -503,7 +519,19 @@ class QLBaseDevice(IDevice):
503
519
  body += bytes.fromhex('00')
504
520
 
505
521
  return body
506
-
522
+ # 设置阻抗测量参数
523
+ def gen_set_impedance_param(self) -> bytes:
524
+
525
+ # 仅通道生效 32字节,其他不生效-272字节,实际73字节
526
+ body = to_bytes(self._impedance_channels)
527
+ # 100 bytes
528
+ # body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
529
+ # # 100 bytes
530
+ # body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
531
+ # 73 bytes
532
+ body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
533
+
534
+ return bytes.fromhex('ffffffffffffffff000000000000000000000000000000000000000000000000e8030000fa00000010000164000000745c5aa50239390045243a0000001204000000000000000000000000000000000000000000000000000000000000000000000100000000000000')
507
535
  def disconnect(self):
508
536
  logger.info(f"[断开设备-{self.device_no}]的连接...")
509
537
  self._listening = False
@@ -522,7 +550,7 @@ class QLBaseDevice(IDevice):
522
550
  self.storage_enable = enable
523
551
 
524
552
  def trigger_info(self, code: int) -> str:
525
- return __TRIGGER_MAPPING.get(code, hex(code))
553
+ return QLBaseDevice.__TRIGGER_MAPPING.get(code, hex(code))
526
554
 
527
555
  def __str__(self):
528
556
  return f'''
@@ -543,13 +571,4 @@ class QLBaseDevice(IDevice):
543
571
  return self.device_type == other.device_type and self.device_no == other.device_no
544
572
 
545
573
  def __hash__(self):
546
- return hash((self.device_type, self.device_no))
547
-
548
- __TRIGGER_MAPPING = {
549
- 0x3E8: "Start of stimulation",
550
- 0x3E9: "End of stimulation",
551
- 0x3EA: "Ascending end of stimulation",
552
- 0x3EB: "Descending start of stimulation ",
553
- 0x3EC: "刺激参数有误",
554
- 0x3ED: "End of stimulation (by force)",
555
- }
574
+ return hash((self.device_type, self.device_no))
@@ -24,6 +24,10 @@ class IDevice(ABC):
24
24
  @property
25
25
  def device_no(self) -> str:
26
26
  pass
27
+
28
+ def set_impedance_channels(self):
29
+ raise NotImplementedError("Not Supported")
30
+
27
31
 
28
32
  def read_msg(self, size: int) -> bytes:
29
33
  raise NotImplementedError("Not Supported")
@@ -71,6 +75,9 @@ class IDevice(ABC):
71
75
  def enable_storage(self, enable: bool = True):
72
76
  pass
73
77
 
78
+ def set_impedance_channel(self):
79
+ raise NotImplementedError("Not Supported")
80
+
74
81
  def start_impedance(self):
75
82
  raise NotImplementedError("Not Supported")
76
83
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qlsdk2
3
- Version: 0.6.0a11
3
+ Version: 0.6.0a12
4
4
  Summary: SDK for quanlan device
5
5
  Home-page: https://github.com/hehuajun/qlsdk
6
6
  Author: hehuajun
@@ -8,7 +8,7 @@ qlsdk/core/local.py,sha256=vbison4XZtS4SNYLJ9CqBhetEcukdviTWmvtdA1efkQ,811
8
8
  qlsdk/core/utils.py,sha256=yfCiLpufO96I68MLs6Drc6IECRjcQ-If8sXn7RaRHrk,4241
9
9
  qlsdk/core/crc/__init__.py,sha256=kaYSr6KN5g4U49xlxAvT2lnEeGtwX4Dz1ArwKDvUIIY,143
10
10
  qlsdk/core/crc/crctools.py,sha256=sDeE6CMccQX2cRAyMQK0SZUk1fa50XMuwqXau5UX5C8,4242
11
- qlsdk/core/entity/__init__.py,sha256=hM694aCfVFMvs3OeX-CWszN6xfel8NQtfJjEdpy-5rk,8669
11
+ qlsdk/core/entity/__init__.py,sha256=P-qKn3yLpP68GIik-1qRozUjYfhsYOOnW1HGfLt3hLI,8427
12
12
  qlsdk/core/filter/__init__.py,sha256=YIWIzDUKN30mq2JTr53ZGblggZfC_rLUp2FSRrsQFgU,36
13
13
  qlsdk/core/filter/norch.py,sha256=5RdIBX5eqs5w5nmVAnCB3ESSuAT_vVBZ2g-dg6HMZdY,1858
14
14
  qlsdk/core/message/__init__.py,sha256=sHuavOyHf4bhH6VdDpTA1EsCh7Q-XsPHcFiItpVz3Rs,51
@@ -39,11 +39,11 @@ qlsdk/rsc/eegion.py,sha256=lxrktO-3Z_MYdFIwc4NxvgLM5AL5kU3UItjH6tsKmHY,11670
39
39
  qlsdk/rsc/entity.py,sha256=-fRWFkVWp9d8Y1uh6GiacXC5scdeEKNiNFf3aziGdCE,17751
40
40
  qlsdk/rsc/paradigm.py,sha256=WH9kAez0wbci-B1z5BC-nw3nqqOtE_txFILue4TM-cE,17644
41
41
  qlsdk/rsc/proxy.py,sha256=9CPdGNGWremwBUh4GvlXAykYB-x_BEPPLqsNvwuwIDE,2736
42
- qlsdk/rsc/command/__init__.py,sha256=iPrPor7NwBIrkQDxz061gVbnlLYK9KE7VXy-NKJy1XQ,12277
42
+ qlsdk/rsc/command/__init__.py,sha256=lewJj_Ys_oIhAGinLvAp7ZFc_BrCbWjfaNMnOw9sfXw,12791
43
43
  qlsdk/rsc/command/message.py,sha256=nTdG-Vp4MBnltyrgedAWiKD6kzOaPrg58Z_hq6yjhys,12220
44
44
  qlsdk/rsc/device/__init__.py,sha256=BzY9lRfssGPUlJ1ys-v3CWNgGihg7mPa2T4X0tl0Vg4,214
45
- qlsdk/rsc/device/arskindling.py,sha256=IVYgCdePI1rnalhZmTWp95eyS05L_xbSo6EhvBTuIvA,11465
46
- qlsdk/rsc/device/base.py,sha256=isdu4NKQpixWtnsh0t4U7Uecw9QQITmaGyZpKO04aL0,21661
45
+ qlsdk/rsc/device/arskindling.py,sha256=cF6XkuB1yqEBArNu8tBDk19Npf52nPA39lJQ81wSsuQ,12002
46
+ qlsdk/rsc/device/base.py,sha256=HDi0ak1793r-o8OBS5qkOrXT_zjPVN5F4zs5fgk75gQ,22639
47
47
  qlsdk/rsc/device/c16_rs.py,sha256=qXt8m5vwcKQsN8JBllWnAsda5_Y6qkEhfHQQX101TMQ,5826
48
48
  qlsdk/rsc/device/c256_rs.py,sha256=7vAEzf_ggNcwrXKmcZMylnKzLFD5ZqtAIfkkI3lQ1iI,1682
49
49
  qlsdk/rsc/device/c64_rs.py,sha256=x8wHdwATKDU34j9vXNEXsNSJg23RAWmAKL8pgIGamG8,1091
@@ -51,7 +51,7 @@ qlsdk/rsc/device/c64s1.py,sha256=WwiKSjxYpUJVkHDMDzPgp7-klbaiZ2f8EOe3wV6d2WU,109
51
51
  qlsdk/rsc/device/device_factory.py,sha256=6cPhm3pPGrVXA1s1HePFLjZqmhNI1vOAucFI0VRD_Y0,1317
52
52
  qlsdk/rsc/interface/__init__.py,sha256=xeRzIlQSB7ZSf4r5kLfH5cDQLzCyWeJAReG8Xq5nOE0,70
53
53
  qlsdk/rsc/interface/command.py,sha256=1s5Lxb_ejsd-JNvKMqU2aFSnOoW-_cx01VSD3czxmQI,199
54
- qlsdk/rsc/interface/device.py,sha256=tOS9EzTC4nty8O4W4E-HR9gdn2hwfdj_2zvb87_bdfM,2417
54
+ qlsdk/rsc/interface/device.py,sha256=8Aqx-jS6v9pKd9qvTGytPspzGtDUlIxHc0g9R-wkV_s,2623
55
55
  qlsdk/rsc/interface/handler.py,sha256=ADDe_a2RAxGMuooLyivH0JBPTGBcFP2JaTVX41R1A4w,198
56
56
  qlsdk/rsc/interface/parser.py,sha256=Z4PND5LXcJ_8CQ-OIq3KlOEVOceU1hKUuZkoFSIGGLM,334
57
57
  qlsdk/rsc/manager/__init__.py,sha256=4ljT3mR8YPBDQur46B5xPqK5tjLKlsWfgCJVuA0gs-8,40
@@ -70,7 +70,7 @@ qlsdk/sdk/libs/libAr4SDK.dll,sha256=kZp9_DRwPdAJ5OgTFQSqS8tEETxUs7YmmETuBP2g60U,
70
70
  qlsdk/sdk/libs/libwinpthread-1.dll,sha256=W77ySaDQDi0yxpnQu-ifcU6-uHKzmQpcvsyx2J9j5eg,52224
71
71
  qlsdk/x8/__init__.py,sha256=FDpDK7GAYL-g3vzfU9U_V03QzoYoxH9YLm93PjMlANg,4870
72
72
  qlsdk/x8m/__init__.py,sha256=cLeUqEEj65qXw4Qa4REyxoLh6T24anSqPaKe9_lR340,634
73
- qlsdk2-0.6.0a11.dist-info/METADATA,sha256=0LHCnkOCM5qaDZAoLglt-mIBltLnZBiaRrta8L9JbHE,1883
74
- qlsdk2-0.6.0a11.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
75
- qlsdk2-0.6.0a11.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
76
- qlsdk2-0.6.0a11.dist-info/RECORD,,
73
+ qlsdk2-0.6.0a12.dist-info/METADATA,sha256=KBM861AYBf0Fr_fwhixloQ2XyLrCcneGeLRceKJAc8k,1883
74
+ qlsdk2-0.6.0a12.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
75
+ qlsdk2-0.6.0a12.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
76
+ qlsdk2-0.6.0a12.dist-info/RECORD,,