python-validity/validitysensor/blobs_90.py
Arvid Norlander 9dc0c14aed
Automated formatting with YAPF.
PEP8 settings are used except the low 80 column limit has be increased
to a more reasonable 100 columns.
2020-08-06 11:46:19 +02:00

366 lines
37 KiB
Python

from .util import unhex
init_hardcoded = unhex('''
06020000013917b3dda91383b5bcac64fa4ad35dce96570a9d2d974b80926a431f9cd46248980a263c6fcef6a82839a90b59ac590848859
afac817b7d53bf51cd3205c1b8f43048be8253c3bd247937c837aca8b18d3cc8ee8c8971ac4f688813cf3d8550d71496985b7ec07ff2dc7
896d330fdab263a0ee433a5c4bc910439d1c6161853feb03f5502209502e7308beb7919473cfe69f422c30502d226a4d0a34d96c8c77956
cf69db8ef6cf927a3b57849d4aa8ad4b44266923e34b82a39c8146ba3cd708c70dfedb50c2de61feb45b1d4f19584297203f5fdc865795f
ec9d6449f3ba9b6f1e4bed698ee151e83d4d8702f76a4006cfa24d9b797888203b2269f8a77d524034ac32e4af58b86ebc63552cb35b12b
285255deaf3a32bf46cdc5ad3bc1c9ed1bcc112c72143f9aec568e2cacfa89ba0c7bb65590d8b93e6871a33c6c6983c0acd04e737ff55ee
e024ca6b9a48332c1a69a5a3fdd24b964cf7e7c55229bb0b48a6e339eb2c42d07ec850a4ee780660ad6c77ffa302a63bd19426134c4533d
6f967441163fb78b73547c68a493b2f800d3cdab827b116762789992aae3c8ab345a49edd312dfd2a27bc501427dc7fa00ac3c5c36551db
b3d5cad8d5bd7cea37e58a31307a6d50e6ae379a53f1366678c0741a3d872b8dcfefa7f63128dc8245
''')
init_hardcoded_clean_slate = unhex('')
reset_blob = unhex('''
0602000001d6123241376f110935a7ae38b614ced9952eaa38e2984842d0552d984b69ab5c1a70175513319970225d9ca25be063a7d70a2
9dff803240c099ba5386910b69c3b7ca8d0b26ec9a5684fe92af9c6d8068ace0954eb8582adc6208aa6c116b1778ff531dd2b6817a10d66
7e0385d18ac7ccb47eb67f1f54b5b94c84d65529c6e9fe9039218ae9cde123f38ffa52a953ed589d0d8bb48680aeea6544b7ceedbea3216
615404921b43859facf8ed4448e585354c568fe8d9561efb3fc9b88af8e6c3c7c02ac9b44adbf780d23730135c1f9840b67b302b6efe9db
19ee1f5918740dc0259b3cbdd4f10e59d1a517f54e932bf01d2b1e5ad5c4f71af23373632e06160f83799a0a1b2479d9bad01892667d136
e27463a0eac485541f24018bd80463cea17ada264cc760b38a0ac87b27539b72e1c4f05d73f6c9c777b2e70c366f1b79d31ae2dd1eebbda
992390c64c988c5e04e3b4ababa8c0fbaa33da18a097b609562f609ecde2443fa9b315667c95fb62abedbb8887dbcd965a1cf351c795ca4
f5cc6e22e844cc813fcceb34741f5c988dd38d31ea3bd3cb373162efd3d5744268c1c9a5b679c97e2356c7b1de146eb675597884fda01e6
6360b807e04c4e557ccde2a29df1030c0da4750c9314c551b6a5061711c6aa1a01564933218e2a9938d8a158a17da154969dcb3aedfb8bc
e12024b908e7e75b9a8f44383a4a7c3a35632054ef1bffa4137e0f4d724c3a06a96fe986a339ca4f27744708feb6523a31aa4e2a19d1567
964d52b568259cdcc602c7ebb468bc5846a9183a56917e3f440e522206e7e0e06a07aed6b680e0bc818217bb4dfb2010ff503be6d3e555e
e1af32edb3f02f6906cdcef6053a851e799913157220c563ddcc47cf7665fede1336f152df1d1c6d145a535e59dc41b7963bb520e66dc12
a21eb5a900f939b7838f274d9ebb7cd0c2951f2b9379b54f20bc50ee6ec2dd09d7af7b9f027261c38f056f3f1b953cf21bda1f5a9caf3b0
7d160f80c186fc5eaa42074d041eaee81518fd2b463112ae6a6c07a185e8c24101ee14dddc4409ce7fcf9a18955bbeb8c7146dcd92ab165
e20484c2b316acb3d9dd2215c5b7f4eb8954202628635a46b463e1b2d35c466eedc3c49951222840959db8eb1112f32fa952d72f2ce2f62
97646ebaf53dc1c0ec484fb703938f4341f21c157fb58dc101e3918053d8abab75c9300b2912f840bacdfb4e27416bfa3a945de6cea14a6
0f09d57e6ec7ee83f5616a9fbf0952017420f857b35fcaafdf7af50446c1e7d2624f9cc4a187af0c6ce6c118ccd4234d991402c0b81dd38
bb523a2ecfcb16896fe16aefe7bab3ded4f746049e1d38e6f8d7130bccbac4b33bf543d9c4929b7a6247d1d4f9d5724e6040f5d4a357041
fa07a8ad998110ca30a3ce6ac9fed580034adb66df8fa8643ad3eccfcff6ccb8df0756ff426aa9dee01d656fe699f091611c5d68688b3ee
28e320d9ee2966a5cf146c13013fc4ce353c203689a38e0437805711141900ddfa13c5425e5c6aa5447c13a35893696ae04587901992071
dedce8155f273581f0ba35b7b23c7b865149945be1bda2233a7b5b4e2f5530170ddd8fee44229a2bbca2622172b36831445d4c9ec9be1dd
b14de7eab8593a6e5389cc260fb453e3062b5862ceba83dd355ab50d859bd47215c844086ef0f8d074412590eb8d1633bc21345dc1aaca9
420fcf354ae43efcdb9a0b3c9422c6634c6e15a01d21d1cc645bb6f3e556de2c17471d4c68aca86ebc700efd31fe9eba3c31d18c33d4b94
8441bc6f6682962018dd0704bdeb78fdfb457c70075a45397668c85ac26e13c890d1c980c2b85602f99538c649fe97a01542f112918b68c
dc0b9e59f814e25e3dbea24c8a36b064ed7f2c924c0c45e712a9ec9339eebbe4278b1ed7fefcd7d60c27ad80a978161e36f718f3b52fd78
37454f04b43438ea78dbe7badf356ce99e4dc3c9749d90de6d630c88e58d8f6f828759dc14d742ea4b6232efd05da4cc200732a4fab8b9b
c8896233432333d344acbdeba7eb64634e8a91919efd81f4b848511c181f3f45ba45841cb235b47745882cdd44baa44ec8f7247c470f412
31b2c663243068cc309aa890ef1b79f8fc438a517b903d4e35a1dbe1ecbaa2df887a1fa18af39c4cfe90104d330fa1b99ef3f1ee8276cad
45074bfb5ec5fd72cf5b9969cbc479375bd2be271d0a8322e50f1b0c3b2c66cc0088a3e4ca6d727679833243386c441e46c25084e37621c
4a3a6774568f65b9d2f506fe698322973ddcb94886159f55a967880f56933b066ada7fdeb861ee431369cd926ee3b088f9c5e852aed064f
a4004fc658efacc3fec6cdc1150bd1b3183ff52cb62d598baf172126afb3d8b3eba65db880f3307078d9f263bf261bec797db705300f635
796775d0e8d2a964f2b51ad769561b2244a48b5f9767f71da4856c329eb5a8a58ccab1993fc0f93f3491991312406c2797e5b08a0ef7172
8e8cc3adcd23d29b7248c328b192489bec81c56be0087cf38653e4148a8065121ff7c6ad4f8aa4bcaa375f566a8c617d59abcd6c3b0aa13
ea4590e5e37f47bc276f0f3cbfbcc0f159e4e411e3b42a5fd2c440bab916117710208ef6f113ea82709d5e0f5cdb68fc376fe707f2600db
2f5bbef6569fbd6cec364621f30445b161d3faef69fa840c87a301604e351b6b25db6a7d20c86c1d3d4d28ebf88850f60d7ac0c1e36e1d6
29f76f07aa65de78bc9b33324ae53312cd15d5cf54175dd0dc9b2b90583d29290a72569a5e3f1d7edec3195da0ddc547567c948b1b8bed5
df3fcdb56f9b0c625aa288fd57815961014298da72d516ce020dc73563c0d34a7463fa869adbe24963d8f12c80d708b8f8510abd66d9047
bd6d14db5815948fe2708ac584a6e0a6a0be66bd315ae1fb7dac0be365910ab0eeec78c9f4b4209415943ff055bce11c621628c5932060e
b516c260d4c3da41b046a2876cc11eb59078d550bc883aa5722139a076123c4dd2debb7da792bcdaa5ace368f8f7d5c95ba0e7397393afe
1d005cb89bba287b6ca2440295bd9c3e83a195ffcd3a853617b1d4c8b9fe1a7f5e4d4817e7e22d0d41255d044b271a653de5c6ab31b17d6
79c5227d1fba14f5de53125424a5fafc7cedbdf560374c7d4e52d04b6fcbb725108ddc8e08e5b4fefe9ef565fb02cfaa3e56de4377c6cb8
36cd0207bfd002522cc850380c39fb66bb92e309c26cd05c97d54ba055ad500f23c2cac8ce1fce29b4c623657a42058196c3fe635ecdb7e
77a01a2114adac63f141169df1f3cdf1c86fb6e34fc419d686e620a427df4d9034970d6618896473b213f1933c533985f45c9197679ca03
a6c6b9b9893492ef8a712b38d317618b6ca000bf0b5134845d6da83c9d93c3785b36ad9155cce63f74fdec88e03b69b6db32265cbf57344
cda57e5f55d26e26576125feddaeac0141cd43dc5e906babc5162ad9c90bf623816ee21de2914c9142f32e28f489858cf931edae30e5b53
a5e6ad8c6d74fcd0f490cd8d01904d07a8df31c6938f792319bf7d03a04b69c58b96b23d4993d10846d436c618401ff97558841489c0b7b
1be5a8d452d4070026d4e240a9ad749b44cf8011b1aef37b789782b0f8e17460d3c43e92555c413489baf2ba1e01ca64eb58f3db61b3921
981bdc7f005858015a987c457a9df8a35cfb70b27777e7043eb0ca06a65473ab3c503955b5a743c89d341c0a32e69047e5d9cdaca901e06
c1b2d11fe1eb275b8d292a992a5bdfbe29d436c03fc0c85f2e5c5da3ba8a18a8b395aef869cc217afd64dd2a748d21535d89a94f64d3704
5f0b28f73315f3d8f420d3082bc3c33a96151812ae683fcde4c9b64e96ce5c463c93c15af02649c7c56ed308c9d386216c88b1eaa87717c
96852e80e6e544d4c3731ec34affe43bd59d1e5a3e286f23ac596c301d1311e98616b6870ae41dc3f4b62c1e8019c7d94bfbcac812a74da
d0e12efdd0842a750c4e65e311c0b7687c180475acca570988f1399f85dec169f4674895f9ba21719b752f4b5134f036af8a6250caf0692
8c5d4c63bab25a9f530f6f6b3b8cc4befaefac68a2b100d64a9fc90004dc2c7ffe32ebaa31ca3714a47d32b23ccd34631943870cca989a1
1e3988ad9a884491fdaeceadd08e6eab8761d6e40b5c6bb5c6be57d879635c7899aff67d3e0ce02fcea2bcffd437434e98480a7388e86be
96c08be01d38157a2021e6b6e7767b253e5e490d19c007d3a55f54d42d5068d574e94c252241dd0ba637e81b35255d26c4011564dc04b8e
824c51c0635c45be6568ca3e4b8fe4b18ef259fdf0598005f153d7c880294445647c293a791ae63fa0bc7188588a4a80acf08a8d25eb376
043a591c6dbd91e3ede155bbba2dad764ac478087e0bf5db54c1e36a751d4d1fbe04ffd5dfa60dadf6d5d4cbe1724a6bcc6376b72c0ee90
1d2444819d4d6d368a7ec539200a66a2a85420a23cc40cdd5b6b7abcec543f0e77a2cac8f9165f17d0bcb8d64c8d17951ae64d3e3cc4054
eb2b56265164ce17f7810f6736835e7ad6653dcb4826121ab3c3482c9c47aecd708a96875efcd744e61fd884549e09c969f78d74be12336
f7c0a3861710dde88783aedb9975ce0ea97df46600a24dbd1580aa33ddf6cfcf845013d2b1d8f271287813c4ef56d358e6d9ce5311beabb
9f978115ece80210c397b9bdddb0aa060c1845a8efb7b4672c8fbeccbb992f8b5a1d8cd4ba9db59f7a513368ef6ead104e3cde8a0df7898
647b89f4f7a7d9a3a8a49e5b3467e9959e63f6ecc18fe8db37e0e3fff24685be43174a62457cac876c1bd7667671562f5989111561e76c0
166bd50b80764861f2e893dd3c183e85f538be504e24467c633ee630aaa1162bb77beda78d8fe812cb503a3c5b9b2ae1d8d08bd8b551a93
d1c11f9e0dadcb23032e9ddb5164a9f7f7f405b13d4c6b4348cd1aab236d2461e62c16c4be9cb7b13f227f94e588fa1b469e3f8813ef488
b1813f99b4eea2a4bc4a01ba6a8d91efc7d49ec61414b415915515344d085369918e28320bf0827001dd044f5d2b362326eedcd1ec30893
fccb0e7ea4d064eab96d4d948424c738af494b95ca6b581127b09c79117b4eb1fb0084084ad954b99660eb0bb1e4dfb8b3916457ecf7b00
ae37b46e1468fe4c27368334ada48647ad511539d9a4e044cf7808bc3d9cc5cd3a6609d3f0b7c24705e6cd9558d2fc8d054102aa13c8bae
4feb6f99854f5d51a556afaa754a4eb2825bd0b188f22dacb1921529353354fbc76e34e504815f86fa3ec7fec2ff8bcac70fed8dd8b4d35
c5d4c40b2bbe8fb0f66a01d8250e248f91ec938fa3436d40e9bc42b5c10aaf00cda166d084210222f03c594b28c6c381431eb562dfdcd06
4a003c230571df8d5817047d79c64a10c71b45cc35462794b4374b4f33566b0dd35aba9142c16d8b449a4845c11ccac5ace613764a2d367
655fa0c3f61851bd78f3c1ec9be3363b55052d997286b93de7299fec7292592510acb12164538959fe0985ded8e9b3e8ad3573091f64f2a
ba3d266e400360d9559592965e2bb090f15a79b0e18e25d5e53136cbf46f8d5c92f963b0345e4b4a953dfe62d87c8d19bf12078893f3ff7
504b7d87e1cb22988e50bcda330944d6e21b31339c54a9f1f62f74d64e42c4ce9ea11cb28370620ddd019d72cf86f23f8d6392feba71040
e6711f6b87d4574b3531230c2cd42811bebd42731daa3fbc22437fcbcd453d5496245d8e1d8d41a44d3388fdc5f44d5a6c2efd50aced0c3
9182b9e13cee5afd257269a752152d2c1ad32276aedd10543d4a43c936a817f97e8504c9829a5ee7191efc6588e0fc51b68bedbc571d026
e88e56df0cf58079ecc9f79e1da3862e197f65129cbb88cd328daa33cbdc84a10e79ec54dfb16d095d6a17661788a5b11c9b33b60180155
a28d58e51c1bab325ec736923a5c5e68a332fccefc15e804260e0e28d2bbca5dee308429b262a1afcff57494706d7b6af55f9d1d297148b
9cb0da0191f71a63990a69d742bcdaccca45e3b870618b87a34ab545c9fe56d8abf0595053eb34daa9d805c94cdbd7664d4b6deefacd61f
305c6d34514d8af7e49c1fee3e61b2d5655fe1da9cd02be10a56090ecb656330f1dcc99c9dacf92db21797f8c683ea72a823f3f4916d1cf
43a5f550e4167a6b2faadc4c76b3996e7c388e9e213356f3f55d11b65451ce82275ba73bec51220107c3aef6c16a59a8bc45c1cd18dad20
1e967e95a0b5a1d5e79a654b8c8e8dd490d7443a3fdc3c5cc296cf161bcf7f5f11ae5e6e283b0aaacfc47e34002ab474fabd907b3b7d3fd
e6e0d70572c72e6120688d4d2d6b527e3f2efbaf43b2c8b98acba51342d1343c2359e7e9977847941bfe4ec45960a73ac7e27f11bdd9d03
14c4607510d9a3988504980728d94672ef5d0ced3b26318aa0d6505d27d6853c1351194b162616497a90a4811158e887f85e43c1447cd7b
15f1cb914ef5f00756933f21781f6d50528f27e65e73063f2c9cbc31cdffd07729276ef30715c07b70203348f16fc79457f8313b41bb4bc
c2297ce9072dd39d9cf572d77b63390df5cdc71a531470b0a03114422091bdbb9287035bc7e8883bc06515fd85d5f6a4ff6c28c0fc174bb
f2a6deb39264e9d4d0a157f7a82160d19ca3d3320e277c67a1450597ee4ef17136908657292fb1535c54e0f33a74c2df98808dc5f0572a2
c872f2abe3c26b61eaa51a1f431f38c1731477e56d0b7294f82450f81d3b4e24ac3b918cdafd657076dc04d0d2478c66177c52f32e63578
ff91cf4b9c3479ff9e50d011325675b0f061f9f39a066709ec2e04799d8c6b7f5c0e6cb0f4736a9c30c2965dd1b6d130c4619c0642bf464
779147524055003d7d106e33b8d4f2878ca1036dc26ba7c043feec62f23e5e614ed216a7688fd491141f2f0ff03901e27188c4c10ca63c9
b16c681811946b709443fec717c0293cf956fe10f1cbc4949e90d6022e1df5187a4a9f33757b532e7afd708cd920c8cd3fb9706976ef925
3099aea257ba89a27d015f2fad5e413fc90b1501d0bf332ae72975acb694657958ac58063b9503940bd0b5da8667d14a6f14778de42fc5b
49aa2f31d63823b458d9d30c9cac2de6437ba07a4dc7f64c58505f8490066b8a308272afdc5f52f9d3847d45adcb4987a57e51e7f87e7b9
7be0864cad5c32fd7d7a523b707d62fe4271b699cca423d88a7b03208615466b37e914d11bf0ac09af27bdafdb8881f594afaca9af804fb
399357f78428a6146f4177029430ae8144efaace1396a67553501159c6b28f519fa2b6c526d0592bd769ebb8ef8d4a9cb06015a3cbbe490
238ed5409c5c6d5c76d050afb81e794edb0cae2b5b32de7936a6dfc55bdf9629c7439ca6e0abc5a72639de5e499884f00d3893216f3b7af
5306ea1e1c6528ffb6d216748c48e66e38195bae12b18e1dfebcdb94a769786c0d5f117692718b2e421cb6cecc31ae303a3cbf0d091aa66
e0868531a206edc80b6b82cbdec468ee5f6995e1781fdfafeebf6e9dc29bedb852d31ab250b6114ea7914db57f2a29005c75d699f96cf67
3c08fc8184afa71a1d1d574fdb4790ba1b903e4be7dab6759419dd5e2676e3674673517666fc2a6dff15ceb63b68898c2c04105a654ccdd
a3004961e2fa04bbd64be6d17e072033137e9139b408e5627afce4086ef3b62ebc10d793ddae623ca685571384b72020c361a3c65737ada
0a99626e1cc4edbf3a2d5ea7b79ee52a29399c83e3337501f11ebe19677884fc547d4856e0c056b309c9c06936b76e59179b6234dd297ad
206a44e367938874c620d304465008cde3b9cd961fe0a2194633b60da9ffa3acdcde56ddd2e9d531c88254c1abfc82eb32d176fd6ee7ef4
88e55ff9146e351d3f88f86458b7d1c015cbeb9a2830c94c139b88dd3722f21ffa0ed5f0fe2f52292d63e7a4e8296aaf6e7c676d50fae02
74633b322b117a25b4ef14de3eba71c8f71c3f1d7b2b6e0a72872168d9fb4dc7736f07f74f061e9793dc11b928fbcf0640f507f258415e2
704e590d8d8a7a3c301509a9480386e9c0dbeda03aa6ee639d321a068f1ff464de5cb8c9e1d8a18544489ebe4a10bf2a38d6b6758da979d
d9d57cb34bf06aa039f8c28ff482f777fdf49bb0e23fd5a13997e74268bd34157b8e9759745446620b67c07a631eded4da64fd52a843252
2a8cbef463cf342c29d824eab6dda3beae4fa865a91bb93bcf19dcbf83c30a463f2722237ec6c3219e4ea1a5c8332cd31a672816c6d6a3a
025a2d4fe2465a70fe31e408174914901f9cd25555ad35ee447bedb46079a10e28d45dc1ddc089501cf6d2897ef5604cfb926b1f91eea87
b3b4b5cf1de1f19de0cac590ee322b901019935650d7401f8594f07d0c5b45ff2a070c2aa99ceb579f9234d40a084bac2d327e39e4696c5
709e8143311f8cbb1b9a9e90542f2a5c7bc31ba55fc75040ccdbb019df60f9f5be3462952c53ed5ae5d2b963e209aeec9152285b57459d9
c30f13f0824d4df7391cd37f4c01bacca23be86522d89a3cea30d530870194c5b9f3e26854fd5c560ed8c1278727de19ecbcc98e70681f7
f502300177bec56c7592dcaea9de7dc84e3a5bfe84518aadee912441f36a21ea72d02ad646b5627a57fa2a936f354a83de8c720bfb77500
75652162815241de1eca2b82b26695a5be54681a352726c05f921192e2617c152ba1b3ea9886d21bdd9fa1af5ca716db253337549497552
fa8a88d90b3aa29cc883bd6b70c3b484d61cb13a48a198d66fde544d2220853023428a472b3950a7e2454a964245e941d3afd17961e7715
a8fcb573daf5aabad00c04f2063762b042cbddbf70e247205800cc3f683744328d36fb099de9a55f160113034f2f07d6b17bdbfca8c900d
8ff46542836fece814f23de9c0eb1ff4d7b2ac19404aeee4ccd730479715eb68eba290f14d4e59bfffef6b32cfdccdb1887e5ac5275edee
510d8f15c4019f8d81b5067eef86d7e0e5a22a5d9c3f9f02a3f127b790734222b35c6b58500d9e71c52af72cc857e81d674acb5a20f8899
37b11fcd1afef357199593d4dc1ed3bd330a9884dc2ec63289aa46bc78c3ecc8bce6b233073f19838d533daecc396e4dedeaad64fe2df5b
18ec9e5d6ffb986c2ec995e396ce4eaea867d1a37a0e37b05d62da3e33f1886fe494407c281a576656d9e877475cdde83724a74139a1a0d
7f46c2bfe50bdf54eefc378fc5989bf3cfb8a50c767e9f387319c63ae3a19baa1f9b2ecdcd1c520cf89812f5afb7b9e1f8c4430d30ef2ad
9ab44ec9040e004c34a98aa5365aa2c47fef4d61ae4460315695db1d9b5c209edb3bb2a19c0d3936d926de49eb38871ab49168876df13e1
2297a0ba4735945cdfbd8e7f9213538f279f1e73962c1d93cf093c641a5e892fea0bee34981795431ec58874ca3324682e294c5919ae542
c9a24c5517653da873a6c808f6e2ee17bf97fb096af3027ba73ff3bbe73b6666bcbf5fb343dedcca608d754253024fc1cbf745be30b9e19
260837e7dfc018735124e321b493ae356ea682ed8b3e543f8ea78efa6fcc670a6f08b7690ef640358563dca8437c8124b54ec5c818c40fd
0e9001ef579c8cee7ded90a0eb57f0be6a77a8bf460131ba700299188d6850e0b6bfe61ac5088cc425fe4b49de058f7b771e97f10851f3e
f4d73f18368f206d66c46cf14d53509eeb2b0e0f7917e0424721729a624f4979f99ad06a6ebc5bfff88df86731395ee8ffdfa2f6f890450
4ffcac2ca833db95abed61d36a611a0f2d8e911fa31e9b3d7c3b93e810298e674e1275c34789cbb4db0ad81453f79806900c7a6cf4d2bc3
b376c3b3a85b87a96d0f391132e67beaf0efc2efe6797c8c9667b0b8a9e366747ab433056e68ceb4423b12c0e9547dd7993bb45794b3e3f
e3ea8263af967a319496755b6dcbaba889ff3a8a63c19de97607fb0a4907f05e6c1b8751d170d5e479e22ee9aca002e3afe564129e20a35
c6de7725d4565e354c00c0dd46a78d3bf64bee3766ab1e9713307816dca44473cf08a41db614dfe24a1f85829ec3b32d8ac299362996d89
63d06213219dcc77057ecceb8b87238900462faa16d24138c24e9f000e40e6c2986d00d4c9e2daa5f88228921d40055c34b12a4c0a95e12
f4261dac024a8057cfa00cc7513f7a6f7f8eec5638f561ff4ef24d7ff8e8ccacd833fd641d7de42cee3d88e92dded6db82c947b20d0e99d
d91a4f464a3e84920a4e79b2f4bc5368c131ad2d1d36a448dd1c35e3a763a9ea77ce1ae501e5c3a3ff654d7b7f3572003aeb1eb3b9c7615
dd1fceab65205278c43a937fe45d8ae44de67bfd69f406b55eb92f1b22bdaf71be9c40b1ce2e490ee7a3d0efe2eb8db0945c4d9f9879594
cf15b2d2ad0e608237977a3b8109af5995a4d04a782e74acaa512c6f4124758facb7fe82b4f11ed4e1d009d4fd72c104c1f8af43bc6ee8e
72bedbdd806066404656ff6657f6a896141e8e3c64d29462f7d9a5a8547f8e70eecd879ab3ce3a83853f686f3057796a65ddc9528e774e8
da5a58e5b95cab51d1630c11076800c102e3a9aeddbc6393fcbf45336e380b2c243b2654abe2c60f14982174dc451e0d2cca2c2875f28de
5dd33015d30083e4e757339ee4e8a8beea16706e0fa40505794cb6add99d4c47d3fd474c6dc6b7c12be07635f88520a396d68c1ed46cf58
d12c5cbd71e8fd611b1814c9b6570f862376e10801b09f2a96f9fe2fb30704573552b6daf5fe225956eebf6670dfec598881774883fb71f
1079caa7610ab316b49045282bcb95d674cb97f755db08adfb3dd48c759c1f3b846645f6e598d40d781cf90f9f6b4b68c6e4eafb04ca121
0c3e32c9bdbbc5cc00e5cb73f6f7a8989b9f77173cf9c48e563d25c08e6421902bbf6eda178eba038a58b6314b9928e05b415274065a294
e797d69ae030ccaf3527e5be9e7793152e34179524191d8fb034f65894c862afb9f5277355588930d06f5e1ecdd161244c5620c7927e558
7fe7859a3c9f553a60c61dbdbb50700e94fac299688c825698738fc9057a03427491ab3cf23060d1d9e651848cf3346673ba64e252013a5
e91fa1f208446d65120e98586e07a3f6c6b70bc10c4fdc8aaba169eb6e467d2cc12c3d5fe16b2730d12da8b30dd168f3f9174e1dc940890
3f9b8d7dfa02cb5f5ddb014f0e4604c4920057261a4d38b62b9c0b365c6b067d10e6b71bccae65284802f3a402a0e4106bab6a2f1d3908c
a87e8001150949e86c18d7169d0e2f96e46eca56059dfa543f121999b734561c4813e6893bcf180a0ed97dcf51c254170d991a8da792a25
e2bb40f6e5819350cd5f19ba46634b8c7e734b6631a90f0bf7be8ac658a6ab74119c24ccc808a2ae0908722bc71a51495b232698014d9cc
86658b7d01b5f2d3dbc402719a750c6737d0ab4d38890f361236c17d8d42a993922063a19c59a199c92310d472743f2317921246a009d6b
8b33856583d98bcf028fed0c906e054a0fd83d3724d535f1fc7c06e03c504aa1d5254ea9d100658ba42771aa41717a7666c11b7cfcc21db
52b598f9754621372107f06f435d01f624b258f9d987a8e3c4699fc1c8eaefbbb2c6bfa52c24f2e7fa61a8894a598c6eca124978b566131
cb23a1ea29d5a877156726954b4e025e9cdc6615baf34af6192c5ee9f23fc48c8ca9cbf66290e52c93503925b8df6718fc9820c84480bf1
50cd0679c0042b52ad5dd97d3cbf59ccce7ffc168bfd49de2f00034f9c2d16f6c438e6c1d156186ff15950a1b829abcbb6c339f443cd23e
6d0be60e818fa0571c1cfc22d11f60423f54f884e4939d7b742a0af3a14531d9341e4e88c98f800ee5d05c9ff29daae165db0aa48e4ad79
25e25ee0acf03bf09393c5ccbbd62343656bedb3a68d7826b01bf9deeebeb32e32058853923f235095cbf5fe9099185ef9601b1e59e96cb
e812a8ee818a5ae1135de863f5241fbccd6277ce0261487ac5925c8a6d303666a045665385b3177e4f4945bac6fe4ba1e3bfa407b964b8d
02f5dd122e1806ebd8c5f92a260b635248d6fbd993c03ae92f75c16a14ce240b1742ea5d0c25ef1629ab0c6bb59ba849cd7a0c15284a780
0ae3b61b13becbed1337d37987e36ebd9b75a8e64754a8109b5efce08306244aa62cf7d0ff73b73f2eaa363d6cfb993be1196ecb43edf51
e702e7575fc3940a36c2075223a7ea6c06466f8d689d6a8f9b2309d893073ad6ad0bb44044b1bc7d0c093b049c07772e39d9e4717733887
157460332241e807e07b0a848715ae8eb085eb96116d1e5e3e98b70321af069c52d34f5e8f99198d18c0a7e0e702fe4a1241956b09ab6b9
e5040ba2a9f0d9c5fe87eae988913c5e08554d32feeb3e60148b1fb1ea67b2ff55285e928efe9039197fe9783eb0ec13d28aa74fcf9e554
9b48ab7098927df50a6cb1bad0dedf8236cb099c1746855b180be40154aca88b4e966cb89ca2813e57dcb0fb7d36f4fbab5ad82a98522df
ddd9e50b9f6335c97b7d36cf8f082d4efdf887cf09dfa42a4926bbb1b58d033c6ad34373045e0e2c9ea83a537127c3c7b2c99b53187623a
a5b429c6ce47499adecdeb536ebe3d884d4109bc06de2f54c221258c15d658ea5dd02039d44af44ca6541e6f4eb7242ed1973ddb5cb0d08
aa78db6ac14d7efd2b20db298ad9bc1cd6c8b3620c8f035496ca386450a81b73022bb9d6bdf7b5142ea8e49e923a6515404f166c24d1e01
3b1b040759e083212dd9f2dd0b9bcd7d66f2eaae71b4da533dbaad18f34c86e72d0b836d8a78c0ab0e9fe657616c67c021b99313f0661ff
e4628a9d3caf75c54727c1720ac71bb484fae167b24d2c197a07cfa10343dbebb02a23e45c7e6cea8f8fe242a3d7407cbcb1553d05a643c
609c9783b43581b957e473569c3b2cf88c1ef91eb4a62392b20a15297f8c85cd7a1cc20b794abae302e3cd3ca869b4dc2258c57ea2849e8
1f31ff2961ef1f02bd7170677848c1d2aa5f4b854682148e651f34bb90fbad9606bf1b096f47c0a662d03869ab963308b7454d921bcf04c
35272d5684b31c6182a4b446eb991a92ffe783b497aa09bc969169a843e795c577c94ddfb2781bdea0f23bcb5b98c12cac376085219ec53
54bfb1986bf9e8e2369f4dc1cc59f0e4971d2710037e35cfa228482fbc8fc197fc8a483937e72c54728efbb7e26b3b7122143e62e0f96c6
bf7a5673444f55af3a224f980ece97cb3152ea3a36a45a47a8190d255e8f8983aa353b99d8441969b5ba7f8c2130766052b7d9aa4962d73
2d618b561b38ba4a7d5851cb1baa6d032d4078114f5e943bc53af0eb52e422361acd6e088c98a477000ae91b11242f083554a921837b69f
be571ee7460e8877a74d50f02d3c8061591c73591cc67f13a4c5ee8ee00211a4142408a7530c0de5c606d7d76479bec4d9c0ed8d96a1274
b589488fe0e73c8be1f69b1a5650ffda224c263544357b22561f64ec9e3b82525022af207610073d6b26ecb3a3f534c95c5bb0536eecafa
f7d83586e88e7174becc82eeec7d8ab52f86caf55fb12d6e08d29242a38cc7b4b94a6219e463426e5a4b38a9f33932c1da2de02ac96a5fb
a25002790ab95cfe61d720dc29cbac8adca48da51bbd22cb79a81fec9e9a3af21e7d22581c4ffb7375920ba798871a0cb69ce6c98fcec09
b4520d27d4d062c151865704ca63de90b733c7b49b6a94ba5477e2c585a1e81fffc5d491d85027a9cb77334988a915e5a79917607a00354
f1ece6334d9f3ecffb5b8c10f1d059c2f63baad95c239a9546553045cf3c9f318d7169d24db36ce3b088609e766882040011b7bc05bd271
b67bf8b372fbc750bc3edd134d3c59e87ee13abb4c2ae32f66b42c5b48ac382102c7039619a94f8bab8ff56ed5fec6b44cec3ebdf74c7c1
862b334cab340202d1a86b56b4981e25d83a33f5bcbc48b260c0b0f092f133c65dd1dd6450c0ae5c04d4ed44b16237f0618e4d810dfccab
1e884693e683a46c79b76e7028f0a12ffca9115df65e7e7d5249cc85eeb1d5b5a736f47226895c0445ddd714eaa636ef4d866b54b7f7187
38f539c063f6e84ed8255390e410b2400ae390a907b2d428de5c10f78e499d8f433f1d3ead0872f6f8469b35baa4c702a7b69ea9a6e657d
6422c00f300bc15cdfa9a41eab53096bdf3dcfb2d80ed70219818cd697bf03759aa888bcee86a01741e316cd28441207c12fc9b36ee8cbd
c2d774656b58441799fa05155c1614c4b735c081c5af2e18d9ad8abc733d2924fb8d6ce8b733d56d67d9482aa49bac974e7de109bf6d32c
924e96172455c4bcb0aa85b6812c704a2af87c683a1f2a9a9101d0fe0ca70a6a6d5ca1fff045b823235c334536b9c429da3272327be745e
fd912040a6445c245f5afa146350f9f193651f8db41ae4d4afa7ab81198043be7cf59dc6de0283f27fe848cbdb2962cacfb96803d9e7ebb
497ab1b0e65f802bdd27b9a36333ee24ae7f5e94a8cfadde40e17b01d6c72d1463f68ef98169eec313f97a02e0634cbe89e2dd4c4d53217
fab8bbece82b1ce9dff25ccc6f7c86f8e743e269492aa5cd7fae7b0ec5ff323b53d70ecf0bd8529898531c6b85f42a304b152bccfae92ba
ed9732d68584c507b510cb27c73277388eea9567b7c3b1f7611d2e2562a86930281e815c0919e87c9ab923cd8be7175b7dbe8413e37fc51
2e0d4a0a8d47ac53df1e19576369539f7b5d74be7f93a2a866a041fe3a8d23196057099afdcb41353c6eba769edae13e502c8a33310f700
9faf5b858b9fda982c3ccd28db2c9cecb7022d981c47967bafb8cb4be54f0d426d5ec7e414e3ea0eb9a0e4218ced00ceb393f4ebeade224
df16af55305155ab2af8fc8a983ba64faee53aaf1cb6e5a1794d3fd0506e0685e4b002d69148aaa795a28d3106edd9a6a001ead88c221ac
539cc44a8a282455c25804a6c26ddabbeb0c917e835a1f71acf6920a33c2732d75465077cda205ae87c9d23d8b8f67d565881ce3b4c48b6
e06d93e310fb1f2fa0085493682ee124d582d85361e29c0cdc2f68e93a124671d9e70c4328793406c5622864dd903c7a5a0244cd24d4a8b
61f4d1647d524e5de8acd571219455d57438b0907a230ed3e47a9bd3f291548aa15a8006308e7f1a8593e27f9fa55ef280266a3f1016212
db2921e80ae9c5d838a24071ac873fe8245e2e877d466f69eb7c87dd9176f31d38476ebfa9f287a699b7d4634902d22b843c575714c84ab
f02f04edf7f56d7646df65c155933b643dca2a2e7621660635e215401ee7004ded4aa9e023b13bf1cdf44720218a02975b9c14707a5baf2
25bfc4937ead5193d533ec78246de1dd94a23f56ad47de9d5b6a47ce60af33324f5afdf1981c2b460da884ecbe4a7f082527fceba6dfbdf
a5dd32d7cbc08a0f4f24b8411821c0b22e1053029dfb9b0d0e61c997f9b4efd9783c8c384cb72a042c1ff23d3eb802a367502ff73e952ec
cfd9b6fa422193defc9f040df291ee198b931fe376b5a4acc56cae472c734b08a4eba293503bd534a14e935b925322d5bb083cfd2ec1600
893ace9e0772339d17f724f4e54f1d9a998fa93dcef407ae4bfc144938a7cacbbf506327b6ef761f6b8bcda139b2852b5d10f325effb71c
bb19425c6a212261604b3ab229fa991d8c0011fc3bc3592d0bee2243db7485ab0fba3520538ab9f527cd5a1dab5205de3261c8283c93a9b
6aaf1e66c32b7a445526cffc142ddeff1c172c583def9bdc2d9f73882e65b9cc7490739a064c62e04f4ddba4957badd6b50c64a13d8790e
2820dd20d6c1218462af6a070c768e8c953b779c732de4ff756f87ecf2695caed49461216883bf5539415359691a57e69b08c0630fb2732
eeee2d6e6d99df1cbffc2212e79c8cd2ab4f8052acf0bd2bdea1d3337cf5b1773f5a1a095e431ed7e467fb386dbab83d30b4924f6bb4d9e
f0851f3cd218c48441af9520e2bdc12db9e4d3b22ca685e9547d2a24a5b9aef06edb4944fde879a8ca7fd2522fca7591017e16881637d12
01f13547b777fee849eec6cd95d2bb18859b5367e1ea78728bc7a7cdc8deb7b92103f65fd799d23dc7e31adbe62b729dd222fbf3e15a97e
f72aea07e183577f591a081845ea340797b79c6c8742e8826a6d7df773ec8564025fbb570bfbc001740e3437384df6324c7605526d9a630
a5d4483f1
''')
db_write_enable = unhex('''
06020000015ddf5d76a8e3bab8b10d9f82f0b31652d5b208dff1d20745b7c5442e09db880c80ca103d5b2071d8bdcaab452b900d1785be2
de478669e72a9d082273f0f6176b700ffb65a026af052e76de5f9e247e994bed7c79e34815b465a8070a76da7d365525d7285dfb152d24c
732a471f031d22ebb67d6e27bfff74b3ab1c4780461a460c0ea5710fbd32ab59a6ca9ca3e3e24264640b15245a6c48b6bd20c6848c2307e
854af75b059e86793dc7a30474a1b1b5484c58dc5a4535eb71911bf9b10f82c27362d68b4baa1ace63a33b7cf3de616810ee5033601febb
cc08b0f55166f4ca08d42d3361426712f7e5a4842e9d2e906c87e4c5c6694eec448c109abe3238128fbbb8b8f383e3b66133f0c9d38ca53
5d47ee9dd8841fcb205510452bd0f733d416b6c763f0b7a647e1992ede714b6c4569de329440549a5a1f6646dc88b08288fc6f9c4f55d90
ccc86487af195ed635e4c9a5a2df5df3bc4e39ff0ad6bc70a54d142a01ba9ef22839859ea1cb9b227cf9407a9f61b3cf8273549d759c3ff
b6db4b33bf9a40f6de2680cde8ad01158ed1c6771bba9fbe230c9e9b8a4edff941f43c4e629097c6149a5ac13ebe757b43a52af3f263f8a
a36ec69989c62539b656a49dfdb14ea066ffec203c41411de29251bc40f75860976834acf368db991d0c88cc5d9f8229be691f55c1dc298
dd0690aa09f46a7a0dcb92909a654a54cb584ed65280236bf368ab2ae909086dcbafa6fbe26556cd724ee9e6b7b3ce2290c5cb832bd4301
66047ab2281c55e7d9d29637bbadfa40b4b9a5008e86239a5998d39a5dda6cfeb7d0bff10bf56c523878db6de81b7ed824fdfdd9515f5d4
90345b47172bdc9db6bbb10f19d39f061fbe53c3397dcb8fe30d5ca032ccf2d26184635b691705b471d81dc86ee31f144512072d9ef7559
e9ef9db8a08fea98abb6706833a9684855578ec04b72ae1bc4e559c87dc1dcbac3115c2c6697cdb45762402836580f29330cb0fe8e4116b
dcd4da603082ca420f5de71b92657c5a6ca96f51e6ed9945ffd39e9c79441ba5cba40b2c09af4d16c3d7957a2d8ab7469819c0c6dd177e3
e7dea2240a1d96756b5fde207543167417a74e702df1781f65165c4ed7bc993e72789af03c2cdcdaa7b558423fd064328d57f2ec9a8ab2b
ca9bda6f625e103a79a12561675e05b448f5dec7554649fb10ee3d28599306de19f63ce50e4c346cabff9f5ccd36072831664c308e63184
cbf31e5541f46e01500d6ed045d7d44eb8087355c5bd5a65c58c705b5299e52cebcbc79254d20b6835c76cfd47d99f9b1f4a96169249a5e
28d6ca753efdb8a008edffe2a7f68ae23bb7d6f84f40751f0232251d4ad4dedf0fb4b8b5f8fc4701bc4578cd8e1c4bb491d16196e952e0c
e684e63ce9b608ef61551011328866545a6999e0881ffc758e41b451e1c2c8f571294eb1d5828131af9735003d00488200dc3b9f6cb6a7d
2bc1239367b372914d4a3a3ecafc89372497d9621c1629c1aeb40d9b6f17efe1fdf19583ae2867efaf0c682d59ef72397c7d709da80425c
30b91b1716893039205b9dc46ef8979aa5f8004c6bb698b35c4b600b45cd9dfc2a929fec37d392ce9e3b83240707226402d89bb034c3a23
07413ba39eb1afdcabbabe9742fe2c62acb679a57ee903de0a788fee19d550b78c4f2095e388766724061b39a1e54c585ddbce238a385e5
0c4ba9866c16ea8f438cc58aedacd6c2652b0ab0847794f80968daaf8a70422c28545caf3e95c38c54e142c8ebf26d5b5adcf905d8f105d
ef1df70997ccaf59e256e7b178e4bc9ee8d6437f23f59e7dcc8fb3f18769fa67bba0b4791cf8c0a4e330751e671be3235a9ffd83272eceb
af2d3b91a91599b1d4f84aca5660dca24acfe5fa78e95f944b4930db9e81a6f3ed23c90b2a446ad7832b6f4bd8e6b932116f4aedab500a4
dfe311d54b3ff9ddd3c73819b5c88a47c87a117c3a008e49361ba1ad4632d38ee4f2fd8822c079a278b491ed5b9488cdfff5ea48dbf8aee
793a2d2e837a9f5fd195833c104da32c3a1363ac846d2a59ffca0c3b1293415069db5e459edf60d704de47138c315df3a8440b378ee88e1
cdb8889b08e0cbeb4ed98311e5218369535e03062507d7c1d13b522e3eec020ffd4cb1b2297760adb4ef7c76a5fd2e78a60bee3cf246f24
8fad7fe6fa8e9c65b52515a7ce73c47c20c04c32f377e1d0ddc20e7e96f7fea55fd85d8456849ffe4cc3c6a03c5b9f21d055e4d498934be
ff14deec1e77f857004d929409e23e54eb19e72a733a3fb3abd035b72a4a4c2076874061baa5526e855be24b413758cdcbe1150bc916514
254ecb95848fc717718265a6901966f22c33dd6ae48ff9cb5731446addb3ff2ea17b1c3586e52afa23bb44ea6c2bec062c59adcb791736a
a2da95eb8445a6381f3941917bed7fcf01ab199228eadd1968847e4b9a40022d2b0ec68318abf97c6d46286a5
''')
# FIXME this must be very specific to a particular device and constructed on the fly from multiple hardcoded tables:
identify_prg = unhex('''
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
0e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b0000080400140800000808000008080000140830000808000014
0831001c081a0032000c0000000080501101004c1126003400080310071d10071d10071d10071d10071c01065810080101000007c8078c0
6100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d80
0af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800
b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800a
ee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b7
00971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae3
08e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b0
97c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808
d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b86098
7800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc
800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b9109928
00ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c180
0b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800
abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a
020803800ab608b5800a030804802003070404020000000000002f000400900000002900040000000000350004001000000017000000260
02800fbb20f00f2220f00300000006001020040010a00018000000a0200000b19000050c360ea010910002e001c00020018002300000090
0090004d01000090017c013c323232640a02013000cc0103000000ff0000001d000003ff00000025000003ff00000022000003101112131
415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b
4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828
38485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f
201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341
c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c
2b23223a211c7e7f807f8080808080808080808080808080808080808180818081808180808080808180818080808180818081808180818
08180818081808180808081808180808081807f808081808080818081808180808081808180818081808180818080808180818081808180
81808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
''')
# The following blob has only 1 byte difference from the above
enroll_prg = unhex('''
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
0e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b0000080400140800000808000008080000140830000808000014
0831001c081a0032000c0000000080501101004c1126003400080310071d10071d10071d10071d10071c01065810080101000007c8078c0
6100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d80
0af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800
b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800a
ee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b7
00971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae3
08e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b0
97c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808
d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b86098
7800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc
800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b9109928
00ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c180
0b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800
abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a
020803800ab608b5800a030804802003070404020000000000002f000400900000002900040000000000350004001000000017000000260
02800fbb20f00f2220f00300000006001020040010a00018000000a0200000b19000050c360ea010910002e001c00020018002300000090
0090004d01000090017c013c323232640a02013000cc0103000000ff0000001d000003ff00000025000003ff00000022000003101112131
415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b
4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828
38485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f
201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341
c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c
2b23223a211c7e7f807f8080808080808080808080808080808080808180818081808180808080808180818080808180818081808180818
08180818081808180808081808180808081807f808081808080818081808180808081808180818081808180818080808180818081808180
81808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
''')
calibrate_prg = unhex('''
0298006103230000002000080000200080000001003200700000000080202005002420000050207736282
0010030200100082170000c210000482102004c210000582000005c20000060200000682005006c200129
70200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200
200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0
206401e420d002e8200001f0200500f8200500fc200000b8203b000008040014080000080800000808000
01408300008080000140831001c081a0032000c0000000080501101004c1126003400080310071d10071d
10071d10071d10071c01065810080101000007c8078c06100000204f80007f000003070107010c07032c0
8fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d800af908f8800b5d
095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b6109628
00af408f3800b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af0
08ef800b660967800aef08ee800b670968800aee08ed800b68096c800aed08ec800b6c096d800aec08eb8
00b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b700971800ae808e7800b71
0972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b7509768
00ae308e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf
08de800b7a097b800ade08dd800b7b097c800add08dc800b7c097d800adc08db800b7d097e800adb08da8
00b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808d7800b810982800ad708d6800b82
0983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b8609878
00ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace
08cd800b8b098c800acd08cc800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c98
00b8f0990800ac908c8800b900991800ac808c7800b910992800ac708c6800b920993800ac608c5800b93
0994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c1800b9709988
00ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd
08bc800b9c099d800abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b88
00ba00801800ab808b7800a010802800ab708b6800a020803800ab608b5800a0308048020030704040200
00000000002f0004009000000029000400000000003500040010000000170000003000cc0103000000ff0
000001d000003ff00000025000003ff00000022000003101112131415161718191a1b1c1d1e1f20212223
2425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4
e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778
797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f2b23203
c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f
1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341c1e1e1c221f2
01d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220
301d2d302f2d2c2b23223a211c7e7f807f808080808080808080808080808080808080818081808180818
080808080818081808080818081808180818081808180818081808180808081808180808081807f808081
8080808180818081808080818081808180818081808180808081808180818081808180818081808180818
0818081808180818081808080808080808080807f807f807f807f7f7e7e
''')