-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathvalidity91.py
356 lines (281 loc) · 56 KB
/
validity91.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import logging
from array import array
import numpy as np
import usb.control
import usb.core
import usb.util
from dataclasses import dataclass
# These messages seem to pop out alot
success = array('B', [0, 0])
failure = array('B', [18, 4])
invalid = array('B', [0x01, 0x04])
class vfs7552:
"""Validity 7552 sensor found on XPS 9360 and 9560.
Example usage:
```
f_sensor = validity91.vfs7552()
f_sensor.initiate_capture()
print("Put your finger on.")
f_sensor.wait_finger_on()
img = f_sensor.capture_image()
print("Take your finger off.")
f_sensor.wait_finger_off()
f_sensor.disable_sensor()
```
"""
image_width = 112
image_height = 112
control_columns = 8
# Mark: Personally, when my finger isn't present, the variance of the image is very close to
# 0. Single digits. My threshold would be 3.3.
# I had originally set it to this, but then many people complained that it would return
# almost immediately.
# @dreamwavedev found:
# Also, the check for img.var() being less than 10 I think was causing some issues as that
# almost never ends up being the case, at least not with my sensor. It's almost always in the
# mid 100s or 200s, and gets to the 700s when a finger is present.
#
# Mark:
# setting the threshold to 600 is fine for a full fingerprint. But I think we can do with
# partial prints. Therefore, I set the threshold to 300.
# Because we are looking at the images, I think std makes more sense.
# It is located in 3 lines of code.
finger_detection_threshold = 300
def __init__(self, *, idVendor=0x138A, idProduct=0x0091):
self.skip_optional = False
self.dev = usb.core.find(idVendor=idVendor, idProduct=idProduct)
if self.dev is None:
raise ValueError('Device not found!')
self.dev.reset()
self.cfg = self.dev.get_active_configuration()
endpoints = self.cfg[(0, 0)]
for endpoint in endpoints:
endpoint.clear_halt()
self.bulk_out = endpoints[0] # Ednpoint 0x01, Direction OUT
self.bulk_in = endpoints[1] # Endpoint 0x81. Direction IN
self.interrupt_in = endpoints[3] # Endpoint 0x83. Interrupt IN
# time.sleep(0.05)
self._activate()
def _send_messages(self, messages):
for i, message in enumerate(messages):
if self.skip_optional and message.optional:
continue
logging.debug(f"Sending message {i}.")
response = self._ask(message)
message.check(response)
def _activate(self):
"""
# is this needed?
assert(dev.ctrl_transfer(usb.util.CTRL_IN | usb.util.CTRL_TYPE_VENDOR |
usb.util.CTRL_RECIPIENT_DEVICE, 20, 0, 0, 2) ==
validity91.success)
"""
self._send_messages(init_messages)
def initiate_capture(self):
logging.info('')
self._send_messages([acquisition_start_message])
def wait_finger_on(self):
logging.info('')
int_response = self._read_interrupt()
"""I've documented 3 responses.
I think they mean:
[0 0 0 0 0 ]: system ready, waiting for finger (returns immediately)
The next reply will be [2 x x x x] when the finger goes
on
[2 X X X X ]: finger on
[3 X X X X ]: finger on? [2, X, X, X, X] was already returned.
Others have reported different results. Maybe they were putting
their finger on too fast? Anyway, the driver shouldn't fail.
"""
if int_response == interrupt_ready_response:
int_response = self._read_interrupt(timeout=0)
# Yes, not elseif, we need to compare the second response
if int_response[0] == 0x02:
return
else: # int_response[0] == 0x03:
s = array_to_str(int_response)
raise("I really don't understand how you can get this response." + s)
def _read_image_part(self, chunk_size=4806):
self._send(message_read_image_part)
header_size = 6
if chunk_size < header_size:
chunk_size = header_size
image_part = self._read(chunk_size)
image_chunk_size = image_part[2] + image_part[3] * 256
bytes_remaining = image_chunk_size + header_size - len(image_part)
# Images are typically returned in 3 chunks
# 4806, 4806, and 3846
# if the chunk_size == 4806, I don't expect this to be needed
if bytes_remaining:
image_part = image_part + self._read(bytes_remaining)
# don't return the header
return image_part[header_size:]
def _read_in_image(self):
previous_log = logging.getLogger()
previous_level = previous_log.level
logging.debug('Reading images, turning off DEBUG logs')
if previous_level <= logging.DEBUG:
logging.getLogger().setLevel(logging.INFO)
img_part1 = self._read_image_part()
img_part2 = self._read_image_part()
img_part3 = self._read_image_part()
img = np.array(img_part1 + img_part2 + img_part3)
img = img.reshape(self.image_height,
self.image_width + self.control_columns)
img = img[:, self.control_columns:]
logging.getLogger().setLevel(previous_level)
logging.debug('Returned to previous log level')
return img
def capture_image(self, N_tries=None, actual_finger=True):
logging.info('')
previous_log = logging.getLogger()
previous_level = previous_log.level
while True:
if N_tries is not None:
if N_tries == 0:
raise RuntimeError("Finger not found")
N_tries = N_tries - 1
response = self._ask(is_image_ready)
# Don't want too many logging messages
logging.debug('Turning off DEBUG logs')
if previous_level <= logging.DEBUG:
logging.getLogger().setLevel(logging.INFO)
if response[:2] == image_ready_response:
logging.getLogger().setLevel(previous_level)
logging.debug("Last received:\n" + array_to_str(response))
img = self._read_in_image()
if (actual_finger and
img.var() < self.finger_detection_threshold):
continue
else:
logging.info(f"Return image var={img.var()}")
return img
def wait_finger_off(self):
logging.info('')
previous_log = logging.getLogger()
previous_level = previous_log.level
while True:
response = self._ask(is_image_ready)
# Don't want too many logging messages
logging.debug('Turning off DEBUG logs')
if previous_level <= logging.DEBUG:
logging.getLogger().setLevel(logging.INFO)
if response[:2] == image_ready_response:
img = self._read_in_image()
# Some heuristic I found that detected that the finger
# was taken off
if img.var() < self.finger_detection_threshold:
logging.info(f'Stopped because var={img.var()}')
break
elif response[:2] == image_error_response:
logging.info('Stopped because received image error response')
break
logging.getLogger().setLevel(previous_level)
logging.debug("Last received:\n" + array_to_str(response))
def disable_sensor(self):
logging.info('')
self._send_messages(stop_acquisition)
def _ask(self, message, read_length=None):
self._send(message)
if read_length is None:
read_length = message.read_length
return self._read(read_length)
def _send(self, message):
self.bulk_out.write(message.query)
logging.debug("Sent:\n" + array_to_str(message.query))
def _read(self, read_length):
response = self.bulk_in.read(read_length)
logging.debug("Received:\n" + array_to_str(response))
return response
def _read_interrupt(self, read_length=8, timeout=1000):
response = self.interrupt_in.read(read_length, timeout=timeout)
logging.debug("Received Interrupt:\n" + array_to_str(response))
return response
@dataclass
class Validity_Messages:
query: array
response: array = success
exact_response: bool = True
read_length: int = 64
optional: bool = False
def check(self, response):
if self.exact_response is True:
assert(response == self.response)
else:
assert(len(response) == len(self.response))
def array_to_str(a, header=None):
np.set_printoptions(threshold=np.inf,
formatter={'int_kind': lambda i: f"0x{i:02x},"},
linewidth=6 * 8 + 1)
return str(np.array(a))
windows_name = 'Synaptics VFS7552'
init_messages = []
init_messages.append(Validity_Messages(
query=array('B', [0x01]),
response=array('B', bytes.fromhex('0000f0b05e54a4000000060701300001000096a18a0069170000000000000100000000000000')), # noqa
exact_response=False,
optional=True
)
)
# Tom Hughes reports on XPS 9360
# response=array('B', bytes.fromhex('0000f0b05e54a4000000060701300001000065418a0040710000000000000100000000000000')) # noqa
init_messages.append(Validity_Messages(
query=array('B', [0x19]),
response=array('B', bytes.fromhex('000002002100100100000000000000000000000045e68c4b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')), # noqa
read_length=128,
exact_response=False,
optional=True
))
# vfs5772_init_00
init_messages.append(Validity_Messages(
query=array('B', bytes.fromhex('0602000001c966111bc5ec1d5b4e90a9b2a86e91c547e29f6c16b0fd47d3a85b30fd5b2525134bd25cb28166da8cc980d255382e9603793eff7e45cc138960d4e8c33297954ad1dea2330f2e3d433ecfec589b558526993fe8e9e3455cce597144d3444bd50f01ff62b35bfc46957963a42ec2d480a53c2b8c586ec20078a1ed046d59b51e7c8ae5cd39640378dd2cc6f68cb01175c65caa81c2e4d3dd144a1bf911baeb0aa70bfc57a36ada00d83368deb26dceafc6b4571ecb44b81231d0a3eefd53e00991920d4318cddafc0fc3118871f118346976b2c0004cd581067454da6668d245df39dcdd206b436d61cd8b8edb01c35f0559fed7500f2f643e6f26e2bc84c17a3f0af54ec463ffdd34eb1e7a64b0ebb95fa541dae812f22f6f939bc58924aa1cefaa5e8e4901a4e4e594b58fddbebd010a1b24f70e638b9f59f50f489f97a1c71092fbf8e2d7906e3c35ccedfa78ec858d39bab5c998a1f29d7eaa9beb5daedcb0e0d94d7536526fdefe8a7c6a78cca911f18364072f75f1134ca1b8075f5a067e36a01bf2f33b8c52906c701834c6b91325b6cebf46ce8fc205f459f1767cb9531794a5b052cd0d08429ccd6b36415e0c12ede50c8c1c7671e5b4d5f3981f52357094085ef818db78cef17a7b0d7bb06d3e6637655711d23a2c7d6fc1d350a85578ad93588ce15ce0503870c080358b')), # noqa
optional=True
))
# vfs5011_init_01
init_messages.append(Validity_Messages(
query=array('B', bytes.fromhex('085c2000800700000004')),
))
init_messages.append(Validity_Messages(
query=array('B', bytes.fromhex('078020008004')),
response=array('B', bytes.fromhex('000003000000')),
optional=True
))
init_messages.append(Validity_Messages(
query=array('B', bytes.fromhex('75')),
response=array('B', bytes.fromhex('0000000000000c004900')),
exact_response=False,
optional=True
))
# Tom Hughes reports this messages on 9360
# response = array('B', bytes.fromhex('0000000000000b004900'))
init_messages.append(Validity_Messages(
query=array('B', bytes.fromhex('060200000119c128a3bd5faf091cd69f55b7dbabbca376a87d42e14d41905a8a59ea53420a8a074a809d00cf55d86f32409e2da4f6e74f78e6b7d03b29f57fa9e10f8efe58d849ead21212c0c60c40814e1e60cc43aef7e10ad6164f6fe77474a82a4472e211c94bea36b4d63f052d4ebbf7b06c7f9eb69fbbf91c352a76c3eed1ee06baf7659a15de056906dc1a3ae2e3d0dbca94ef14bd037537a6c02042c611ba9c7d6b1e552b54503e6db1bab6bf8e2b43afedba05719ab271b3f146cb3a7133ce73d9bf75929cb34ec6e3e5405ede71bdef73620424c9ab12dfbf1e473221cc00afbb0bef99b650c4ac3af6f53419ef2f6fabe4122bb0812ba219059348e5a6f4716c6fa3a01c18c9eb3952ec494c63f2353388c6c08f516f91e0151a87403fd04002c430de3bca5ba0d181fb867c570816d5e667b69259b9d67db737ee0a3ae10e550674a6377dab760570fe62fa4ea6efd64b7c767c0e9065501b117586fb3475fc720d9bd794bd46a2419934e58895449824e6e408d453694e1722c610bf6b594aeee5ed14abce9c205450a23c073752651e2f9acd613cad85be39919e378db9eecc354091ef09b1d47ec53c1f68c4462ae343d095cded5f76c5614db7bc61ff67ef4affd0dc2f802e0e9c85ad358d52a85f80f8357b25e2781e4cc9c14e16eb76cfdccc6bbd198e8adcbc9f85e9fdeb929212f23c392520ac2b30fdbf637429ef16412a2d654434d206b0ba7a3e0e6168103a23dd368436e50cd3f5b5f359e61116768fe53cd5671996e2584b25a1ed42fd187007efd49f328c33105c279a71cafc6b09fc06503c3e00a0e3b939172af72d80fc920bd50d2e7748f6897f87fd10b9fb18e811ff330ffd3dae9e77f26c01974b934ed0b3ed797b824eea27ba243f672f6350ec52ec989ec83cfac91b89b10865ab98a9fac008d7f53e4bad2b1c68f1a352c592178db53d8ba17cc04b0eb282c6c9e840ffa1ad2c2d791ef9de20a6a8eb9a7e9c8d15d299c3302b4106fde5fc146e579bfbdcab79eee3bb65c1a2bd31cecd0fa578614c83bd3bcc88845d5b0d5837a2eacabff3bcab82f23659057bd251fb1a3e2f5f523a88a1d20babad843601eaea203377af60fe63129458b5de087eb9d54ac4aa5c8dfa71b60139f9ea2d9af6f3c4a044fda8ae60dd664d9018e305bfcb80226210f979865906e552dbda408ffbb0ce66c5046e4eb6b25f91bedf5e341466ec393fbf3bdf3a5044ca0c95fb91b76eaa85c9a462ca220a4ab186c9894a8a1129c278b7891ed980d0204f2377d4193bb7829a70f7630d2cdad50323a2c9036c8a9cb18a50bbc02f82c04d840138ca95fea0b80128c08fc9022516f66c098005c7fbca5dc6637e77ece4271ef5d1f5eba1c86d1822ad7d632cd73203fdca674e35273866fe2f1e18b5407b4105262d10d8b78f8e34557dc51b6310a306ee5e7e209b5ed359fbcdfc621f8e3a3159cccbc0f1126b6627910e265defd639c5550640285f05641c93231a0658740382c63b06b9f971ac780df450cbb0567925ff0fecc9a628a5ee81e007c95ba6b3f7bad08ae10a56a14e7c131088379ede0e5f5c57a0fdf842e3529f48a5523e86235c4d90b066df08a35348fa5c433f78888c152f88da63684ca15a5f192059105df3a6f653e3e877c0e708fc296f64a1018924630947d66647c8acf42f992cbd266f35d0ff201bad96661aa624b54a12cc0028b2d8de345af88b8fbdcddecaa6e12b60315ab48fd4b1f66491fe87a3e2e13adddfead98a30911d6f4979fc555d1dad51785c603d8adf072da6cb5dcb2a854c728b4272f634029de82b56176140bb998e297885ffdfaf605a900426e7b0c73864f292b2feec0b5e4383f92b123b7bf5057d1675ffec9afc069c5bfcdf37c0ab52a57b1bcc6a2fd575628ccee76bdc51dc0f2445863f8669f2dfc845392492abd846440aecd669b255df553a0c30ff0438252b6f7f4c61d5727c99aa91fb13465c0842e6166742198c5abd32f6c842889cbeb728bebb9ffd5778dbf74328341af27c2b3f44bd23d22f809f8d56496a3c7ed1b8f335ba54017bc75a874698bd730beef22545c116edda2aea911ff4dec25b7ebc6d001e7f10d020964cc38c700ab2391efdf23bc77960da38c2533af795fbd209e9ca17ef8356149600a80c9be202edf4e83cccacccb011864c23c8ba93697757105ec1992af2bd7c81f78899c4c4ab324d79658a3b0c766c3f53774e488e7d9adc9bd5116059f5a0c385595b27fcfe2647e0ab540f4a40483097b7e6f2688b1b8d6bf8b1285b526f8b986f92465e6a33d078b8ecf9dba80dd22715ba7f86e7967ea027e024ee54019a18fbfb77ba5ac6d8a366ac27c314221bfd276ae5aca5bd828c39fae143d57a261cb4066253c1975df1833287923ce52d860f7403c65865c487108e5c52858c187867e08901f13b0f2b9f4997710f14661d1d229e5ce2de9f3f0cab7fd6b24849214c65c144fc6c4246689ae2e65c77107bd465a2bc308c08ac26e61784f9b2442313be037de350df36792d5c0c76d17fb77ce6958de9add2ca51d4d668d41dd6965389ed2474bef1e6ab9c3ddc8a5e4f4567aa3f2d3563bbf8b68c9b552bcfa08fd3e920bc7d3e7ad235c4e45a07f7bb3fb74620cc85a73c3ce141b6123cf56e9cde26a8e1c7306fab8502289e8c07966c533a8470d0ded96d2da5fffc1894039c2a889d3c137f12821703c4753cd99f5594cb1e4470c70ddcdbf007b0b66efbb25eba232b01375b7f6b6cea930cc56ae48559b615dacb9f4be4def668aef2eca2802df7e1712c8ff9ec2c70f62aff52bfc07d6fd2500b1c92ca989dbd739af041c1067376a8fd618dfc6c219b83528ba5dff70675434f8913c43db8fe434126e63918f32485267205ac1d9f9911468091ab5634fcd8244586f2779c5108a5111ad250f4c92740747867745a29a70b9c7da170948565c25a7b63ba200fadff234fac6dd4e6950cdbaa133983f6c193dc356bf60e6a91bb9de3099f09da2aab1234fd41ae860e9c0222e241638764d8b352f476ba01caa144c7a73accc2c1706ede38cfc56a4da5ddfbef3b43f2a0df3a4b9515c97e50496ccdf13b38ca42f103611db2b64bff3a21f767d61df39b07b435199320876adea6e6fb8766e20723c94500ddc151549da3ffdacf14b42d9b30c4e391403bf30a5bb83852e862d1b36a294afb7c5c100c476a8b4fb96505cf7c7de69e9ce5d04e219b9c359f4e609c463a3a9288934b649e2946de8657c96d5bd1ee37eb31426987062012504bbbbba7d300953b9805d2cd8c4513f5052087da14cf50b03ce326fc6f244564f63e04b61898a905fe3a8d4248b7fe89ab381583fea41d02d387f125581cfa661686e0bcae306e12f0a57a4f987118448b6102fb79c62addccc7ae78b7c4d733cd0af648d440d99c4b3702a28aec081ec94ba1fed427891ed23d667168b532ca62a397953b0379f3323b3acc02c3820ff5cf8905f55e12c478197e98750e0f8414c7a002ad674f232e720166873fab6ea32b1d6631e5d49771790b715b10e315df216a57411a13e205f35bc09a6344d28a7239041cdd2684f48f8c3b5e78d991f2843349831550494d88d6242e963b58ebc0b1f26dd5214be37231af7bd757f11cf26ef4673f56c1953290fcba96be24d7478db90f391ac2813bf1e755f4e861dc9336bcfe7a322f10f83ad45d8a19b542370781b08de739434ea7e2fdb5dd1d37f263d208e6edb2c79fb48b6e40647050728b98bdcc08af55aded8a97810c86bc6e9ab02d9c53eef924a7e7b2b83817f3f5406fea1b6971c6810f4f9d80040fd69ae7e8c1f85e1c749f7535dee469a579c257df17169120ae038fad23540b16dce236f7a0f8b0fe85130449675ee258a5b88737062a37869af876176472770fbc5a1657a335a372ff8ffb8276d2e0e71d0a9b86d254858fe415ea0f474457d23a3401976eecb82335e059cfe0deaa2482b695e60b6090ba5245f2579202c0a433c427e20a5e70fb3ac3d196771c69e2cae93de302197cc8c153035d4780b2a1c5c98bb0e3c94d1a773bfd27c5c2b0fb98cb4c4fca4fd459e77cd8991e1398a5e222f4c29fdcbf688e534f6e2fe2a802a47ae8785335a8b961ac00a7578cc07fdac202cdfc14af696a2388e2f02479af98d3457a89a138d3ed946afb61c4775d1ad5072e2a4cdf8e2ab9b0f4381857a0d61e71fb126edf03d790a316d47368ff8af4e46610930f4ae97e2a32d1ac2ad10c4264dfab4e202d8062ed903cd794fddee97e8b6826e4a38547364c04b959662baab422212b0fed406fdd5c8b9a692c9ac8ccf4a8c3b31c96e36c5a94a547fb6c2ec004bb30eca70bf4eedf8e433ce282b5ce5c86cf6aa16c2b59224869272d4f35dd3296eb6af6d6900b1a30cd364671ae11f4974bbaaf1379905265cdf43fb6e9a1fa1208423911b60707ae6627ca0f1841421eb51444d7fcdf9083da0ed94014a9f5ac3a2dc1c0093d140616d10970704568c5fefef70809457f9ec5f32426994a7aae18fd94d320220fac19bc506ef39faca9e177d1c62115e77687e3a415475a52539dd0a64a0782729d3e2aa62ed6cd3569ef41e6e9eed319648f4268911e546c417d4d5ba498ca3da237a60b288b808570df1c3312ebfd27a72f0152ef30eec05a0cec447c3c06d89397a1badfe59d53134e0bae8afd72b5f3a1406f096c0cb26930ec11708cb11c34f0269c0c5911e14a2d5fc5c64e89cb7034c868fa4fe73537527dde11b6ed16f556242eec6b93dca44b955648196daa71c307e17b678244cf1b53a56d2a603ec1eaf9130ae1611d9fa4dcd4df2799f2a7d00e56c786b1c1c47c763a115415f73677303cfcf0713849c8b2d07d6e1d3596f5fafab9e3b8e707970e32073477a6a639f5e432ead528386acbfc4beb341c03b0b066bcfa9d3c2215c0a27e75b75c22dd731b39a0ebc2f296e2c5e5831ac8d8fb006d2dd69a644a4cd921a150e171f89ab532eaac5a4120e984ebfe01626bc89bade47454ada9c459970825669b96699d6236bdf93d4c8e5f7c664e3cf396384724619e9bc9f722a6ff14d3c0ff796ac801921704bc8becf50129f3c3da724a16788253341abd1a3539cb2e716a16c88ec494a672909ef5fadc90214dd873da4709f19e2bd0fd25120fdf86553960ea960dc083b150c9ab6786ecfc9888dc41987becbc3e1e6aaaa286f9b3d01feaa79db5e0c57ce1c13bd0a2a35c67b4534d2d776799d62def5dab8ba788f77924ec21bae62b1486d8fcfe057f48a7629e6f98fd91b1d755dba1aede74c2d17f72610f4975700af74615e951b0d0468f836e84b2ebb7374757077b82ab42ffdf61e7bcc756a22cb831d9f25e9a3bc1628c6d0fbaa88e84c3fe9fd48f9eaffde5e3c4729913326431b02da8f9d9585fa4006c6bf11934044142143418d924f61521b6f2b5075a80c5505a1958c07d271b28ff37487c0f614b111ef7d17ef58a790d8962cb1aba11db57d25d77a34efdaa237937b7da1b39e5516fe7d3d64691a9b82c5edf49e2411d66315b8903f3258d0f1851c0b9cc9425de89793923b91ee21d623b2a1df7eafd2f5b6503733fd7fedd214663b5c1b6397c15d473ef5e2add51434c43675e7715be5342bda9f3500fa6c62a90caf108bf9d397284d4a06e2525ab6d91da2ddef9c048469fca6c3ef994d3b402d466fae7b6cdd027eea07849deb8d1b87073e9a7999fd6d9b95bd896b9b0cd6de98eab49e7d0b6d58828bdc6b0e884c45cd33ce7e693418df47cbcc82a6a5d3b73ac3f3f15464f9376a1187a4d106353972c34396869a092e84d0bcc1c10609786e484b3ccbb93991b136dc51a9f14b1986e51eca5755c2891d58bb0516fc01b738b0bc30f1561683c855081de514906c54bf8b7d0a95353c2bd9c20bdff71b817fcdc64a7cdc99d8280ab5493c0ae26c609dec1f2dddf477fe9a9e03e13328e36e34254c738f249a7a59e0060773caede31be1000573b13607aa4b64aa6ca42fcc38f47a09dc9b2381655d7492a8b8b3dd2794dad973511fbf922b0669ef61ef1becf9c885e7e21a583bb183065f4e099dd835adc78b046e45b0b761b4c10b2e0c0e1cea0cdfe57bf29585cbec8c8ad8a874fc31cc0ab471673cf2a541c851406da7018da96e7a0afcb428ba2b3f79fe12f4b0523316d1555ec87371d49ae5cfd5b1931db589087b032ecc4d11b9971c35d92eec52237694f742760660e0dd99374bf00bc9257a81abd7d6844c17c32dea991b103f8db5fcaa2d526b8e0831ce400b1707edfa65b1bf0904c7c33781a54b653af3c7ca8905e865c84750f578223163089a38c598922afa9acdde7114f8f6731b1fd0e44b7ec38128a9cbf1368ace33311fe551534e20eafa47c6846a76307784768b78c20e53d1b987987e8ece0a8b745252a7a9dd6ceeafecf053bb49ebd3442c9d5fcd993c71c2891298d3228a85be95a52d207224b2ce5154a67ac6ce821127584deb2a3171e6a4aa45a8b935a00f131d88eb7d17cf7aeb61fa98c6b9c9bf88d546930d82560067a927fb3d027af2b2fd412b15e9524ff98e7078c387c40fffa87a6a7811f260883ab48a3c2804f820b3f344948b8e6b5a9c3d48a40444e69ab7f5dad00739e5ae10b4a7984c85a099c2f1e481dca384ade0d047c1307ab5ad62b84c9180f44ce75f83147abba838fd0a306e3ec7d571f621a93c4356e16f52d1caa8e4a5f8a726ca308f2b929d5940fed319d5e19ca16f1c3066348febdd5bf7108570a49976d8d57b7557e2cc604ed6b199be51ca2a0a5dec5ab40cab775620ed39f8954de62775ec0882c23843a3c0873211044923a25b93ae6e8c3085091f8ce949b51c242d064aacca92c2b82c660fef236ff632b8e75405af09cb62a20f21792d47ae68e336c7b05a142423aaf2bebd53eafdce6b8d74648a617b8614cbbd7ba9ea714c3bf573dd828c62e7875c9aabdc53f8417177e9b9ce16055d28e3b06cd1dd1eb1ecc4982e4ea97b26c3cdf64962b880d088bf8ea01fa08360f7fd97f9e24f1bb655d74184eb10d22396a406b3711e5de55e7736bf99a1fe4c4858490321eea23593b0923e17bceadd53bfe54ba563c435784b076893e465dfcd9c6187ad4d1b9fa7233d825916db78bd6a350ed77d7c910bbb9b72bb10276d27e3be0e91ebd9894fe554915582a53d615cbb3ca1071440516e71a13071bc3c7dd37e8a635c5536e25cd8c18a9cadde34d364d3effe77aac0ef3e5c9c8cf293d39a3587ad9b14aca1bcc4cfbf224963fecd41601ad9f66048761aecf48fadf9751727cf746cd370df99f04ebccd670f5194ce126530eb0792672e4599d4d3a47cf710412bbaddea3c4779adedbdbc1dd1bf511f958ff40e2ab60b8e8c10843db8a3cb01991141d0b15bc505b7058b56e6a9cd3a3cdc782d6522c53ae044743e8230339fa9176d66c45b3801fef515696ecdbc8de161965bcd658921e10191eb4f30b56aa9e067099b8c4b16d59be32e5e7ad6eed490cf0ccd35d05deae323aaa4f65cc2cd7eac14eed5a55f47c122bb4887f6316b79123435a934dd957eff777257a0e9dadaff1a894b192870f3c69063c4f04cb87a84a565046ed7068943c51c257ff9189c0e82a6c32acffdf544fe935aa0a8616ca393fcebff16cc5607efc78ed13737cf56d9ee8c7f137263d9ce48ba12bb3de06fb52bdc966044db74debbb02071414306015e20faa61a8d5cbcddfb8646c211654464c57fd7148636f638c4231492b45e779f170868345faa2f664bb64bbc8560895e9ea0c76db39380f54071b6d99889e4b2f5506f801a9a5a86d6ef1e0b5d0a64e609d8a23ce919402f7c5f46e7d95ba6e8699b56bf7378a701247d2a56d79bbdcafbadcb49b1551c7eb7eed05c801b6d12a4e67cc0dfa5891388f904fa4a153fd28710a9b33897e8422feb96487b9d894d127ac56bcf07e34920a915d2172cb4b667e9f423d043ea941504ef63acc726854d9fd1071cfe51440f4517b498819bc5bef7fc087e754656cb2e0ba842e03b41106e1bd4c524fe9c69e242e43bf012beb336e71b374c8d377ad047675a5858af3173259b8af522b2e1c71f66939dd6a6f1cbf7cc61dc6fc497294d64fec4458732d11108631d485ef40bfbcbcebc922ff6eb394d6f3846ee11b0e55ea55c7b27ddcf0d7ebe8f48cf15add18bfec14e3e361cb5dc6c839177c68b7e66261fc4839766afda5c195d4a4e8ef646b8cae9a95bbb3599c700e5b1df381141db1abcde017e3c1e0414ffcb8367e960e2ad4fe7035fe50a76b7978873110d625bd4e809305ec943f52e6482cae557c49a778bf1cb54a77479f1168d4fcca52c43acfaea605d5478ec67dbb8a07a2dd3ace1879340fe94e2ed898208246d2b93a7cceccbf3eb7b6a15b72d66458b2f65110dafb0140552437d56ebd41377028454696d6012d3e4d545a69e9c0e0f9fbcaf2c622070ce1f99325d4b37f1780dee58cb1c429ad546084b9ecd03c10177b27a96425ff58bab4dcc87c7df64dc35338ab41e8aad06e77d44f73b0a7a7f51b720754f3ed2e92b67756b1b4383908d430225b86cae69e1ccf63510ee8b8629988754a9ce3f49ffd0cc033c74c55fe6b1ce62969b7ba8795e750994e7f3982835f76b9e3c555c6cfd9c644e8f00e99a6a650ae01fd1e7fa9ee42ffec7688412b6f872e93167313f408c0d48fbfd109285dfb0d3c25101d41a05088af2e70024776438f949c7ba62616c65cab0a4cf0195c79cdebe5f7d6feae65079d35c04637231e1672106f2d17d6cc517b93ff3b6072b63df21c74ba188f528de1bc93aeb7db7a9dc3ed05ee54a9fd0753ed5b2d32f2fcba709d0f453685ba7b49aa57dfcaa70544fad0da1e94b99f51943376c82b799b08a475f3c113a03b13c455d594f5224b28326adbabaf756c90438be32e44635835b93d9f67477671f346c7fb12500344f023d34792c1208322b587af93a3aa4bdf3882e48788f27c80414d6e7f7f26938b830d07b662ee58b526b6b7a567e79f75799a16ee988fa08ea18d62088a15a357e3a61fd8e18f3e34dbfd2c5156bff81add67df8432a4d27a1656f648236a8a5a7f2bc9b569487e4d8dbd110cab321f6c5d8a7f0fdef3ccbae6016b986da212b36cf43b7ba7c755bfb2e9a46d4384f55b80b0a3914313467f341fa3fc8aed48030d408fe1abaa7363e5b501db307a2e91157617d407e0c61df2d1219553c6b9a63c14015d1166b2d109c01df58f3e22600657138c8fe69d54f1f93733ae23d385efdc17fc0ffa92dffb1228fbb2cd5111a4439288b1120978f8903c5d4d0f502b9c40d0befc26244b206dd4d9ff311f5637c6756dc4d61d23d1eb8964e6bff32302750e0a5fa519c425cbc55ae02cec2e62b130080d87d013acf2')), # noqa
))
acquisition_start_message = Validity_Messages(
query=array('B', bytes.fromhex('027800000023000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482104004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a0032000c0000000080501101004c111e0034007401eaf5f9fbf7f3f1f3f9ff00000000faf9f9ff00030202070b0b0904070b100f0a00feff0202010407080909060203040607060604040409090b0c0a04fffbf8f7fafcfd010404fef9f8f9fafaf8faff0202fdfbf9f8f6f5f3f4f8fbfd00040603feffff060a0b08020201040407090d0c10232e10232e10232c10232c10232c01065010240101000007c8078c06ff00004f8a006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f00040070000000290004007000000035000400800000001700000026002800fbb20f00f2220f00300000004a0002002a000a00018000000a0200000b19000050c360ea010910002e001c000200180004000000700070004d010000b400a0003c32321e3c0a020244000400010000003000f4311e000000ff0000008d002007ff00000091003007ffffffff00000085ffffffff04000085ffffffff08000085ffffffff0c000085ffffffff10000085ffffffff14000085ffffffff18000085ffffffff1c000085ffffffff20000085ffffffff24000085ffffffff28000085ffffffff2c000085ffffffff30000085ffffffff34000085ffffffff38000085ffffffff3c000085ffffffff40000085ffffffff44000085ffffffff48000085ffffffff4c000085ffffffff50000085ffffffff54000085ffffffff58000085ffffffff5c000085ffffffff60000085ffffffff64000085ffffffff68000085ffffffff6c0000857d240600120c080508040202090000fc040507060b0605020fff000005fdfbfb02fdf7f6fcfafcfefafbfe02faf3f5fb0800050af2f7fafcf6f1f5f9f0f8fc02f3fdff00faf9ff00ff040607f7fffffefbff0000fe07060403101312ff0c0c08fa070a0a030e0b090e150a02fb100d09f3060b0afa0402fef6feff011b190c04f0f5f6f7e5f2f9fbedf8fd00f2fafdffe7f3faffeffc0203edf2f7fce6eff7faedf3fafcfaf4f8faf5f8f5f9effbfcfef7f8f5f5f5ff0100f8030504f5030400ee000505f9060402f70404ffe0f7fe02e5fbfe02edf5f8fcedf4f9fce5f6f7f7eaf5f9fbe4f2f9fbedfbfcfcecf6f6fce5eef0f7f0eeeff3e7f3f5f5f3f4f5f7f8020001eefbfbfaecf3f8f9f0fcfbfce3f0f2f8f403060af7050402fc0b0e0cfa020505f8050605fc090a07251f1008fc070406edfbfcfde9f8fafbf1000300f0f9f6f6edf6f6f6f0f7f8f6f5f7f7f5e6f7faf8e2f7fcfbecf4f9feedf7fe00f2fcfefcf1fafcfcf6fcfe00f1fe0200e9fafefee7ff040602100903fbfdfbfbf3f9fbfaf6030504f5060a06fe130f08f80a0b0af6050a0cf1fafe00edf5fafcf1eef1f4f2f0f1f1f8fafbfbf2f2f5f8fef3f3f100f7f4f400f9f4f47f2c0c0609111c19090a0d0b03030100fdfbfbfa0500fcfafefcf8fa01010000fe000204f8fafffffefcfcfafefcfafbfbfcfbfc0f0e0f0efefefd00fcfefd0004020200fdfcfafafbf6f7fb02fbf5f6fcf8f6f7fbf4f0f0fffcfbfa0e07fffa0500f8f7090701fa0402fefafefafaf504fffaf704f8f1f0f8f7f3f0fdf9f5f2fbf4efeef6f3f0eef6f2f4f3fffdfcfb0201fefc02040405020203020000fffffbfafe05fcfc000500050a0b00060d0d0104070bfb01040200ff00ff04030401fe000203030000fbfdfcfbfaf7f5f3f501000103020402010000fffb010200fcf5f5f1f0f7f3f1f3f8f4f3f6f9f9f8f8fdfefbfbf8f9f9f6f4f4f6f9f5f4f5f6f8f7faf90303060601050808fd010406fafe0207fafafafe09080908040808070c0a080808080906050402fe030300000502fefc04020000fdfefcfffe050403ff010404f8fc0001f7fafafdf4f4fafef5f7fb01f8f8fcfcf8f7f9fbfefcfdfd0205060600020607000000030105080800000408fc0003080807090704060706fe000000faf8fbfc04ff040804000204050608040b0a07000f0c0b0500fdfefffefeff00f7fafe00f5f6fbfbfbfe02fff8fbfbfbf0f3f6f4f6f9faf9f1f2f3f7fffaf7f7191b14080e0d08020000ff00fcfdfcfbfcfcfd00fd01040600010307050305080204060bfafb0003f8f7fafef9fafbff0805020000fffcfc0103030402050705fbfdfe02ff000304fa000204f5f3f2f7f6f9fb00fbfdfafaf6f5f8fcf3f1f1f5f2eceaecf2ece8eaf2ede8e8f4ede8e5eeebeceeeeedf2f5f2f2f6f6eceef3f7eff1f6fbf2f1f4f4f7f4f8faf8f7f9fa04fcf6f3fefbfaf80200fefb0903fef8080806000d0b09060c0200fe05fbf9f7fef9fd00fcfcfcfcfefcff0100000204fcfafefcfafbfcfaf9fbfdfd0404030000000203fc010402fbfa00feeff6fbfcf9ff0000fc000402fb020405fc020408f8f9f7f8fcfcf8f8f7f8f8fefbfbfcfc0504000008090504080803fc0d0c050004090c0e0603fefc04fffaf60402fefa00fbf7f3fcf8f7f10202fffef9faf5f3ff04040402090c0c020401fd06080600030200fb020400fc020400fe0202fffdfdfaf9f7fdfbf7f5000100010404060405040203040404040802020408040200090e1010090b0b0a05070d0f01080a0bfefffffc080806040507070702fdfe02fdfe010202040306010304030304040202010102fcfbfbfbfdfbfcfefaf9f6f7f4f2f3f6f7f7fcfdf9f9fc00f8f9000bfcfafaf9ff00fffffe00fdfcfe0000fd06090a090c1014130d0e10110a0d0e1111111111060606070509070603010200fcf6f3f6fcfe01050505060804050608030608070607070904060507fafe000304090606feff0202fd000004fafbfdfceff3f7fbedf3f8fcecf1f5f8e8edf2f4f1f3f2f2f8f7f6f4f8f4f3f3f9f7f7f7fdf9f7f5f5f5f7fbfcfafafcfbf7f7fcf0f2f3f9f7f4f5f6fbf8f6f5f8f7f6f3fefbfaf80700fcf7fefaf7f4fbfaf7f300fbf7f4fef9f6f400fcfbf900fefe00f8f7fafbf8f6f6f8fdf9f8f800fdfefc00fdf9fcfffaf8fafbf3f2f5fbf6f4f50000faf90000fdfc0405040307090603fafcfaf7f8fafafb000504040000020402080c0d0304090afcfd00000000010011120b00fafc0000f6f6fafbf9fc0204f1f2f7f8f2f1f2f3fdfefaf6f2f3f5f300fdfbf804fcf6f3f8f9f7f8fbf9f7f8fafafbfbf7f6f7fbf8f8fbfefcfcfdfcf6f6f9f8f6f4f5f300fcfcfd01ff0000040404050504020207070501020000ff0e0c0604080504000c05010003fcfbf7fbf8f8f802fffdff050607070609090a0405090604070805050709040507070502050401fcfe020000020606fafd00fefafe0001ff020506010102070f11111300071215fd010609fafafbfcfcfcfe01050304070e0a07090d0a04040f0904010d0800fe0504030204010000fefbfdfefa00070b06060405060501000707060505030404060400fc060400fa00fefefe0400fbf800fefcfb0200fdfcf9f6f4f5fcfbfbfb00fefcfcf9f9fafbf6f9fafbf4f9f9f9f4f8f7f8f7f9f8f6f7f7f8f7f3f1f0f2fbfbf8f7fdfefbfbfcfcf6f7f5f1eeedf3f4f4f6f1f1eff0f2f0efeef4f3f3f1f1f0eeeef0eeeff0efefeff2f0eff0f8f3f4f9fcf8f8f8fafefaf9f8faf8f7f7f6f7f8fcf9fafaf8fafc0001fe030406fbfcfcfffe020707f5fb0004f9ff0003f9fbfd0100020204fffd0000f6f9fc05fd01060701020406050607080c0a0a0a0c0805040000fdfd0000fefcf9f7f3f001fefcfc0000030404050408f9fbff03f6fbfcfdf3f6fafcf3f2f5fafafb0205f4f5f7f9f6f6f8fbf9fe0305f9f9fc000002040302040507fe000504f8f9f9faf6f8fefcfefefbf80403040007060302020000fc00fefdfd000202fe0301fffdfcfbfefffdfaf8f9f9f9f8f7fcfe00000004060a0404040707060505060509080505060500020304050504020000000002010402060609070000000104060707090c10130709090913100c05181e1a140c11171502070f11040707080605060708070b100404030503000207fdfc000602fdfc0000fffdfe00fcfbfe0c09070703fefcfffcfaf7f60000fcfe02fefd01fcfb0004fc000507fe00fffefafafbfefbfbfdfffcfbfcfff4f4f6fdfcfefbfb00fefcfdfcf8f8fcf9f5f7faf6f6f8f7f7f8fbfbf5f8fbfcf6f8fafbf3f5f7f9f3f4f8f7fbfafbf9f8fbfcfef2f7fbf8fafefef9f2f6fbfcf0f3f6f5f0efeff1f0f1f3eef2f2f1edf4f6f8f4f9fbfbfbfcf9f8f6fbf9f7f7f9f6f6f5f6f3f3f3f9f8f6f4f5f3f2f4fffaf8f60502fefc00fcfcfa070303fd060505010202070b030200ff0300fe010404040a090904040a0705070504060f060401040b0a08090204060bfc020000fcfeff00f1f4f6fa0102060806080b0e0b0d0d0f08090809fe01000400010406fcfffefe08080c0dfc00030cfc01050d04040a1101010206020200000400fdfc02fefefcf9faf9fbfcf9f9f9f8f8fcfeff000100040501fbfcfcfbfafcf9f8f8fbf7f4f2fbfaf8f9fcfaf7f6f9f7f3f3f7f8faf80102fffe0b0d0d0e0c121514080d13160b0d0d0d06080a0a050300fc01fefdfc00fffefe010100ff06030200040505030706040212120c0b0a0b0d0c050204010700faf40f0602fd0d0a0701050400fe0704030013120d08090c0b0b0b0e0c0c0e0e0e0b02020104020302030000000307080910fffcfd01fafc0001fdfcfdff0000fdfe0504040306060507fe01000203090b0a030504060204040800050406fafe0105fbfafbff00fdfcfffcfbfbfaf7f5f6f7ff00050400030608fcff0506fcfd0105f6f6f8fcf9f8fbfcfefcfe00f6f4f8f9f8f6fcfff9f6f900f6f6f8faeff0f3f6eeeef4f6e9ecf1f5f2eff1f4fbf9f9fcf7f8f8fbf6f7f9f9f8fb0003f7fc0203f6fb0304fc020506f8fcfe0000020502fcfe0104fdfd0202fefbfc000b090507fcfdff02020401030d0e0809040805040808050316160e06040502fd060702fe07070402faf8f7f9faf7f2f5f7f6f3f309040203110d0a07100e0b0d080505050202fdfc06060404feffff010c08070b10110f0a110c0603140b050006040302fffdfcfefbfbfcfefcfe0205fcfe0002fbfbfdfb02020402fcfc0001f8f9fbfcf8f9fcfdf7f6f7f8f5f5f5f3fbfdff00f9fd00fef5f9fcf9fbfdfefc000202fe0e0c070615141612191614130d0d0d0e090b1011fc000205fc000405fe020508ff0104050002050303020004020000fc080605040806050400010202f0f1f5fafbfbff03fdf9fafcfbf8f8fbfffdfc00070402fd07020201070500000a05030007080200060501fc0608060115181511050605050305060400000304fbfbf9f800fefaf80400fe000200fefc0600fcf60704fefb09090601040400fa050401000000fdfcfefffdfdfafcfcfcfbfbfefe0202000006040505070504050602fdfcfbfcfbfbfdfeff020000fe02f8f9fe020204060b060c0b0afe02070afb000406fc000202f9fcfd00f7fa0006fcff0003fafcff04f8fc0006040404050404050705050d11060a0e0c04080d0c06070e0e0201000202010204050606050b100f0a0910120f04080c0c090c0b08000202030200000002020302faf9fcfbfaf9f8fb02010100fc000000fc000200f5f7fcfd05060709060604061111100b0a0b0604fcfe0303060706fe040502000c0e0b0e060200020304050c050b141905090d0d02050c0e03060c0f0708090a04040507fcfcfd00fef8f8fa03000102fdff0204fcfafafbfafefe00f5fafe0002030404fbfb0004f8fafdfef8f5f3effaf5f2ef0400fcf70a02f9f5100a02fb0d0903fe0e0703fc050300fe06050200060301fd02fefd000000010000fcf8f8f9f6f4f50000fcfe00fcf9f8fef7f2f3fbfbf8f4070b0500fefdfbfcfbf9f8f90100fe00fcfafbfa00fcfbf90200fefdfcfaf9f9fefefcfcfcfeff00fcfafefe0f0f0e0b040400fc02fcf7f202fcfcfbf6f6f8faf5f4f4f800fefe01fbfbfc02f4f2f4fafafafcfdfdfcfe02f2f1f4f8000202040004090cfe000404fc000005000101fefefcfbfc0400000007060300fcfeffff00010402060b0d0f060b0d100d0f1515101213170c0d0f120d0d0f0f090b0a0f0001050b0204060b0b0f0f1204070d130a0d0f110a0a0808070707060e11131013131313080504060a09060709040100fffcf8f80300fc0202fefdfe00feff020601fefd0804ff000604ff0000fefe00020000fd01000101000000fefe0001fefdfcfeff00020100fefcfefcf9f7f6f90a0a09060606040204020407fe00020402020102fcfefffe00fffefc0b0d0b090607070310121111181617160c0d0c0e0f0f110e0f0e0b08090b0b040b0f0e0704090600fd00ff000407060307080807fe020404ff050a0c0205040404040304060301fe00fefbf7eeececeff1f2f7f9f7f7fc04f5f6fafcfb00fefbfcf8f6f4fbf9f8f8fcfcfcfefcfbfafafcfdfdfe0000fdfc010100fef8f90001f9fbfe00fcfcfe02f5f5fb00f2f1f2f9efedececf9f7f7f5fbfcf9f7f8faf7f60000fbf4fdfe0001fcfcfefcfefffdfcfbfcfefefcf8f6f6fef9f2f0fcf5f3f204fef7f2f7f2ebe6efeff0effaf7f4f2fbf9faf6f9fbfafb05050302050a0805fe04070dff00020405040606ff040709040606070b09050605040a1002020004fe0204040003070a04080a09010506040105070602020508100d0f0d110f111117120f0e1c1e1b1513131416100e0d0c11110f0b121111101011110f12130f0d17171612100d080808060602080707040c060404100700fc060501fb0603040200000203f9fafcfc030300fe010301fe02010407f9fa00070002080f0007101801050a0d00000000fffe0009fafafcfffbfd0104fe00000000fcfaf7fefcfcfaf5f2f60406050a0c04070e0f0c12131104040402fffefefefcfe0204fdfe000005020204030407060d090605160f0a060f0e0b060c0a0600040300fdfdfbfc0100fbfdfcfdfcfd00fefdfaf90100fefb05040200000000020700fbfe0204040408080807000000fef7f8fbfdf6fafcfe000102ff060704ff02060705fc0004fff4f6f9faf8000405fbfcfaf8fbfcfdfafe020404fbfcfefdfdff000302020506fffcfcfe0402fffc040403ff00fffcf6edeff3f4f0f2f7fbf6f9fafaf3f4f9fbf3f5fafe00020607fcfe0004fbfe000200050607f9fafefef4f8faf9f4f4f4f5eee9e5e5e8e9eceeefeeeeefefedeef1f6f2efeffaf8f6f5030201fe04fffafb0c0a060004060401070502fe0602fefa0601fefa04040204120f0d0b06080508040201010b0805050705040603020609040508080807080a0e0c0f11141515121113120e110f0d0d14100c090b09070508060304100d0b080e0a090805040507100c0906060502000201fffe020204060300fefcfbfe0102fafe030200000000020000ff00fefdf8fefefefbff0000fd08090906090a0a091211100d181a17140b090a0703080d0e0f11130f040b0b0b0404070aff030609f7faff03fd00040710191b1a0a0806060c0a07070f08050500fffefdfcfbfbfd0502020000fdf9f9040301030503020201fcfd020200ff0204030101fcfbfd03fdfe020503030302fe0000000300fcfffcfc0000fcfcff0001020200020504010205030204050806090c0d0a020507060305060704080a06000203040000040502000000fcfb0000fafcfbfb00fdf9f6f6f7f7fbfbfcff0000fd0000fefcfcfe0403040406040200000100fefc0000fefcfaf9f7f3efeeeff5f4f2eefbfcfbfbfafafbfcff00fffc04050504080905040505020106060605050501fefcfefefdfafafcfcf5f3f4f5e5e9edf0f2f6fafef1f2f7fff9fd0105f2f6fa00f6f5f6f8000000fefc01fcfafcfaf9faff00fffdfcfffefcf9f8f6f5fafbf7f6050502000b0a08040c0d0e0c040608080503fefe070705020d0d090507060a080a0a0808110f0e0b0e0806060b0705040a0807080502010305060604050400000501fcfd090605040504050500fcfcfffefbfcfcfafaf8f904020000fefe010301000103020000fefefefffdfefbfefef5f6f4f7fdfe0100fbfa0002020304060402060b0a0708060c0704050a0909070c09090b10100f0f0c1113130c0d0f11080b1017060b0e12080e11121919181905090c0f0406040a0506080902070c0a02060a0c04060808fe0204040508060704020202080806040303060901010000050505060705050404040609040a0e0c02060605fefcfefe0205080701030404fcfcfbfc00ff020305060907050302000401fc00070400fd01fcf9f6050503fc090b06000000fcfb01fef8f9fcfbfcfcf6f7f8fbfcfcfaf90000fcfb0200fbfafffcfdfd02000002fcfbfbfc00020200fdfe0000f8f4f5f8eeece8efeceeefeefcfefcf9fafaf9f8f6f8f6f6fefdfcfcfcfcfafafcf9f3f400fcf7f6f9fcfafbfafbfbfafdffff00fafc00fff3f3f0effe00fe020004020308080807050a0807f9fbff00fc000001f9fefefff9ff0001fc000001fcfcfcfef3f5f7f9f5f9f9f9000000fe040406040603ff0002fdfbfcff00000201020402040203020702000203fefb020603030707060607040607060b0a0906060708080506060404050605fe000100050406090402000400fefe03fcfe0000fc010406000102010506050302fffefcfffcfd00fcfbfc00feff0308f7fcfc00fd00fe0206040400070606040c0705040a0d0e0c09101013080d0d0a090c0d0e0d1112130f0d0b0b131413101b1c1b1913141210121316171d2322220f10100f0d0e0c090a0b0b0f0606050c0b08080c060c0f12050908090b0f1213050c0e0e050a0b090e0d0e09000205040407050404050100050602040802fefdfffbfbfefcf9fbfc02fdf9fa02fefcfafefe0000fffbfafb03fffbf9fcfafafa0002fdfbfdfbfcf8f4f2f1f4f6f4f7f7fcfafbf9fbfefefefafc0102fd0000fdfe040303fcfefefefd010002fdfffbfbfbf8f5f7fcfefefefbf9fafdf9f7f5f9fbfcfe00fbfe0001f4fafaf9f0f3f5f5f5f4f7f5f4f3f4f1f3f0f0f1faf5eeecf8f6f6f8f1f4f4f4f6f9f9f6f9f9faf9f9f8f8f6fcf8f5f4fdfbfcfcedecf4fe0206070703050707060404050201020400000205feff0306fcfdfdff00040402fe000306fe00fdfffcfefcfbf9f8f8fbfaf7f8fa00fffbfbfdfefdfefdfbfbfa060505030000000102000001030300000a0b03ff0b0b0a09080c0d0c0606050604020100070400ff00fcf9f901fef7f5030000fe0a080605040605060406070a00ff0409020102050205080c00000407fe020507050b0c09080b0e0d0c0b0807080c0e090104090d00fe010404050909020204040806080b1011120f080b09080b0b0a0811100c080a0707060a0707081715140d0d0a070213110c09221d1407110f0e0c0a0707051215100c0d100e080f0f0d0e131617120b0e0e0c0f0c0a0c0a040102040002070703000204050605fefefdfffdf9fafa0200fffefcfd0006fefdfe02ff00050cfb00040cfdfb00000100fefdfbf9faf8f6f2f1f4fbfcff04fc040408f7fc0205fafc00fdf8f5f6f6f9f7f4f1fcfcf9f600fbfbfafcfbfaf9040201fbfe0000fdfffdfefefe040803fafe00000002080602040504fbfe010200010506010100fff5f8f9fcf5f8f7f3f6f9fbf8f1f4f8f9f3f5f7f7f0f5f7f7f9faf9f8f6f7fbfaf7f6f8faf7f7f6f6f5f4f4f5f4f5f3f3fcf6f5f407090606070300fd080200fd040404030201feff06060403070a0c0d000003080405050508090a0801050506fbfefefefc000406fcff0105fcff040700ff0205faf8f9fa00fbf8f9fefcfaff0000ff0100fcfbfcfc00ff0007040404080505040305040702060b0efcfdff04fafbfbfef3f5f7fbfaf8f7fa02fffc0202020004080703000d0b0907060704050d0a08050b0c0a0808050402040200000c06080406040404050100fe0d0d0b07060806050b0c0a05070c0c0b0c0d0c0d0e0b0e100607080c08080706090a0704070707040602010308040407000204060300020104fefcf60a080808040401000605040204080d0c0e0f110e110f0e0a090a0d0e0e0f1214090e0f0f0c1212100a0f0f0e0404050600040608fc00040700070b0c0a0e0e0f070b0d0a11120f0b0f12110f04070d10fcff0207fbfc0104f8fbfcfe07070705090b0b0605060605feff0100f7fafcfcf2f6f7fcf0f0f3f8f9fafb00f8f8f8fbfcfaf9f8fcfaf6f8fbfafafcfefcfd0200ffff000601fdfd0402fffd00fdfbf9050000fcfcf9f6f6f8f5f4f5e9e5e4e3f4f0ecebf5efeae9f5eee9e9f7f5f2eff6f4efeefbf7f1eefaf5f1eef6f2f1f3f6f7f6f7f7fe0000f8fafdfe04020306fcfafcfefcf9f7fa04020002fefeffff00f9f8fb0c0a08070d0a0603060504040806080606060807fe00000007050502090f100f0d0d0e0e070b0d0efc020809fd00030500060404030a0f10fc0106070204040505090e0d0406070e0a0f0f0e10141415060c101200070e1100080d0dfd05080a060c0b0a050c0a0603070a0b050a090b05090a0806090a0c06090a0904070d0c0004070d05070a0a04040407fcfcfcfc0403fffc0000fefffffbf8f705fffbfb0a080603120d0b060d0805040505020004050502040002020608080a0a0a0a0e0703030702020402f5f3f3f20600fdfbfffbfbf600fbf9fa09fdf6f10c0500fb0c0703fe0a01fbfa110c05020c0401ff0d0904040e111211090d100f101214110e10130f0a080c10101314120a0c0f12060402060b0806070d0e0c090c10120f080f100e02060b0c000002060000000204030302fcfcfcfff9fbff0200050400fc00040600020305fbfbfafbf7f5f6fbf6f7f5f5fcfffffe0406040402050402fe030504fafd0106f6f8fcfeff0000fef7fbfbfef8fbfbfae7edf3f4f0f4f7f5eef4f8faecf1f2f0eeeff1f4f0f3f6f8eceeeeedefeeefedf6f8f7f8f6f7f6f4f9f5f2f0fefbf8f709080602030200fd0107090802020204000000fffefd0003060200000401fefc050807070604030404ff000401000405040406040e0b0b0b121211110804020302fefcfe05020202010000ff0b060404090c0d0d04050606100f100e121414120a070403120f0a0710110f0a0e0c0a040a080b060a1014140b13141204080b0b0a0e100e050204040500fffe0807060905060306060200070a090a0d0904010208060304fbfd0305fcfeff00fcf9fafbfafcfd01fcfafbfb0200fffd0807070502fefbf9fefbf8f800fdfefe0200fefe0d0b070311110e0c0d0d080504020100f6f6fafafd00ff01fafe0202fe010408f5fafe00fcfafafe00010409fdfcf9f4030200fafffefcff0202fefe0d060302100d0c0a0f0703000f0c07051617130e120d0b070e09070408080706070605040507080a0c0c0a09070200fe0501ff0207090d1101060b0e0204080a02040907fcfc0002fefe02040606070406060402fc010204ff000103f3f6f7f9faf7f6f5010100fbfdfdfbf80404040105040502fdffff01fcfdfe01fafbf8faf3eeebeef5f6f5f3f7f9fe00f9fafdffeff6fcfdf4f7f9fbf8fafcfaeceef4f6edf1f5f7fbfefcfcf4f7f9faf1f3f6f9f6f6f8f901fcf4edf9f5f3f802fcf8f902fbf9fcfcf8f8fc0500fdfc01010406fc0002060804020002050609040204080504050c020406090807080c110f101205070b0d0004080d04050608fffe030404060a090f100e0b0c0c0e0c0f0e0d0c1212110f04040a0e050b0b0c090502ff0300ff0005040402130f0c090f0f14140c0d0f0f0c0b0a0a080300fe0000000208080807070808040c0a04000c0703fd0406060604050505060400f902050400000100ff0504fef9fbfbfaf9000000fd06080607fafe0002fafbfafc00fcfbf8ff0000fd010402fe0e0c0a04020402fd0100fcfc02070908040402040304050b0b0c0908050604ff0100fafa0904fef7f4f4f5f5f6f5f9fe0001020000020504040203030806040200fefefffefcfbfb0702fefe04fefaf900fcf9fa04fdf7f7040403020a08050408050200020305030504040510100e0b10100e0b0a08060907fffbf802fef9f502fdf9f600fcfbfb0000050903070b0e05070408fbfe0004f5f6fc02fafe0205fafe0506fe00040402ff0002000200000102040afbfe0306f3f7fc00f3f1f0ec03fefffcfefefdf8faf7f9f5fbfcfbf9f8f2f4f3f4f0f1f7f6f7f8fbf9f8f9fbfaf9fbfbfbfcfefffbf9fcfbedeff0f4fc000204fb00030502050c1102060c110204090b0b090d0b07080b0c00000105090506060e110f120d0a0908080a0b0c0b0c0f140f0e10130d0e111313171516090a0c0c0b0a0a0a090808080200fafb0802fbfb070400fe0e0801000e0c08050c0d0c0b0005070602090a0c060c0e110a090504120c06060c0603020805fef9fffefbfa02020202050300000406060703060503fbfbfbfa050702fd0400fffff6f6f5f6fcfbfaf9fe000000f8f9fafaf8f8fbfeff030609040507070004040403040c0afafe0507fcfa0003fcfc0002fcf6fc02f6f4f800fdff0407070c121205040404080604030a0400fffeff0202fc000203f7f6fafbf6f8fdfe0001070afefbfcfd01fefefc050300fcfdf8f5f4fdfcfe00fbfbfe00fdfbfcfbfafcfaf70001fcf7fafaf6f30100fefe03040202fcfafbfb02030300070a0705070303000905020107050200f5f3f3f6f3f6f7fafa00fefefbfdfbfe0a0a07070d0a04010605fefe070603ff090f100e06080809040105080707070b03020000010100fe0d0c0a0a07080808080b0f0deaebeff2fdfbf9f9f5f1f2f4f5f3f8fbf7f8fafbf5f6f9fcf8f8f9fbfefffffcfffdfcfdfaf8f9fbfefeff01fcfc0206f6fbfd000a0f1113060b0e12140f0d0e0e0a0506090606070b080709070500ff0708050306050506120d0b06090805010c0c0804120f090614110f0c1310100d10120d090b0e0c0b0b0e0e0d070a0b09fc010504fc020402000200fbfafbfd00010202040c0c0b0804060706070400fe0e0b00fb0406040005050200000201fef9fe0202fbfefffe020200fe0000fefc0604fffe00fcf9f4f5f8fcfcfaf9f9f9fdfbf9f8f5f9f9f8fafbff00feff0100f8faff02fcfafafc0600fcf90502020001fbfaf908fffbf90500ff0003fcfbfb02fdf7f805020201050400fe0701fdfa110c0e0f040001000200fffc0000030204040300020400fefefe0302000001020c070704fd000204fcfbfcfef7f8f8f9f3f3f5f600fbfafcfff9f7f7fbfbfcfef9fafaf8f5f6f5f6f3f7f8fcfe02040701040300fc020102fd000304fdfcfbfcfeff010200020102fdfdfcfefc020404fc050505fe000200020504030505050600000204ff030506000606080b0605010a0c0805090a06040e0f0c0b04090c0b01040404080502000503000007fff8f9f5fafcfbf8f9fafcf7f9fbfc0000fefffe0000040102060b0002060bfbfe03050304060800050c0c0306090f09090b0c01040407100f0e0e1310110e0f10111205040406080a09060b0c0a06ff000203040407070608070905040405000004060304090a04000205070504060b06060a0401fe010a0b0d0d0c0f0e10070806090301020304010205faf9f9f9010403fd040400fb040200fe04040402fefcfafaf5f2eff3fcf9f8fafefeff00fcfafafc00fcfcfffdfcfe02fbf8faff0002020200010100f5f6f5f8fbf6f4f4f7f7f3f4f7f5f1eff9fafafa04020400fdfaf9f902fdfbf9fefcfaf8fafbf9f6fdfcfcfcfcfaf9f6faf7f2f1fefaf6f3fbf9f8f7fafbf8f30202fefbfefcf9f9f5f2f1f40f0a070600fefcfbf8f6f7f50100fefcfdfcf9f7f9f9f8f602fcf9f6fefaf4ee00fefbf801f9f4effcf9f4f1f6f4f3f4f7f7faf8fbfbf8f6f4f3f4f700020303fc000408fbfc0007fe04060b05090808060505020002020104000204fdfefcfa000100fb01020100fcfcfbfafefe00fe0000fefefbf8f8fa03fffcfa0704fffe0402fffc0604040406070500fffdfeff04070b0b02020100070404040805020102fefefe00fffe000203050500070e12f6f0ecedfcfbf9fafefaf7f6fefefafa060402000d0c05050c0a060606060608080706060f0e0c080e0e0e0f11120f0c07070300100f0b0a0d0a0705120e06030502fdfc0701fefb0603030402fefdff040806050809060803040607050401fd090400fc07080a080c0d0e090f11110c050e13120d0e10100e1012110d121413080c0c09080d0b07f8f9fe00f8f7fafaf7f8fcfcfcfbfcfe00fcfcfbfcfcfdfcf5f6fafcf9fa010401080b11fc040e120003060503070a09040308060100020500020404fc0001fdf4f3f5f6f5f7fafdf1f80006f9f8fe0000000505fafbfbfcf8f6f5f3f6f6f6f5f4f5f6f6fbfaf6f4f3f0eeedf2f3f1f1f1eeeeeff7f8f8faf1f3f2f6f9f6f3f2f8f9f9fcf6f9fbfc07090504f9f7f7f9f5f2f1f0f7f4f1f0f4f5f1f1f4f4f4f7f5f6f4f6eff1f4f4f2f5f8fbf0f7f8f9f1f7fafcf4fafefef7f8f8f6f6f8f9fbf8fbfcfe060603fd0a0a04000b0c07040805fef6080606030102040300fcfcfb0300fdfbf5f3f4f6f7f4f4f4fef9f8f9fbfcfcfcfdf9f9f8fcfaf9fbfcfdfefefcf9f8f700040605ff020302010000000001030404070b0a050506070002030302fe000000fdfcfbfefafafd0000000003fcf8f913100f10f5020a0efbff0004fbfe0203fb0001030305060605060506090d0808050404040505070c080807060e0b0b0807060a0bfefcfefe0604050502fefe01fffffe00fbfcfdfcfaf7f8f80301fcfa0000fcf60401fdf90502fdfa0400fefcf9f9f9f9fafbfcfc02fe010404040407050300000c04fffb0d0402fd0c0600fe0d0702ff00fcf9fa01fef9f7fdf9f5f3f9f4f2f4fbf6f2effdfbf9faf8f4f4f7fcfafbf900fcfcfb06050401120e0700100700fa0400f9f702fbf4f104fbf6f40400faf900fcfcfcfafaf9f6f8f6f5f4fffefefb060401010502040205040200fcfcfdfbf4f8fbfdf3f5f4f4f2f1f0f2f1f3f800f1f7fcfef8fd00fdf6fd0102fc000302f7fcfcfef8fd0206fd000001fdffff00070a0c0af8f9f8f9f4f5f7f9eff3f6f9f2f4f5f6fafefcfbf8fcfe00f6fafe00fe000405f7fafc00fd00ff00fe010204f6f9f7fafafafcfcfcfdf9f7fcfc0000fdfefffefefcf9faf4f3f4fafdfaf9fb00fafcfcfcfcfcfcfafbfefef9fbfefcf7f8fbf9fbf9f8f8fcfbff00fc00050700000404fefe0001f7f9fcff04010002fe01080aff00040601fdfbfa0400fcf904fdfcfd00fdfafa00020002ff000402020200fc020000fef9f9fbfe0a02fcf80c0f0c0703060a0806070c0e04050a0d050607090305040607040402050402fe100e0b0704060607050402000b0806080201060e0805050406090d0c050a0d0dff000000f8f8fbfff8fbfcfff5f3f5f8f4f5f7f9f7f5f7f9fbf4f4f4fbfcfbfcfefcfafa040200000908090afffdfd00f8f7f7f9fcf9fb00fcfafc01fbf6f4f8f9f7f6f9f4f2f5faf2f4fafdfafbfffef0f5fbfbfbfcfafbf8f8fafdf8f8f9faf9f5f4f600fffdfcfaf9f9fcf4efeff4f4f4f7f9edeef3faf2f4f6fafbfd0004fbf8fbfff0f2f2f4f0f1f6faf8f6f8fa000000000406060402030808f8f9f9fb00040603f8fbfffff7fafbf904030200fdfbf8f8fefbfbf80000fdfefffefaf8fefcf5f1070500fc0201fefcfefefcff0b07fff8fbfcfefffcf9f5f4fd00fefdf9faf9f7f9f9f9f9020300fffefefcf80402fdf90001fef900fefbf80301faf8f8fcfcfcfbf9f4f2f2f1efef01fffbf6fcf9f7f4f9f5f5f3fcfdfcf9fafafcfefcfe0002ffff010000fe0000faf7f4f4f9fbf8f5fafaf9f600fef9f50505fdf90300fcfa00fffcf8fefefefc050606010e0c080108090805fbfdff00f8fbfafe0102fefcfbfafafcff00fe0100010201f9f9fbfefcfbfdfefbfcfe02fafd0a1600090e1607080a0f0f0e0c0b0c09080a0908070a0607060504040204fefe000302fefc0104fefafcfbf7f6f70400fbf5130e02f5040100fe0b0500fb06fff7f7fffbfafafefefbfa0202010100020202fcfefdfdfcfbfafbf8f9fb00fcfafafafcfdfcfa00fffefd0b06020000fefcfafcfefffa07060701090c0c05020b0c0701040401fdfaf8f9fefcfbf8fefbf8f4fcf8f8f3fefefefcfefcf9f4fdfdfbf6f8f9faf6ff0000fb01020400fc03050202040401020604ffff0204020608060403040505f6faff02fcf9f6f9f9f6f7f8fefcfcfc02fefefb07080a0afbfbfe04feffff06fdfbfbfdf7f7f5f9faf6f4f8f5f1eef1f5f3f1f3faf3edf0f2f1f1f2f0eff0f6f9f7f4f6f9f8f5f9fdfcfafbf3f3f5fffefcfafaf4f6f7f9fcfbf5f3faf7fafcf8f8f8fdfcfbfcfcf7f7f9fdfafc0002f7f2f1f0f6f5f5f7f7f9f9fefafafbfcf1f4fb00eff4fa04f7f9fe04f6f8fc00f5f7fafcf9fafaf8000000fc000000fcfefdfcfbfdfafcfbf4f7f8faf3f7faf9f4f7f8f7f0f2f4f7f2f5f5f6f5f5f9fcf7fb0205f8f7fbfc0001020000ff01ff02fdfcfafefdfdfefffffdfefefefefcff01020203070809ff010404fefeff020002040301fffcf71e170c01181d211e121417180c0d0f11080706080a0d0a090302010003020000080a06060505020302030304f9fcfafdf1eff0f3eae6e6e9fefcf8faf7f6f4f6fafbfbf7fbfaf9f8f8f7f5f600fefbfe0001fdfeff00000001030607060a0a09fffe0203fbfe0002fefdfcfffffdfbfbfbfcfdfdf8f9f9f8fcf8f9f9fefafafb03fdfcfafcfafafbfafcfdfcf6f6f8f9efedf2faf2f2f2f4faf9f8f9f3f1f4f4f1eef0f1f2efeff1f9f7f8f8000000000101040400fffe00fcfbfe0000fdff0001fffeff0705050607070907ff060909fbff060900030b0cfcfe04060a0b0c0b080c0c060a0b0802ff00fdfbfcfbf6f6f6f4f2f5f3f9f7f5f9fcf9f8f5f8f5f1f6fafaf7f9fcfbf9f6f8f8f7fafcfafbfcfcfaf803040102fafbfbfaf5f4edeeeeeceaedf9f5f2f0fefcf6f1f8f4f0f1fffef8f80001fdfcf0f1f1f4fafcfbfc000000fdfefdfaf9030504020b0d07fe0404fffa040200fbfdfffef9f4f3f4f5fcfbfbf8fafafbfaf8f7f7f8f9f7f8f9f7f6f7f4f7f4f4f5f6f8fefefafc00fff9fd01fffffe00fe040302000000040001000200fefcfcfbfaf9faf9fdfbfcfdfefe0000fafc00ff030002ff090a0905040304040404060402020508f4f7fb01fdfcff08180f121615120f0d12110f090c0e0b0a070c0a080507070404070602060601fc06090400050604010000fcf7f5f7f5f7ecedecedfcfdfbfaf9fbfdfcfafcfefffafdfdfaf6f7f9fbff040609fe00fcfd04040401090c0b0b0a0c0a050708060404050607fffefaf9fcfdfbfbfcfefcfaf6f7f6f2f9f8f6f6f9f9f9faf7f4f1f0fdfcfaf9fcfefffefbfbf7f3fcfaf7f6f5f6f6f5fafdfdfbf8000405f5fcfe00f4f7f7f7f8f9fbfb00ff00000400fdfc03080a0d03060c0f020200020306080a0809070807070401080705040a0704040903fefc03fcfbfe0804040200fafcf802010405fcfe0204f7faf9fbf6f7fa00f5f6f8f8fbfcfcfbf2f8fcfbf5f6f9fcf6f4f5f6f7f7f7f8f9f9f6f8f7f6f3f102050606f6f8fbfeedeff3f6f2f6fafcf1f2f8fff0f0f2f4f2f7fcfcf6f5f4f5faf9faf9f6fafcfb000000fc0000fffbf8f9f9fbfcfaf9fbf5f3f2f5f8f7fafbf9f8f7f9f3f1efeff2f1f3f6f5f3f6fbf8f6f7f9f7f6f9fff7fbfd02f3f1f2f7f3f4f8fcfcfafbfbfcf7f2eefffefbfafefe0001fffcfbfbfefcfe02fffe0104f9f6f7fafafe0404fefc0000fffafaf9fdfcfe0000fafafb02fcf9f7020200ff03050500090b06020a10110d131e1a131919161108060404060303000604000000f9f9fc02020404ff000100faf9f9fcfdfe0000fffefffef5f5fafdf8fcfe00f2f6f7f5f8f7fafcfcfcfaf6fefffcfbf4f5f2f3fcfcfbfa0c0c070500020202040405070905060600fcfd010505050206050400fafbfcfcfd010404fafcfffef1f2f4f7f8fcfe02fcfffefef0f4f6faf7f8fafbfcfcfbfbf0f0f4f5f6f7f7f8f4f4f3f3f9f9f9f80000fcfc00fefcf9f4f2f0f0fcfbf9f900fcfbf9fcf8f9fd0e0b0a0d100906080100fcff0c0d0a070c0f0d08fffe00fd04050404020000fdfbfaf9fa0100fffe04050400fcfe000007090d0c04070805fbfdfbf8020200fdf8f9f7f6f6f6f4f4f9f9f8f8ff01fcfaf8fafaf6fcfefdfcf7f6f3f4eeedf0f403020405fffcfafaf6f5f3f30101020204040405f7f8fc00fcfd0104fafbf8f4f9f9f7f8fafcfcfcfbfcfaf8f5f1f1f3fbfbf8f5fbf9f8f6f2f1f4f7fe000201fbfefdfcf2f8f9fbfafbf8f6fefef9f7fbfefcfe0407070606080a0bfafb000300020606fbfbfafaf0f2f6f9fc00fe0002000100fe010607070c0d0d090d1212fcfe02050202050800fe0003f9fafc0200fcfc00fcfcf9fcf7f7f6fbfbf8f9fafcfaf8fbfdfbfbfd0500faf70602fefe4300c0000f0000009b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a0908060c7400004a25c210386e2d4466a3f5455b69c5f8e6ad67cdf4d679ad9c115dec6cc51af3be65c436ef6ddf86bf5bedb3ce76ebacfbd6d65297f5a3543e7bb977af629c2b8ce628140a6b0000')), # noqa
response=array('B', bytes.fromhex('0000880200305d000000eaf5f9fbf7f3f1f3f9ff00000000faf9f9ff00030202070b0b0904070b100f0a00feff0202010407080909060203040607060604040409090b0c0a04fffbf8f7fafcfd010404fef9f8f9fafaf8faff0202fdfbf9f8f6f5f3f4f8fbfd00040603feffff060a0b08020201040407090d0c10232e10232e10232c10232c10232c01065010240101000007c8078c06ff00004f8a006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c070303072004020000000090020030000000000000000000000000000000000000000002000000080200001c020000400000001500000000000000020000000000000000000000380000000200000008000000a0120000c0120000a4120000c0120000000000000000000004000000020000001a0800001c0800001c08000000000000c00000002f00000003130000e0120100a0480000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000a81200000000000000000000000000000200000000000000b01200000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000c800000018000000695a7ea50000000087040000000041017897a601fab8a6010000000000000000000000000000000000000000040100000c000000200d33330300000000000000ff000000000000000000000071c3000000000000a5000000000000000000000000000000695a7ea50a00000000000000000000000000000000000100050000000000000000000000100000000100000031000000040000001a00000000000000e001000000000000000000000000000000000000949b0200a4580200f4c60300305802008c5e0200ac620200a01b02004c540200685c0200f01c0200f61f0000b75d0000cbf70000fee20000ad910100ffe50000dcdb01007fdf0100ffff00003bf90100e7ff01007ded01007fff0100bfff0000fdbb0100ef7a0100f9ff00007fff01005fff0100eff70100afdf0100cdf90100fffb01007fc50000bf7f0100fdfb0100f52f0100ffbf0100ef7f0100e2560100064fc7410603da80bcc27d5006ebda2c06bdd90c06efd81006ebea6106d556000677db0c0636eba1f5bf7fbcd9fffb77755ceaffbfafbd7afdd1ffdb35eff7ffcffeccecfdffceafdfefffffbfbeb72b1d7efff8ff5335ffff17feedffbfdf77bdefffde6fbff3fcd77d77f76fe7e7fff1ef1c55f71cf4ef91fb7f9befef7ddfef4feec5fb2caff3ccbcfefabcfefd2bff7f7fcdeff37fcf7ebf1fffe52dfdfe0000000020000000000000000000000000000000010000000100000038050000817e0000ff07000003000000010000000f000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000010000000000000000001e0000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000980100192800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff0300000000000000000000000000000000000000000100100000000100000001000000010000000000004003000000010000000400000000000501010000000000000001000000000000000000000080000000000000000000000000000000000000007736000000000000000000000000000000000000000000000500000001490000014100000188000001800000000000000000000030000000000000004a0002002a000a0001800000000000000a0200000b19000000000000000000000000000000000000030000003a00000014000000020000000100000002000000f503f503a101a1010000000000000000e803000064010000d002000000010000000000000500000000000000050000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000')), # noqa
read_length=2048,
exact_response=False
)
stop_acquisition = []
stop_acquisition.append(Validity_Messages(
query=array('B', [0x04]),
))
stop_acquisition.append(Validity_Messages(
query=array('B', [0x52])
))
is_image_ready = Validity_Messages(
query=array('B', bytes.fromhex('7800000000')),
)
message_read_image_part = Validity_Messages(
query=array('B', bytes.fromhex('78c0120000'))
)
interrupt_ready_response = array('B', [0, 0, 0, 0, 0])
# I believe the The protocol is as follows:
# Bytes 0 and 1: error codes
# Bytes 2 and 3: how long the following chuck is
# img1[2] + img1[3]*256
# Bytes 4 and 5: Unknown
image_ready_response = array('B', [0x00, 0x00])
image_not_ready_response = array('B', [0x01, 0x00])
image_error_response = array('B', [0x12, 0x04])