From 643a9dd20e7d27a0a816e63536e5a8230185380f Mon Sep 17 00:00:00 2001 From: Alise Au <20424172+ahiuchingau@users.noreply.github.com> Date: Wed, 15 May 2024 14:38:32 -0400 Subject: [PATCH] feat(shared-data, api): add absorbance plate reader definition and module control (#15167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Overview This PR adds support for the Absorbance Plate Reader in the hardware controller API. We can now see the plate reader as an attached module on the backend and use the AbsorbanceReaderDriver to communicate with the plate reader like we would with the other modules. # Caveat The driver is not fully finished - there are some functions that still need to be implemented and I expect the format of the response will change depending on how we implement the engine commands. We still need to add some changes on oe-core side to make sure this runs on all robot - however i'm happy to show you the plate reader in action at this time. --- api/Pipfile | 1 + api/Pipfile.lock | 201 +- .../drivers/absorbance_reader/__init__.py | 11 + .../drivers/absorbance_reader/abstract.py | 45 + .../drivers/absorbance_reader/async_byonoy.py | 272 ++ .../drivers/absorbance_reader/driver.py | 63 + .../drivers/absorbance_reader/hid_protocol.py | 115 + .../drivers/absorbance_reader/simulator.py | 55 + .../opentrons/drivers/rpi_drivers/types.py | 118 +- api/src/opentrons/drivers/rpi_drivers/usb.py | 20 +- api/src/opentrons/drivers/types.py | 16 + .../hardware_control/modules/__init__.py | 2 + .../modules/absorbance_reader.py | 172 + .../hardware_control/modules/types.py | 16 + .../hardware_control/modules/utils.py | 3 + .../absorbance_reader_substate.py | 20 + .../drivers/absorbance_reader/__init__.py | 0 .../drivers/absorbance_reader/test_driver.py | 168 + g-code-testing/Pipfile | 1 + g-code-testing/Pipfile.lock | 437 +- hardware-testing/Pipfile | 1 + hardware-testing/Pipfile.lock | 496 +-- robot-server/Pipfile | 1 + robot-server/Pipfile.lock | 217 +- .../definitions/3/absorbanceReaderV1.json | 3686 +++++++++++++++++ shared-data/module/schemas/3.json | 5 +- .../opentrons_shared_data/module/dev_types.py | 4 + 27 files changed, 5336 insertions(+), 810 deletions(-) create mode 100644 api/src/opentrons/drivers/absorbance_reader/__init__.py create mode 100644 api/src/opentrons/drivers/absorbance_reader/abstract.py create mode 100644 api/src/opentrons/drivers/absorbance_reader/async_byonoy.py create mode 100644 api/src/opentrons/drivers/absorbance_reader/driver.py create mode 100644 api/src/opentrons/drivers/absorbance_reader/hid_protocol.py create mode 100644 api/src/opentrons/drivers/absorbance_reader/simulator.py create mode 100644 api/src/opentrons/hardware_control/modules/absorbance_reader.py create mode 100644 api/src/opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py create mode 100644 api/tests/opentrons/drivers/absorbance_reader/__init__.py create mode 100644 api/tests/opentrons/drivers/absorbance_reader/test_driver.py create mode 100644 shared-data/module/definitions/3/absorbanceReaderV1.json diff --git a/api/Pipfile b/api/Pipfile index 7be11b82934..e37e6e1c5f9 100755 --- a/api/Pipfile +++ b/api/Pipfile @@ -11,6 +11,7 @@ opentrons-shared-data = { editable = true, path = "../shared-data/python" } opentrons = { editable = true, path = "." } opentrons-hardware = { editable = true, path = "./../hardware", extras=["FLEX"] } numpy = "==1.22.3" +pyusb = "==1.2.1" [dev-packages] # atomicwrites and colorama are pytest dependencies on windows, diff --git a/api/Pipfile.lock b/api/Pipfile.lock index 94643ce22a7..b08815e2656 100644 --- a/api/Pipfile.lock +++ b/api/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "a531665bfd7452ea19565ee95137118966532a8ab5475b7d5ee086ada333e627" + "sha256": "8a1eb02e26b3ae9d690880546729375c7b74c8e53a8f1806eefdbeac5829dc67" }, "pipfile-spec": 6, "requires": {}, @@ -48,11 +48,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "idna": { "hashes": [ @@ -162,7 +162,7 @@ }, "opentrons": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "." }, "opentrons-hardware": { @@ -174,7 +174,7 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "../shared-data/python" }, "packaging": { @@ -280,6 +280,15 @@ ], "version": "==4.2.2" }, + "pyusb": { + "hashes": [ + "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", + "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9" + ], + "index": "pypi", + "markers": "python_full_version >= '3.6.0'", + "version": "==1.2.1" + }, "setuptools": { "hashes": [ "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987", @@ -408,19 +417,19 @@ }, "babel": { "hashes": [ - "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363", - "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287" + "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb", + "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413" ], - "markers": "python_version >= '3.7'", - "version": "==2.14.0" + "markers": "python_version >= '3.8'", + "version": "==2.15.0" }, "backports.tarfile": { "hashes": [ - "sha256:2688f159c21afd56a07b75f01306f9f52c79aebcc5f4a117fb8fbb4445352c75", - "sha256:bcd36290d9684beb524d3fe74f4a2db056824c47746583f090b8e55daf0776e4" + "sha256:73e0179647803d3726d82e76089d01d8549ceca9bace469953fcb4d97cf2d417", + "sha256:9c2ef9696cb73374f7164e17fc761389393ca76777036f5aad42e8b93fcd8009" ], "markers": "python_version < '3.12'", - "version": "==1.0.0" + "version": "==1.1.1" }, "black": { "hashes": [ @@ -460,64 +469,6 @@ "markers": "python_version >= '3.6'", "version": "==2024.2.2" }, - "cffi": { - "hashes": [ - "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", - "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", - "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", - "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", - "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", - "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", - "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", - "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", - "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", - "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", - "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", - "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", - "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", - "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", - "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", - "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", - "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", - "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", - "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", - "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", - "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", - "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", - "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", - "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", - "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", - "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", - "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", - "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", - "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", - "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", - "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", - "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", - "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", - "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", - "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", - "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", - "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", - "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", - "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", - "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", - "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", - "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", - "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", - "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", - "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", - "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", - "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", - "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", - "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", - "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", - "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", - "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" - ], - "markers": "platform_python_implementation != 'PyPy'", - "version": "==1.16.0" - }, "charset-normalizer": { "hashes": [ "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", @@ -742,44 +693,6 @@ "markers": "python_version >= '3.8'", "version": "==7.4.1" }, - "cryptography": { - "hashes": [ - "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", - "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", - "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", - "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", - "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", - "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", - "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", - "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", - "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", - "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", - "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", - "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", - "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", - "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", - "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", - "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", - "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", - "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", - "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", - "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", - "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", - "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", - "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", - "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", - "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", - "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", - "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", - "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", - "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", - "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", - "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", - "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" - ], - "markers": "python_version >= '3.7'", - "version": "==42.0.5" - }, "cycler": { "hashes": [ "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", @@ -807,11 +720,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "execnet": { "hashes": [ @@ -972,19 +885,11 @@ }, "jaraco.functools": { "hashes": [ - "sha256:c279cb24c93d694ef7270f970d499cab4d3813f4e08273f95398651a634f0925", - "sha256:daf276ddf234bea897ef14f43c4e1bf9eefeac7b7a82a4dd69228ac20acff68d" + "sha256:3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664", + "sha256:d33fa765374c0611b52f8b3a795f8900869aa88c84769d4d1746cd68fb28c3e8" ], "markers": "python_version >= '3.8'", - "version": "==4.0.0" - }, - "jeepney": { - "hashes": [ - "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", - "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755" - ], - "markers": "sys_platform == 'linux'", - "version": "==0.8.0" + "version": "==4.0.1" }, "jinja2": { "hashes": [ @@ -1006,11 +911,11 @@ }, "keyring": { "hashes": [ - "sha256:26fc12e6a329d61d24aa47b22a7c5c3f35753df7d8f2860973cf94f4e1fb3427", - "sha256:7230ea690525133f6ad536a9b5def74a4bd52642abe594761028fc044d7c7893" + "sha256:2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50", + "sha256:daaffd42dbda25ddafb1ad5fec4024e5bbcfe424597ca1ca452b299861e49f1b" ], "markers": "python_version >= '3.8'", - "version": "==25.1.0" + "version": "==25.2.1" }, "kiwisolver": { "hashes": [ @@ -1362,7 +1267,7 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "../shared-data/python" }, "packaging": { @@ -1470,19 +1375,19 @@ }, "platformdirs": { "hashes": [ - "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", - "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" + "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf", + "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1" ], "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.2.1" }, "pluggy": { "hashes": [ - "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", - "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.4.0" + "version": "==1.5.0" }, "py": { "hashes": [ @@ -1500,14 +1405,6 @@ "markers": "python_version >= '3.8'", "version": "==2.11.1" }, - "pycparser": { - "hashes": [ - "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", - "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" - ], - "markers": "python_version >= '3.8'", - "version": "==2.22" - }, "pydantic": { "hashes": [ "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", @@ -1569,11 +1466,11 @@ }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pyparsing": { "hashes": [ @@ -1731,14 +1628,6 @@ "markers": "python_full_version >= '3.7.0'", "version": "==13.7.1" }, - "secretstorage": { - "hashes": [ - "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", - "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99" - ], - "markers": "sys_platform == 'linux'", - "version": "==3.3.3" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1878,12 +1767,12 @@ }, "types-mock": { "hashes": [ - "sha256:0769cb376dfc75b45215619f17a9fd6333d771cc29ce4a38937f060b1e45530f", - "sha256:7472797986d83016f96fde7f73577d129b0cd8a8d0b783487a7be330d57ba431" + "sha256:5281a645d72e827d70043e3cc144fe33b1c003db084f789dc203aa90e812a5a4", + "sha256:d586a01d39ad919d3ddcd73de6cde73ca7f3c69707219f722d1b8d7733641ad7" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0.20240311" + "version": "==5.1.0.20240425" }, "types-setuptools": { "hashes": [ diff --git a/api/src/opentrons/drivers/absorbance_reader/__init__.py b/api/src/opentrons/drivers/absorbance_reader/__init__.py new file mode 100644 index 00000000000..9b127df97b3 --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/__init__.py @@ -0,0 +1,11 @@ +from .abstract import AbstractAbsorbanceReaderDriver +from .driver import AbsorbanceReaderDriver +from .simulator import SimulatingDriver +from .hid_protocol import AbsorbanceHidInterface + +__all__ = [ + "AbstractAbsorbanceReaderDriver", + "AbsorbanceReaderDriver", + "SimulatingDriver", + "AbsorbanceHidInterface", +] diff --git a/api/src/opentrons/drivers/absorbance_reader/abstract.py b/api/src/opentrons/drivers/absorbance_reader/abstract.py new file mode 100644 index 00000000000..769de38253e --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/abstract.py @@ -0,0 +1,45 @@ +from abc import ABC, abstractmethod +from typing import Dict, List +from opentrons.drivers.types import AbsorbanceReaderLidStatus + + +class AbstractAbsorbanceReaderDriver(ABC): + @abstractmethod + async def connect(self) -> None: + """Connect to absorbance reader""" + ... + + @abstractmethod + async def disconnect(self) -> None: + """Disconnect from absorbance reader""" + ... + + @abstractmethod + async def is_connected(self) -> bool: + """Check connection to absorbance reader""" + ... + + @abstractmethod + async def get_lid_status(self) -> AbsorbanceReaderLidStatus: + ... + + @abstractmethod + async def get_available_wavelengths(self) -> List[int]: + ... + + @abstractmethod + async def get_single_measurement(self, wavelength: int) -> List[float]: + ... + + @abstractmethod + async def initialize_measurement(self, wavelength: int) -> None: + ... + + @abstractmethod + async def get_status(self) -> None: + ... + + @abstractmethod + async def get_device_info(self) -> Dict[str, str]: + """Get device info""" + ... diff --git a/api/src/opentrons/drivers/absorbance_reader/async_byonoy.py b/api/src/opentrons/drivers/absorbance_reader/async_byonoy.py new file mode 100644 index 00000000000..1d5465db342 --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/async_byonoy.py @@ -0,0 +1,272 @@ +from __future__ import annotations + +import asyncio +import re +from concurrent.futures.thread import ThreadPoolExecutor +from functools import partial +from typing import Optional, List, Dict +import usb.core as usb_core # type: ignore[import-untyped] + + +from .hid_protocol import AbsorbanceHidInterface as AbsProtocol, ErrorCodeNames +from opentrons.drivers.types import ( + AbsorbanceReaderLidStatus, + AbsorbanceReaderPlatePresence, +) +from opentrons.drivers.rpi_drivers.types import USBPort + + +SN_PARSER = re.compile(r'ATTRS{serial}=="(?P.+?)"') + + +class AsyncByonoy: + """Async wrapper around Byonoy Device Library.""" + + @staticmethod + def match_device_with_sn( + sn: str, devices: List[AbsProtocol.Device] + ) -> AbsProtocol.Device: + for device in devices: + if device.sn == sn: + return device + raise RuntimeError(f"Unavailble module with serial number: {sn}") + + @staticmethod + def serial_number_from_port(name: str) -> str: + """ + Get the serial number from a port using pyusb. + """ + port_numbers = tuple(int(s) for s in name.split("-")[1].split(".")) + device = usb_core.find(port_numbers=port_numbers) + if device: + return str(device.serial_number) + raise RuntimeError(f"Could not find serial number for port: {name}") + + @classmethod + async def create( + cls, + port: str, + usb_port: USBPort, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> AsyncByonoy: + """ + Create an AsyncByonoy instance. + + Args: + port: url or port name + baud_rate: the baud rate + timeout: optional timeout in seconds + write_timeout: optional write timeout in seconds + loop: optional event loop. if None get_running_loop will be used + reset_buffer_before_write: reset the serial input buffer before + writing to it + """ + loop = loop or asyncio.get_running_loop() + executor = ThreadPoolExecutor(max_workers=1) + + import pybyonoy_device_library as byonoy # type: ignore[import-not-found] + + interface: AbsProtocol = byonoy + + device_sn = cls.serial_number_from_port(usb_port.name) + found: List[AbsProtocol.Device] = await loop.run_in_executor( + executor=executor, func=byonoy.byonoy_available_devices + ) + device = cls.match_device_with_sn(device_sn, found) + + return cls( + interface=interface, + device=device, + executor=executor, + loop=loop, + ) + + def __init__( + self, + interface: AbsProtocol, + device: AbsProtocol.Device, + executor: ThreadPoolExecutor, + loop: asyncio.AbstractEventLoop, + ) -> None: + """ + Constructor + + Args: + serial: connected Serial object + executor: a thread pool executor + loop: event loop + """ + self._interface = interface + self._device = device + self._executor = executor + self._loop = loop + self._supported_wavelengths: Optional[list[int]] = None + self._device_handle: Optional[int] = None + self._current_config: Optional[AbsProtocol.MeasurementConfig] = None + + def _cleanup(self) -> None: + self._device_handle = None + + def _open(self) -> None: + err, device_handle = self._interface.byonoy_open_device(self._device) + if err.name != "BYONOY_ERROR_NO_ERROR": + raise RuntimeError(f"Error opening device: {err}") + self._device_handle = device_handle + + def _free(self) -> None: + if self._device_handle: + self._interface.byonoy_free_device(self._device_handle) + self._cleanup() + + def verify_device_handle(self) -> int: + assert self._device_handle is not None, RuntimeError( + "Device handle not set up." + ) + return self._device_handle + + def _raise_if_error( + self, + err_name: ErrorCodeNames, + msg: str = "Error occurred: ", + ) -> None: + if err_name != "BYONOY_ERROR_NO_ERROR": + raise RuntimeError(msg, err_name) + + def _get_device_information(self) -> AbsProtocol.DeviceInfo: + handle = self.verify_device_handle() + err, device_info = self._interface.byonoy_get_device_information(handle) + self._raise_if_error(err.name, "Error getting device information: ") + return device_info + + def _get_device_status(self) -> AbsProtocol.DeviceState: + handle = self.verify_device_handle() + err, status = self._interface.byonoy_get_device_status(handle) + self._raise_if_error(err.name, "Error getting device status: ") + return status + + def _get_slot_status(self) -> AbsProtocol.SlotState: + handle = self.verify_device_handle() + err, slot_status = self._interface.byonoy_get_device_slot_status(handle) + self._raise_if_error(err.name, "Error getting slot status: ") + return slot_status + + def _get_lid_status(self) -> bool: + handle = self.verify_device_handle() + lid_on: bool + err, lid_on = self._interface.byonoy_get_device_parts_aligned(handle) + self._raise_if_error(err.name, "Error getting lid status: ") + return lid_on + + def _get_supported_wavelengths(self) -> List[int]: + handle = self.verify_device_handle() + wavelengths: List[int] + err, wavelengths = self._interface.byonoy_abs96_get_available_wavelengths( + handle + ) + self._raise_if_error(err.name, "Error getting available wavelengths: ") + self._supported_wavelengths = wavelengths + return wavelengths + + def _initialize_measurement(self, conf: AbsProtocol.MeasurementConfig) -> None: + handle = self.verify_device_handle() + err = self._interface.byonoy_abs96_initialize_single_measurement(handle, conf) + self._raise_if_error(err.name, "Error initializing measurement: ") + self._current_config = conf + + def _single_measurement(self, conf: AbsProtocol.MeasurementConfig) -> List[float]: + handle = self.verify_device_handle() + measurements: List[float] + err, measurements = self._interface.byonoy_abs96_single_measure(handle, conf) + self._raise_if_error(err.name, "Error getting single measurement: ") + return measurements + + def _set_sample_wavelength(self, wavelength: int) -> AbsProtocol.MeasurementConfig: + if not self._supported_wavelengths: + self._get_supported_wavelengths() + assert self._supported_wavelengths + if wavelength in self._supported_wavelengths: + conf = self._interface.ByonoyAbs96SingleMeasurementConfig() + conf.sample_wavelength = wavelength + return conf + else: + raise ValueError( + f"Unsupported wavelength: {wavelength}, expected: {self._supported_wavelengths}" + ) + + def _initialize(self, wavelength: int) -> None: + conf = self._set_sample_wavelength(wavelength) + self._initialize_measurement(conf) + + def _get_single_measurement(self, wavelength: int) -> List[float]: + initialized = self._current_config + assert initialized and initialized.sample_wavelength == wavelength + return self._single_measurement(initialized) + + async def open(self) -> None: + """ + Open the connection. + + Returns: None + """ + return await self._loop.run_in_executor( + executor=self._executor, func=self._open + ) + + async def close(self) -> None: + """ + Close the connection + + Returns: None + """ + await self._loop.run_in_executor(executor=self._executor, func=self._free) + + async def is_open(self) -> bool: + """ + Check if connection is open. + + Returns: boolean + """ + return self._device_handle is not None + + async def get_device_static_info(self) -> Dict[str, str]: + return { + "serial": self._device.sn, + "model": "ABS96", + } + + async def get_device_information(self) -> Dict[str, str]: + device_info = await self._loop.run_in_executor( + executor=self._executor, func=self._get_device_information + ) + return { + "serial_number": device_info.sn, + "reference_number": device_info.ref_no, + "version": device_info.version, + } + + async def get_lid_status(self) -> AbsorbanceReaderLidStatus: + lid_info = await self._loop.run_in_executor( + executor=self._executor, func=self._get_lid_status + ) + return ( + AbsorbanceReaderLidStatus.ON if lid_info else AbsorbanceReaderLidStatus.OFF + ) + + async def get_supported_wavelengths(self) -> list[int]: + return await self._loop.run_in_executor( + executor=self._executor, func=self._get_supported_wavelengths + ) + + async def initialize(self, wavelength: int) -> None: + return await self._loop.run_in_executor( + executor=self._executor, func=partial(self._initialize, wavelength) + ) + + async def get_single_measurement(self, wavelength: int) -> List[float]: + return await self._loop.run_in_executor( + executor=self._executor, + func=partial(self._get_single_measurement, wavelength), + ) + + async def get_plate_presence(self) -> AbsorbanceReaderPlatePresence: + return AbsorbanceReaderPlatePresence.UNKNOWN diff --git a/api/src/opentrons/drivers/absorbance_reader/driver.py b/api/src/opentrons/drivers/absorbance_reader/driver.py new file mode 100644 index 00000000000..538bc83d70d --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/driver.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +import asyncio +from typing import Dict, Optional, List + +from opentrons.drivers.types import AbsorbanceReaderLidStatus +from opentrons.drivers.absorbance_reader.abstract import AbstractAbsorbanceReaderDriver +from opentrons.drivers.rpi_drivers.types import USBPort +from .async_byonoy import AsyncByonoy + + +class AbsorbanceReaderDriver(AbstractAbsorbanceReaderDriver): + @classmethod + async def create( + cls, + port: str, + usb_port: USBPort, + loop: Optional[asyncio.AbstractEventLoop], + ) -> AbsorbanceReaderDriver: + """Create an absorbance reader driver.""" + from .async_byonoy import AsyncByonoy + + connection = await AsyncByonoy.create(port=port, usb_port=usb_port, loop=loop) + return cls(connection=connection) + + def __init__(self, connection: AsyncByonoy) -> None: + self._connection = connection + + async def get_device_info(self) -> Dict[str, str]: + """Get device info""" + connected = await self.is_connected() + if not connected: + info = await self._connection.get_device_static_info() + else: + info = await self._connection.get_device_information() + return info + + async def connect(self) -> None: + """Connect to absorbance reader""" + await self._connection.open() + + async def disconnect(self) -> None: + """Disconnect from absorbance reader""" + await self._connection.close() + + async def is_connected(self) -> bool: + """Check connection to absorbance reader""" + return await self._connection.is_open() + + async def get_lid_status(self) -> AbsorbanceReaderLidStatus: + return await self._connection.get_lid_status() + + async def get_available_wavelengths(self) -> List[int]: + return await self._connection.get_supported_wavelengths() + + async def get_single_measurement(self, wavelength: int) -> List[float]: + return await self._connection.get_single_measurement(wavelength) + + async def initialize_measurement(self, wavelength: int) -> None: + await self._connection.initialize(wavelength) + + async def get_status(self) -> None: + pass diff --git a/api/src/opentrons/drivers/absorbance_reader/hid_protocol.py b/api/src/opentrons/drivers/absorbance_reader/hid_protocol.py new file mode 100644 index 00000000000..6ddd82aa030 --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/hid_protocol.py @@ -0,0 +1,115 @@ +from typing import ( + Dict, + Protocol, + List, + Literal, + Tuple, + ClassVar, + runtime_checkable, + TypeVar, +) + +Response = TypeVar("Response") + +ErrorCodeNames = Literal[ + "BYONOY_ERROR_NO_ERROR", + "BYONOY_ERROR_UNKNOWN_ERROR", + "BYONOY_ERROR_DEVICE_CLOSED", + "BYONOY_ERROR_INVALID_ARGUMENT", + "BYONOY_ERROR_NO_MEMORY", + "BYONOY_ERROR_UNSUPPORTED_OPERATION", + "BYONOY_ERROR_DEVICE_COMMUNICATION_FAILURE", + "BYONOY_ERROR_DEVICE_OPERATION_FAILED", + "BYONOY_ERROR_DEVICE_OPEN_PREFIX", + "BYONOY_ERROR_DEVICE_NOT_FOUND", + "BYONOY_ERROR_DEVICE_TOO_NEW", + "BYONOY_ERROR_DEVICE_ALREADY_OPEN", + "BYONOY_ERROR_FIRMWARE_UPDATE_ERROR_PREFIX", + "BYONOY_ERROR_FIRMWARE_UPDATE_FILE_NOT_FOUND", + "BYONOY_ERROR_FIRMWARE_UPDATE_FILE_NOT_VALID", + "BYONOY_ERROR_FIRMWARE_UPDATE_FAILED", + "BYONOY_ERROR_FILE_ERROR_PREFIX", + "BYONOY_ERROR_FILE_WRITE_ERROR", + "BYONOY_ERROR_MEASUTEMNT_ERROR_PREFIX", + "BYONOY_ERROR_MEASUTEMNT_SLOT_NOT_EMPTY", + "BYONOY_ERROR_NOT_INITIALIZED", + "BYONOY_ERROR_INTERNAL", +] + + +@runtime_checkable +class AbsorbanceHidInterface(Protocol): + @runtime_checkable + class Device(Protocol): + sn: str + + @runtime_checkable + class ErrorCode(Protocol): + __members__: Dict[ErrorCodeNames, int] + name: ErrorCodeNames + value: int + + @runtime_checkable + class SlotState(Protocol): + __members__: ClassVar[Dict[str, int]] + + @runtime_checkable + class MeasurementConfig(Protocol): + sample_wavelength: int + + @runtime_checkable + class DeviceInfo(Protocol): + ref_no: str + sn: str + version: str + + @runtime_checkable + class DeviceState(Protocol): + __members__: ClassVar[Dict[str, int]] + + def ByonoyAbs96SingleMeasurementConfig(self) -> MeasurementConfig: + ... + + def byonoy_open_device(self, device: Device) -> Tuple[ErrorCode, int]: + ... + + def byonoy_free_device(self, device_handle: int) -> Tuple[ErrorCode, bool]: + ... + + def byonoy_get_device_information( + self, device_handle: int + ) -> Tuple[ErrorCode, DeviceInfo]: + ... + + def byonoy_get_device_status( + self, device_handle: int + ) -> Tuple[ErrorCode, DeviceState]: + ... + + def byonoy_get_device_slot_status( + self, device_handle: int + ) -> Tuple[ErrorCode, SlotState]: + ... + + def byonoy_get_device_parts_aligned( + self, device_handle: int + ) -> Tuple[ErrorCode, bool]: + ... + + def byonoy_abs96_get_available_wavelengths( + self, device_handle: int + ) -> Tuple[ErrorCode, List[int]]: + ... + + def byonoy_abs96_initialize_single_measurement( + self, device_handle: int, conf: MeasurementConfig + ) -> ErrorCode: + ... + + def byonoy_abs96_single_measure( + self, device_handle: int, conf: MeasurementConfig + ) -> Tuple[ErrorCode, List[float]]: + ... + + def byonoy_available_devices(self) -> List[Device]: + ... diff --git a/api/src/opentrons/drivers/absorbance_reader/simulator.py b/api/src/opentrons/drivers/absorbance_reader/simulator.py new file mode 100644 index 00000000000..b189030b653 --- /dev/null +++ b/api/src/opentrons/drivers/absorbance_reader/simulator.py @@ -0,0 +1,55 @@ +from typing import Dict, List, Optional +from opentrons.util.async_helpers import ensure_yield + +from opentrons.drivers.types import AbsorbanceReaderLidStatus + +from .abstract import AbstractAbsorbanceReaderDriver + + +class SimulatingDriver(AbstractAbsorbanceReaderDriver): + def __init__(self, serial_number: Optional[str] = None) -> None: + self._serial_number = serial_number + + @ensure_yield + async def get_device_info(self) -> Dict[str, str]: + """Get device info""" + return { + "serial": self._serial_number if self._serial_number else "dummySerialAR", + "model": "dummyModelAR", + "version": "dummyVersionAR", + } + + @ensure_yield + async def connect(self) -> None: + """Connect to absorbance reader""" + pass + + @ensure_yield + async def disconnect(self) -> None: + """Disconnect from absorbance reader""" + pass + + @ensure_yield + async def is_connected(self) -> bool: + """Check connection to absorbance reader""" + return True + + @ensure_yield + async def get_lid_status(self) -> AbsorbanceReaderLidStatus: + return AbsorbanceReaderLidStatus.ON + + @ensure_yield + async def get_available_wavelengths(self) -> List[int]: + return [450, 570, 600, 650] + + @ensure_yield + async def get_single_measurement(self, wavelength: int) -> List[float]: + return [0.0] + + @ensure_yield + async def initialize_measurement(self, wavelength: int) -> None: + pass + + @ensure_yield + async def get_status(self) -> None: + pass diff --git a/api/src/opentrons/drivers/rpi_drivers/types.py b/api/src/opentrons/drivers/rpi_drivers/types.py index 5c36d0109c2..acb177a05b4 100644 --- a/api/src/opentrons/drivers/rpi_drivers/types.py +++ b/api/src/opentrons/drivers/rpi_drivers/types.py @@ -1,5 +1,6 @@ from __future__ import annotations import enum +import re from itertools import groupby from dataclasses import dataclass from typing import List, Optional, Tuple @@ -27,6 +28,26 @@ class PortGroup: FLEX_B2_USB_PORT_GROUP_FRONT = 7 FLEX_B2_USB_PORTS = {"4": 1, "3": 2, "2": 3, "1": 4} +BUS_PATH = "/sys/bus/usb/devices/usb1/" + +# Example usb path might look like: +# '/sys/bus/usb/devices/usb1/1-1/1-1.3/1-1.3:1.0/tty/ttyACM1/dev'. +# Example hid device path might look like: +# '/sys/bus/usb/devices/usb1/1-1/1-1.3/1-1.3:1.0/0003:16D0:1199.0002/hidraw/hidraw0/dev' +# There is only 1 bus that supports USB on the raspberry pi. +USB_PORT_INFO = re.compile( + r""" + (?P(\d[\d]*-\d[\d\.]*[/]?)+): + (?P + \d.\d/ + (tty/tty(\w{4})/dev | [\w:\.]+?/hidraw/hidraw\d/dev) + ) + """, + re.VERBOSE, +) + +HUB_PATTERN = re.compile(r"(\d-[\d.]+\d?)[\/:]") + @dataclass(frozen=True) class USBPort: @@ -38,7 +59,9 @@ class USBPort: device_path: str = "" @classmethod - def build(cls, port_path: str, board_revision: BoardRevision) -> "USBPort": + def build( + cls, full_path: str, board_revision: BoardRevision + ) -> Optional["USBPort"]: """ Build a USBPort dataclass. @@ -52,8 +75,13 @@ def build(cls, port_path: str, board_revision: BoardRevision) -> "USBPort": Returns: Tuple of the port number, port group, hub, hub port, device path, and name """ - full_name, device_path = port_path.split(":") - port_nodes = cls.get_unique_nodes(full_name) + match = USB_PORT_INFO.search(full_path) + if not match: + return None + + port_path = match.group("port_path") + device_path = match.group("device_path") + port_nodes = cls.get_unique_nodes(port_path) hub, port, hub_port, name = cls.find_hub(port_nodes, board_revision) hub, port_group, port, hub_port = cls.map_to_revision( board_revision, @@ -91,43 +119,52 @@ def find_hub( :param port_nodes: A list of unique port id(s) :returns: Tuple of the hub, port number, hub_port and name """ - if len(port_nodes) > 2: - port_info = port_nodes[2].split(".") - hub: Optional[int] = int(port_info[1]) - port = int(port_info[2]) - hub_port: Optional[int] = int(port_info[3]) - name = port_nodes[2] - elif len(port_nodes) > 1: - if board_revision == BoardRevision.OG: - port_info = port_nodes[1].split(".") + if len(port_nodes) == 1 and "." not in port_nodes[0]: + # if no hub is attached, such as on a dev kit, the port + # nodes available will be 1-1 + port = int(port_nodes[0].split("-")[1]) + hub = None + hub_port = None + name = port_nodes[0] + else: + port_nodes = [node for node in port_nodes if "." in node] + if len(port_nodes) > 2: + port_info = port_nodes[2].split(".") hub = int(port_info[1]) - port = int(port_info[1]) - hub_port = int(port_info[2]) - name = port_nodes[1] + port = int(port_info[2]) + hub_port = int(port_info[3]) + name = port_nodes[2] + elif len(port_nodes) > 1: + if board_revision == BoardRevision.OG: + port_info = port_nodes[1].split(".") + hub = int(port_info[1]) + port = int(port_info[1]) + hub_port = int(port_info[2]) + name = port_nodes[1] + else: + port_info = port_nodes[1].split(".") + hub = int(port_info[1]) + name = port_nodes[1] + if (board_revision == BoardRevision.FLEX_B2) and ( + hub == FLEX_B2_USB_PORT_GROUP_FRONT + ): + port = 9 + hub_port = int(port_info[2]) + else: + port = int(port_info[2]) + hub_port = None else: - port_info = port_nodes[1].split(".") - hub = int(port_info[1]) - name = port_nodes[1] - if (board_revision == BoardRevision.FLEX_B2) and ( - hub == FLEX_B2_USB_PORT_GROUP_FRONT - ): + if board_revision == BoardRevision.FLEX_B2: + port_info = port_nodes[0].split(".") + hub = int(port_info[1]) port = 9 - hub_port = int(port_info[2]) + hub_port = None + name = port_nodes[0] else: - port = int(port_info[2]) + port = int(port_nodes[0].split(".")[1]) + hub = None hub_port = None - else: - if board_revision == BoardRevision.FLEX_B2: - port_info = port_nodes[0].split(".") - hub = int(port_info[1]) - port = 9 - hub_port = None - name = port_nodes[0] - else: - port = int(port_nodes[0].split(".")[1]) - hub = None - hub_port = None - name = port_nodes[0] + name = port_nodes[0] return hub, port, hub_port, name @staticmethod @@ -161,11 +198,12 @@ def get_unique_nodes(full_name: str) -> List[str]: :param full_name: Full path of the physical USB Path :returns: List of separated USB port paths """ - port_nodes = [] - for node in full_name.split("/"): - if node not in port_nodes: - port_nodes.append(node) - return port_nodes + all_match = HUB_PATTERN.findall(full_name) + match_set = [] + for match in all_match: + if match not in match_set: + match_set.append(match) + return match_set @staticmethod def map_to_revision( diff --git a/api/src/opentrons/drivers/rpi_drivers/usb.py b/api/src/opentrons/drivers/rpi_drivers/usb.py index 04ee5496c4a..b2446a96b73 100644 --- a/api/src/opentrons/drivers/rpi_drivers/usb.py +++ b/api/src/opentrons/drivers/rpi_drivers/usb.py @@ -6,7 +6,6 @@ """ import subprocess -import re import os from typing import List, Union @@ -17,16 +16,7 @@ from opentrons.hardware_control.types import BoardRevision from .interfaces import USBDriverInterface -from .types import USBPort - - -# Example usb path might look like: -# '/sys/bus/usb/devices/usb1/1-1/1-1.3/1-1.3:1.0/tty/ttyACM1/dev'. -# There is only 1 bus that supports USB on the raspberry pi. -BUS_PATH = "/sys/bus/usb/devices/usb1/" -PORT_PATTERN = r"(/\d-\d(\.?\d)+)+:" -DEVICE_PATH = r"\d.\d/tty/tty(\w{4})/dev" -USB_PORT_INFO = re.compile(PORT_PATTERN + DEVICE_PATH) +from .types import BUS_PATH, USBPort class USBBus(USBDriverInterface): @@ -73,11 +63,9 @@ def _read_usb_bus(self) -> List[USBPort]: active_ports = self._read_bus() port_matches = [] for port in active_ports: - match = USB_PORT_INFO.search(port) - if match: - port_matches.append( - USBPort.build(match.group(0).strip("/"), self._board_revision) - ) + usb_port = USBPort.build(port.strip("/"), self._board_revision) + if usb_port: + port_matches.append(usb_port) return port_matches def match_virtual_ports( diff --git a/api/src/opentrons/drivers/types.py b/api/src/opentrons/drivers/types.py index 7186025dc35..09691ff051f 100644 --- a/api/src/opentrons/drivers/types.py +++ b/api/src/opentrons/drivers/types.py @@ -58,3 +58,19 @@ class ThermocyclerLidStatus(str, Enum): IN_BETWEEN = "in_between" OPEN = "open" MAX = "max" + + +class AbsorbanceReaderLidStatus(str, Enum): + """Absorbance reader lid status.""" + + UNKNOWN = "unknown" + ON = "on" + OFF = "off" + + +class AbsorbanceReaderPlatePresence(str, Enum): + """Absorbance reader plate presence.""" + + UNKNOWN = "unknown" + PRESENT = "present" + ABSENCE = "absence" diff --git a/api/src/opentrons/hardware_control/modules/__init__.py b/api/src/opentrons/hardware_control/modules/__init__.py index 8675bc59de9..3e4c14f0baf 100644 --- a/api/src/opentrons/hardware_control/modules/__init__.py +++ b/api/src/opentrons/hardware_control/modules/__init__.py @@ -3,6 +3,7 @@ from .magdeck import MagDeck from .thermocycler import Thermocycler from .heater_shaker import HeaterShaker +from .absorbance_reader import AbsorbanceReader from .update import update_firmware from .utils import MODULE_TYPE_BY_NAME, build from .types import ( @@ -45,4 +46,5 @@ "HeaterShakerStatus", "SpeedStatus", "LiveData", + "AbsorbanceReader", ] diff --git a/api/src/opentrons/hardware_control/modules/absorbance_reader.py b/api/src/opentrons/hardware_control/modules/absorbance_reader.py new file mode 100644 index 00000000000..8f3c65e3ace --- /dev/null +++ b/api/src/opentrons/hardware_control/modules/absorbance_reader.py @@ -0,0 +1,172 @@ +import asyncio +from typing import Optional, Mapping, List, Dict, Any, Tuple + +from opentrons.drivers.rpi_drivers.types import USBPort +from opentrons.drivers.absorbance_reader import ( + AbstractAbsorbanceReaderDriver, + AbsorbanceReaderDriver, + SimulatingDriver, +) +from opentrons.hardware_control.execution_manager import ExecutionManager +from opentrons.hardware_control.modules import mod_abc +from opentrons.hardware_control.modules.types import ( + ModuleType, + AbsorbanceReaderStatus, + LiveData, + UploadFunction, +) + + +async def upload_func_placeholder( + dfu_serial: str, firmware_file_path: str, kwargs: Dict[str, Any] +) -> Tuple[bool, str]: + return False, "Not implemented" + + +class AbsorbanceReader(mod_abc.AbstractModule): + """Hardware control interface for an attached Absorbance Reader module.""" + + MODULE_TYPE = ModuleType.ABSORBANCE_READER + + @classmethod + async def build( + cls, + port: str, + usb_port: USBPort, + execution_manager: ExecutionManager, + hw_control_loop: asyncio.AbstractEventLoop, + poll_interval_seconds: Optional[float] = None, + simulating: bool = False, + sim_model: Optional[str] = None, + sim_serial_number: Optional[str] = None, + ) -> "AbsorbanceReader": + """Create an AbsorbanceReader.""" + driver: AbstractAbsorbanceReaderDriver + if not simulating: + driver = await AbsorbanceReaderDriver.create( + port, usb_port, hw_control_loop + ) + else: + driver = SimulatingDriver(serial_number=sim_serial_number) + module = cls( + port=port, + usb_port=usb_port, + device_info=await driver.get_device_info(), + execution_manager=execution_manager, + driver=driver, + hw_control_loop=hw_control_loop, + ) + return module + + def __init__( + self, + port: str, + usb_port: USBPort, + driver: AbstractAbsorbanceReaderDriver, + device_info: Mapping[str, str], + execution_manager: ExecutionManager, + hw_control_loop: asyncio.AbstractEventLoop, + ) -> None: + super().__init__(port, usb_port, execution_manager, hw_control_loop) + self._driver = driver + self._device_info = device_info + + async def deactivate(self, must_be_running: bool = True) -> None: + """Deactivate the module. + + Contains an override to the `wait_for_is_running` step in cases where the + module must be deactivated regardless of context.""" + await self._driver.disconnect() + + @property + def status(self) -> AbsorbanceReaderStatus: + """Return some string describing status.""" + return AbsorbanceReaderStatus.IDLE + + @property + def device_info(self) -> Mapping[str, str]: + """Return a dict of the module's static information (serial, etc)""" + return self._device_info + + @property + def live_data(self) -> LiveData: + """Return a dict of the module's dynamic information""" + return { + "status": "idle", + "data": { + "sampleWavelength": 400, + }, + } + + @property + def is_simulated(self) -> bool: + """True if this is a simulated module.""" + return isinstance(self._driver, SimulatingDriver) + + @property + def port(self) -> str: + """The virtual port where the module is connected.""" + return self._port + + @property + def usb_port(self) -> USBPort: + """The physical port where the module is connected.""" + return self._usb_port + + async def wait_for_is_running(self) -> None: + if not self.is_simulated: + await self._execution_manager.wait_for_is_running() + + async def prep_for_update(self) -> str: + """Prepare for an update. + + By the time this coroutine completes, the hardware should be ready + to take an update. This implicitly tears down the module instance; + it does not need to be either working or recoverable after this + coroutine completes. + + :returns str: The port we're running on. + """ + return "" + + def model(self) -> str: + """A name for this specific module, matching module defs""" + return "absorbanceReaderV1" + + @classmethod + def name(cls) -> str: + """A shortname used for matching usb ports, among other things""" + return "absorbancereader" + + def firmware_prefix(self) -> str: + """The prefix used for looking up firmware""" + # TODO: (AA) This is a placeholder + return "" + + def bootloader(self) -> UploadFunction: + """Bootloader mode""" + return upload_func_placeholder + + async def cleanup(self) -> None: + """Clean up the module instance. + + Clean up, i.e. stop pollers, disconnect serial, etc in preparation for + object destruction. + """ + await self._driver.disconnect() + + async def set_sample_wavelength(self, wavelength: int) -> None: + """Set the Absorbance Reader's active wavelength.""" + await self._driver.initialize_measurement(wavelength) + + async def start_measure(self, wavelength: int) -> None: + """Initiate a single measurement.""" + await self._driver.get_single_measurement(wavelength) + + async def get_supported_wavelengths(self) -> List[int]: + """Get the Absorbance Reader's supported wavelengths.""" + return await self._driver.get_available_wavelengths() + + async def get_current_wavelength(self) -> None: + """Get the Absorbance Reader's current active wavelength.""" + pass diff --git a/api/src/opentrons/hardware_control/modules/types.py b/api/src/opentrons/hardware_control/modules/types.py index f0980fca2b1..e538e603f8d 100644 --- a/api/src/opentrons/hardware_control/modules/types.py +++ b/api/src/opentrons/hardware_control/modules/types.py @@ -25,6 +25,7 @@ TemperatureModuleType, HeaterShakerModuleType, MagneticBlockType, + AbsorbanceReaderType, ) @@ -51,6 +52,7 @@ class ModuleType(str, Enum): MAGNETIC: MagneticModuleType = "magneticModuleType" HEATER_SHAKER: HeaterShakerModuleType = "heaterShakerModuleType" MAGNETIC_BLOCK: MagneticBlockType = "magneticBlockType" + ABSORBANCE_READER: AbsorbanceReaderType = "absorbanceReaderType" @classmethod def from_model(cls, model: ModuleModel) -> ModuleType: @@ -64,6 +66,8 @@ def from_model(cls, model: ModuleModel) -> ModuleType: return cls.HEATER_SHAKER if isinstance(model, MagneticBlockModel): return cls.MAGNETIC_BLOCK + if isinstance(model, AbsorbanceReaderModel): + return cls.ABSORBANCE_READER @classmethod def to_module_fixture_id(cls, module_type: ModuleType) -> str: @@ -105,6 +109,10 @@ class MagneticBlockModel(str, Enum): MAGNETIC_BLOCK_V1: str = "magneticBlockV1" +class AbsorbanceReaderModel(str, Enum): + ABSORBANCE_READER_V1: str = "absorbanceReaderV1" + + def module_model_from_string(model_string: str) -> ModuleModel: for model_enum in { MagneticModuleModel, @@ -112,6 +120,7 @@ def module_model_from_string(model_string: str) -> ModuleModel: ThermocyclerModuleModel, HeaterShakerModuleModel, MagneticBlockModel, + AbsorbanceReaderModel, }: try: return cast(ModuleModel, model_enum(model_string)) @@ -166,6 +175,7 @@ class ModuleInfo(NamedTuple): ThermocyclerModuleModel, HeaterShakerModuleModel, MagneticBlockModel, + AbsorbanceReaderModel, ] @@ -194,3 +204,9 @@ class HeaterShakerStatus(str, Enum): IDLE = "idle" RUNNING = "running" ERROR = "error" + + +class AbsorbanceReaderStatus(str, Enum): + IDLE = "idle" + MEASURING = "measuring" + ERROR = "error" diff --git a/api/src/opentrons/hardware_control/modules/utils.py b/api/src/opentrons/hardware_control/modules/utils.py index 0c213ead6a1..862617e2d60 100644 --- a/api/src/opentrons/hardware_control/modules/utils.py +++ b/api/src/opentrons/hardware_control/modules/utils.py @@ -12,6 +12,7 @@ from .magdeck import MagDeck from .thermocycler import Thermocycler from .heater_shaker import HeaterShaker +from .absorbance_reader import AbsorbanceReader log = logging.getLogger(__name__) @@ -24,6 +25,7 @@ TempDeck.name(): TempDeck.MODULE_TYPE, Thermocycler.name(): Thermocycler.MODULE_TYPE, HeaterShaker.name(): HeaterShaker.MODULE_TYPE, + AbsorbanceReader.name(): AbsorbanceReader.MODULE_TYPE, } _MODULE_CLS_BY_TYPE: Dict[ModuleType, Type[AbstractModule]] = { @@ -31,6 +33,7 @@ TempDeck.MODULE_TYPE: TempDeck, Thermocycler.MODULE_TYPE: Thermocycler, HeaterShaker.MODULE_TYPE: HeaterShaker, + AbsorbanceReader.MODULE_TYPE: AbsorbanceReader, } diff --git a/api/src/opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py b/api/src/opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py new file mode 100644 index 00000000000..f694f798a71 --- /dev/null +++ b/api/src/opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py @@ -0,0 +1,20 @@ +"""Heater-Shaker Module sub-state.""" +from dataclasses import dataclass +from typing import List, NewType, Optional + + +AbsorbanceReaderId = NewType("AbsorbanceReaderId", str) + + +@dataclass(frozen=True) +class AbsorbanceReaderSubState: + """Absorbance-Plate-Reader-specific state.""" + + module_id: AbsorbanceReaderId + initialized: bool + is_lid_open: bool + is_loaded: bool + is_measuring: bool + temperature: float + sample_wavelength: Optional[int] + supported_wavelengths: Optional[List[int]] diff --git a/api/tests/opentrons/drivers/absorbance_reader/__init__.py b/api/tests/opentrons/drivers/absorbance_reader/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/api/tests/opentrons/drivers/absorbance_reader/test_driver.py b/api/tests/opentrons/drivers/absorbance_reader/test_driver.py new file mode 100644 index 00000000000..ecda705fa3e --- /dev/null +++ b/api/tests/opentrons/drivers/absorbance_reader/test_driver.py @@ -0,0 +1,168 @@ +from mock import MagicMock +import pytest +import asyncio +from enum import Enum +from concurrent.futures.thread import ThreadPoolExecutor + +from opentrons.drivers.absorbance_reader import ( + AbsorbanceReaderDriver, + AbsorbanceHidInterface, +) +from opentrons.drivers.absorbance_reader.async_byonoy import AsyncByonoy +from opentrons.drivers.types import AbsorbanceReaderLidStatus + + +@pytest.fixture +def mock_interface() -> MagicMock: + return MagicMock(spec=AbsorbanceHidInterface) + + +@pytest.fixture +def mock_device() -> MagicMock: + return MagicMock(spec=AbsorbanceHidInterface.Device) + + +class MockErrorCode(Enum): + BYONOY_ERROR_NO_ERROR = "no_error" + BYONOY_ERROR = "error" + + +@pytest.fixture +async def mock_async_byonoy(mock_interface, mock_device) -> AsyncByonoy: + loop = asyncio.get_running_loop() + return AsyncByonoy( + mock_interface, mock_device, ThreadPoolExecutor(max_workers=1), loop + ) + + +@pytest.fixture +async def driver(mock_async_byonoy: AsyncByonoy) -> AbsorbanceReaderDriver: + return AbsorbanceReaderDriver(mock_async_byonoy) + + +@pytest.fixture +async def connected_driver(driver: AbsorbanceReaderDriver) -> AbsorbanceReaderDriver: + driver._connection._device_handle = 1 + return driver + + +async def test_driver_connect_disconnect( + mock_interface: MagicMock, + driver: AbsorbanceReaderDriver, +) -> None: + mock_interface.byonoy_open_device.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR, + 1, + ) + + assert not await driver.is_connected() + await driver.connect() + + mock_interface.byonoy_open_device.assert_called_once() + assert await driver.is_connected() + assert driver._connection.verify_device_handle() + assert driver._connection._device_handle == 1 + + mock_interface.byonoy_free_device.return_value = MockErrorCode.BYONOY_ERROR_NO_ERROR + await driver.disconnect() + + assert not await driver.is_connected() + assert driver._connection._device_handle is None + + +async def test_driver_get_device_info( + mock_interface: MagicMock, + connected_driver: AbsorbanceReaderDriver, +) -> None: + + DEVICE_INFO = MagicMock(AbsorbanceHidInterface.DeviceInfo) + DEVICE_INFO.ref_no = "456" + DEVICE_INFO.sn = "123" + DEVICE_INFO.version = "1.0" + + mock_interface.byonoy_get_device_information.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR, + DEVICE_INFO, + ) + + info = await connected_driver.get_device_info() + + mock_interface.byonoy_get_device_information.assert_called_once() + assert info == {"serial_number": "123", "reference_number": "456", "version": "1.0"} + + +@pytest.mark.parametrize( + "parts_aligned, module_status", + [(True, AbsorbanceReaderLidStatus.ON), (False, AbsorbanceReaderLidStatus.OFF)], +) +async def test_driver_get_lid_status( + mock_interface: MagicMock, + connected_driver: AbsorbanceReaderDriver, + parts_aligned: bool, + module_status: AbsorbanceReaderLidStatus, +) -> None: + + mock_interface.byonoy_get_device_parts_aligned.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR, + parts_aligned, + ) + + status = await connected_driver.get_lid_status() + + mock_interface.byonoy_get_device_parts_aligned.assert_called_once() + assert status == module_status + + +async def test_driver_get_supported_wavelengths( + mock_interface: MagicMock, + connected_driver: AbsorbanceReaderDriver, +) -> None: + SUPPORTED_WAVELENGTHS = [450, 500] + mock_interface.byonoy_abs96_get_available_wavelengths.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR, + SUPPORTED_WAVELENGTHS, + ) + + assert not connected_driver._connection._supported_wavelengths + + wavelengths = await connected_driver.get_available_wavelengths() + + mock_interface.byonoy_abs96_get_available_wavelengths.assert_called_once() + assert connected_driver._connection._supported_wavelengths == SUPPORTED_WAVELENGTHS + assert wavelengths == SUPPORTED_WAVELENGTHS + + +async def test_driver_initialize_and_read( + mock_interface: MagicMock, + connected_driver: AbsorbanceReaderDriver, +) -> None: + # set up mock interface + connected_driver._connection._supported_wavelengths = [450, 500] + mock_interface.byonoy_abs96_initialize_single_measurement.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR + ) + mock_interface.ByonoyAbs96SingleMeasurementConfig = MagicMock( + spec=AbsorbanceHidInterface.MeasurementConfig + ) + + # current config should not have been setup yet + assert not connected_driver._connection._current_config + await connected_driver.initialize_measurement(450) + + conf = connected_driver._connection._current_config + assert conf and conf.sample_wavelength == 450 + mock_interface.byonoy_abs96_initialize_single_measurement.assert_called_once_with( + 1, conf + ) + + # setup up mock interface + MEASURE_RESULT = [0.1] * 96 + mock_interface.byonoy_abs96_single_measure.return_value = ( + MockErrorCode.BYONOY_ERROR_NO_ERROR, + MEASURE_RESULT, + ) + + result = await connected_driver.get_single_measurement(450) + mock_interface.byonoy_abs96_single_measure.assert_called_once_with(1, conf) + + assert result == MEASURE_RESULT diff --git a/g-code-testing/Pipfile b/g-code-testing/Pipfile index 80f83a4561a..0b39a9dd222 100644 --- a/g-code-testing/Pipfile +++ b/g-code-testing/Pipfile @@ -31,6 +31,7 @@ flake8-docstrings = "~=1.7.0" flake8-noqa = "~=1.4.0" black = "==22.3.0" decoy = "~=2.1.1" +pyusb = "==1.2.1" [requires] python_version = "3.10" diff --git a/g-code-testing/Pipfile.lock b/g-code-testing/Pipfile.lock index ad7aa98a701..fd068bff783 100644 --- a/g-code-testing/Pipfile.lock +++ b/g-code-testing/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2454d48b1b831db24fb96b42516e1ac204d98ea0ed929307858ee32ac793fb20" + "sha256": "214f2b205b35dd2d385ec40836249499ecebefc1696107a12d48c58b13c6353d" }, "pipfile-spec": 6, "requires": { @@ -23,14 +23,6 @@ ], "version": "==0.2.0" }, - "aiosqlite": { - "hashes": [ - "sha256:95ee77b91c8d2808bd08a59fbebf66270e9090c3d92ffbf260dc0db0b979577d", - "sha256:edba222e03453e094a3ce605db1b970c4b3376264e56f32e2a4959f948d66a96" - ], - "markers": "python_version >= '3.7'", - "version": "==0.19.0" - }, "anyio": { "hashes": [ "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", @@ -58,11 +50,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "fastapi": { "hashes": [ @@ -86,11 +78,11 @@ }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "jsonschema": { "hashes": [ @@ -102,49 +94,49 @@ }, "numpy": { "hashes": [ - "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd", - "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b", - "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e", - "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f", - "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f", - "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178", - "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3", - "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4", - "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e", - "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0", - "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00", - "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419", - "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4", - "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6", - "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166", - "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b", - "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3", - "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf", - "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2", - "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2", - "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36", - "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03", - "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce", - "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6", - "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13", - "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5", - "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e", - "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485", - "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137", - "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374", - "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58", - "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b", - "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb", - "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b", - "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda", - "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511" + "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", + "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", + "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", + "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", + "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", + "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", + "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", + "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", + "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", + "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", + "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", + "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", + "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", + "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", + "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", + "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", + "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", + "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", + "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", + "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", + "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", + "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", + "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", + "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", + "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", + "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", + "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", + "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", + "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", + "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", + "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", + "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", + "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", + "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", + "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", + "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" ], "markers": "python_version >= '3.9'", - "version": "==1.26.3" + "version": "==1.26.4" }, "opentrons": { "editable": true, - "markers": "python_version >= '3.7'", + "markers": "python_version >= '3.10'", "path": "./../api" }, "opentrons-hardware": { @@ -153,7 +145,7 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.7'", + "markers": "python_version >= '3.10'", "path": "../shared-data/python" }, "paho-mqtt": { @@ -276,11 +268,11 @@ }, "sniffio": { "hashes": [ - "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", - "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "sqlalchemy": { "hashes": [ @@ -351,11 +343,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.11.0" }, "uvicorn": { "hashes": [ @@ -377,85 +369,85 @@ "develop": { "aiohttp": { "hashes": [ - "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168", - "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb", - "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5", - "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f", - "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc", - "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c", - "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29", - "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4", - "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc", - "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc", - "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63", - "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e", - "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d", - "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a", - "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60", - "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38", - "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b", - "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2", - "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53", - "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5", - "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4", - "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96", - "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58", - "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa", - "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321", - "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae", - "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce", - "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8", - "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194", - "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c", - "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf", - "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d", - "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869", - "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b", - "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52", - "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528", - "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5", - "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1", - "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4", - "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8", - "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d", - "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7", - "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5", - "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54", - "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3", - "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5", - "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c", - "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29", - "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3", - "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747", - "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672", - "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5", - "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11", - "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca", - "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768", - "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6", - "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2", - "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533", - "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6", - "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266", - "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d", - "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec", - "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5", - "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1", - "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b", - "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679", - "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283", - "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb", - "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b", - "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3", - "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051", - "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511", - "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e", - "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d", - "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542", - "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f" + "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8", + "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c", + "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475", + "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed", + "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf", + "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372", + "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81", + "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f", + "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1", + "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd", + "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a", + "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb", + "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46", + "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de", + "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78", + "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c", + "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771", + "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb", + "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430", + "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233", + "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156", + "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9", + "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59", + "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888", + "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c", + "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c", + "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da", + "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424", + "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2", + "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb", + "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8", + "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a", + "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10", + "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0", + "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09", + "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031", + "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4", + "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3", + "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa", + "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a", + "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe", + "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a", + "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2", + "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1", + "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323", + "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b", + "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b", + "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106", + "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac", + "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6", + "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832", + "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75", + "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6", + "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d", + "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72", + "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db", + "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a", + "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da", + "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678", + "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b", + "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24", + "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed", + "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f", + "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e", + "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58", + "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a", + "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342", + "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558", + "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2", + "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551", + "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595", + "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee", + "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11", + "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d", + "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7", + "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f" ], "markers": "python_version >= '3.8'", - "version": "==3.9.3" + "version": "==3.9.5" }, "aiosignal": { "hashes": [ @@ -524,61 +516,61 @@ "toml" ], "hashes": [ - "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", - "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", - "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7", - "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7", - "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75", - "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd", - "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35", - "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04", - "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6", - "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042", - "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166", - "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1", - "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d", - "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c", - "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66", - "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70", - "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1", - "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676", - "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630", - "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a", - "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74", - "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad", - "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19", - "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6", - "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448", - "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018", - "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218", - "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756", - "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54", - "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45", - "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628", - "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968", - "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d", - "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25", - "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60", - "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950", - "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06", - "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295", - "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b", - "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c", - "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc", - "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74", - "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1", - "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee", - "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011", - "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156", - "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766", - "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5", - "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581", - "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016", - "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c", - "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3" + "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de", + "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661", + "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26", + "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41", + "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d", + "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981", + "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2", + "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34", + "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f", + "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a", + "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35", + "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223", + "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1", + "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746", + "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90", + "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c", + "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca", + "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8", + "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596", + "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e", + "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd", + "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e", + "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3", + "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e", + "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312", + "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7", + "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572", + "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428", + "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f", + "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07", + "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e", + "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4", + "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136", + "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5", + "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8", + "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d", + "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228", + "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206", + "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa", + "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e", + "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be", + "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5", + "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668", + "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601", + "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057", + "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146", + "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f", + "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8", + "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7", + "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987", + "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19", + "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece" ], "markers": "python_version >= '3.8'", - "version": "==7.4.1" + "version": "==7.5.1" }, "decoy": { "hashes": [ @@ -600,19 +592,19 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "execnet": { "hashes": [ - "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41", - "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af" + "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", + "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3" ], - "markers": "python_version >= '3.7'", - "version": "==2.0.2" + "markers": "python_version >= '3.8'", + "version": "==2.1.1" }, "flake8": { "hashes": [ @@ -735,11 +727,11 @@ }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "iniconfig": { "hashes": [ @@ -906,11 +898,11 @@ }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pathspec": { "hashes": [ @@ -922,19 +914,19 @@ }, "platformdirs": { "hashes": [ - "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", - "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" ], "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.2.2" }, "pluggy": { "hashes": [ - "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", - "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.4.0" + "version": "==1.5.0" }, "py": { "hashes": [ @@ -988,11 +980,11 @@ }, "pytest-asyncio": { "hashes": [ - "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", - "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" + "sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a", + "sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f" ], "markers": "python_version >= '3.8'", - "version": "==0.23.4" + "version": "==0.23.6" }, "pytest-cov": { "hashes": [ @@ -1020,6 +1012,15 @@ "markers": "python_version >= '3.6'", "version": "==2.5.0" }, + "pyusb": { + "hashes": [ + "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", + "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9" + ], + "index": "pypi", + "markers": "python_full_version >= '3.6.0'", + "version": "==1.2.1" + }, "snowballstemmer": { "hashes": [ "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", @@ -1037,20 +1038,20 @@ }, "types-mock": { "hashes": [ - "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", - "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" + "sha256:5281a645d72e827d70043e3cc144fe33b1c003db084f789dc203aa90e812a5a4", + "sha256:d586a01d39ad919d3ddcd73de6cde73ca7f3c69707219f722d1b8d7733641ad7" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0.20240106" + "version": "==5.1.0.20240425" }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.11.0" }, "yarl": { "hashes": [ diff --git a/hardware-testing/Pipfile b/hardware-testing/Pipfile index acc317ac325..e851331de96 100644 --- a/hardware-testing/Pipfile +++ b/hardware-testing/Pipfile @@ -23,6 +23,7 @@ flake8-docstrings = "~=1.6.0" flake8-noqa = "~=1.2.1" requests = "==2.27.1" types-requests = "==2.25.6" +pyusb = "==1.2.1" [requires] python_version = "3.10" diff --git a/hardware-testing/Pipfile.lock b/hardware-testing/Pipfile.lock index 6c717bc2743..cbe473a96c3 100644 --- a/hardware-testing/Pipfile.lock +++ b/hardware-testing/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "62d9d88f58594147f78dbda65db2d96b53ac2c07a54eb0b81854c7c7ebe4e247" + "sha256": "29fd7580a2384b6f20317de4c4869f27ede50315e7d87d75346bfbabd0ef683c" }, "pipfile-spec": 6, "requires": { @@ -25,19 +25,19 @@ }, "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" + "markers": "python_version >= '3.7'", + "version": "==3.7.1" }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "click": { "hashes": [ @@ -47,134 +47,144 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "exceptiongroup": { + "hashes": [ + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.1" + }, "hardware-testing": { "editable": true, "path": "." }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" ], - "version": "==3.0.2" + "markers": "python_version >= '3.7'", + "version": "==4.17.3" }, "msgpack": { "hashes": [ - "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862", - "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d", - "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3", - "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672", - "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0", - "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9", - "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee", - "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46", - "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524", - "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819", - "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc", - "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc", - "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1", - "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82", - "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81", - "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6", - "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d", - "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2", - "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c", - "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87", - "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84", - "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e", - "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95", - "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f", - "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b", - "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93", - "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf", - "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61", - "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c", - "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8", - "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d", - "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c", - "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4", - "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba", - "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415", - "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee", - "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d", - "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9", - "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075", - "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f", - "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7", - "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681", - "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329", - "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1", - "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf", - "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c", - "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5", - "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b", - "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5", - "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e", - "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b", - "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad", - "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd", - "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7", - "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002", - "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc" + "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982", + "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3", + "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40", + "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee", + "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693", + "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950", + "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151", + "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24", + "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305", + "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b", + "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c", + "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659", + "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d", + "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18", + "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746", + "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868", + "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2", + "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba", + "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228", + "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2", + "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273", + "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c", + "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653", + "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a", + "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596", + "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd", + "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8", + "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa", + "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85", + "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc", + "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836", + "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3", + "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58", + "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128", + "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db", + "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f", + "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77", + "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad", + "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13", + "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8", + "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b", + "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a", + "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543", + "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b", + "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce", + "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d", + "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a", + "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c", + "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f", + "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e", + "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011", + "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04", + "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480", + "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a", + "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d", + "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d" ], "markers": "platform_system != 'Windows'", - "version": "==1.0.7" + "version": "==1.0.8" }, "numpy": { "hashes": [ - "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a", - "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6", - "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2", - "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79", - "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9", - "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919", - "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d", - "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060", - "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75", - "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f", - "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe", - "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167", - "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef", - "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75", - "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3", - "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7", - "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7", - "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d", - "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b", - "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186", - "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0", - "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1", - "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6", - "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e", - "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523", - "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36", - "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841", - "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818", - "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00", - "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80", - "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440", - "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210", - "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8", - "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea", - "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec", - "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841" + "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", + "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", + "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", + "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", + "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", + "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", + "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", + "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", + "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", + "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", + "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", + "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", + "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", + "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", + "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", + "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", + "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", + "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", + "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", + "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", + "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", + "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", + "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", + "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", + "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", + "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", + "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", + "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", + "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", + "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", + "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", + "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", + "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", + "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", + "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", + "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" ], "markers": "python_version >= '3.9'", - "version": "==1.26.2" + "version": "==1.26.4" }, "opentrons": { "editable": true, "extras": [ "flex-hardware" ], + "markers": "python_version >= '3.10'", "path": "./../api" }, "opentrons-hardware": { @@ -186,57 +196,58 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.7'", + "markers": "python_version >= '3.10'", "path": "./../shared-data/python" }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "sha256:005655cabc29081de8243126e036f2065bd7ea5b9dff95fde6d2c642d39755de", + "sha256:0d142fa1b8f2f0ae11ddd5e3e317dcac060b951d605fda26ca9b234b92214986", + "sha256:22ed12ee588b1df028a2aa5d66f07bf8f8b4c8579c2e96d5a9c1f96b77f3bb55", + "sha256:2746189100c646682eff0bce95efa7d2e203420d8e1c613dc0c6b4c1d9c1fde4", + "sha256:28e552a060ba2740d0d2aabe35162652c1459a0b9069fe0db7f4ee0e18e74d58", + "sha256:3287e1614393119c67bd4404f46e33ae3be3ed4cd10360b48d0a4459f420c6a3", + "sha256:3350f527bb04138f8aff932dc828f154847fbdc7a1a44c240fbfff1b57f49a12", + "sha256:3453685ccd7140715e05f2193d64030101eaad26076fad4e246c1cc97e1bb30d", + "sha256:394f08750bd8eaad714718812e7fab615f873b3cdd0b9d84e76e51ef3b50b6b7", + "sha256:4e316e54b5775d1eb59187f9290aeb38acf620e10f7fd2f776d97bb788199e53", + "sha256:50f1666a9940d3d68683c9d96e39640f709d7a72ff8702987dab1761036206bb", + "sha256:51d405b42f1b86703555797270e4970a9f9bd7953f3990142e69d1037f9d9e51", + "sha256:584f2d4c98ffec420e02305cf675857bae03c9d617fcfdc34946b1160213a948", + "sha256:5e09c19df304b8123938dc3c53d3d3be6ec74b9d7d0d80f4f4b5432ae16c2022", + "sha256:676ed48f2c5bbad835f1a8ed8a6d44c1cd5a21121116d2ac40bd1cd3619746ed", + "sha256:67f1a1fb467d3f49e1708a3f632b11c69fccb4e748a325d5a491ddc7b5d22383", + "sha256:6a51a1dd4aa7b3f1317f65493a182d3cff708385327c1c82c81e4a9d6d65b2e4", + "sha256:6bd7030c9abc80134087d8b6e7aa957e43d35714daa116aced57269a445b8f7b", + "sha256:75279d3cac98186b6ebc2597b06bcbc7244744f6b0b44a23e4ef01e5683cc0d2", + "sha256:7ac9237cd62947db00a0d16acf2f3e00d1ae9d3bd602b9c415f93e7a9fc10528", + "sha256:7ea210336b891f5ea334f8fc9f8f862b87acd5d4a0cbc9e3e208e7aa1775dabf", + "sha256:82790d4753ee5d00739d6cb5cf56bceb186d9d6ce134aca3ba7befb1eedbc2c8", + "sha256:92229f73400b80c13afcd050687f4d7e88de9234d74b27e6728aa689abcf58cc", + "sha256:9bea1f03b8d4e8e86702c918ccfd5d947ac268f0f0cc6ed71782e4b09353b26f", + "sha256:a980a77c52723b0dc56640ced396b73a024d4b74f02bcb2d21dbbac1debbe9d0", + "sha256:af9850d98fc21e5bc24ea9e35dd80a29faf6462c608728a110c0a30b595e58b7", + "sha256:bbc6989fad0c030bd70a0b6f626f98a862224bc2b1e36bfc531ea2facc0a340c", + "sha256:be51dd2c8596b25fe43c0a4a59c2bee4f18d88efb8031188f9e7ddc6b469cf44", + "sha256:c365ad9c394f9eeffcb30a82f4246c0006417f03a7c0f8315d6211f25f7cb654", + "sha256:c3d5731a120752248844676bf92f25a12f6e45425e63ce22e0849297a093b5b0", + "sha256:ca832e124eda231a60a041da4f013e3ff24949d94a01154b137fc2f2a43c3ffb", + "sha256:d207d5b87f6cbefbdb1198154292faee8017d7495a54ae58db06762004500d00", + "sha256:d31ee5b14a82c9afe2bd26aaa405293d4237d0591527d9129ce36e58f19f95c1", + "sha256:d3b5c4cbd0c9cb61bbbb19ce335e1f8ab87a811f6d589ed52b0254cf585d709c", + "sha256:d573082c6ef99336f2cb5b667b781d2f776d4af311574fb53d908517ba523c22", + "sha256:e49db944fad339b2ccb80128ffd3f8af076f9f287197a480bf1e4ca053a866f0" + ], + "markers": "python_version >= '3.7'", + "version": "==1.10.15" }, "pyrsistent": { "hashes": [ @@ -293,35 +304,27 @@ }, "setuptools": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987", + "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "version": "==69.5.1" }, "sniffio": { "hashes": [ - "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", - "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.11.0" }, "wrapt": { "hashes": [ @@ -410,11 +413,11 @@ }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "black": { "hashes": [ @@ -448,11 +451,11 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -481,61 +484,61 @@ }, "coverage": { "hashes": [ - "sha256:007a7e49831cfe387473e92e9ff07377f6121120669ddc39674e7244350a6a29", - "sha256:1191270b06ecd68b1d00897b2daddb98e1719f63750969614ceb3438228c088e", - "sha256:1367aa411afb4431ab58fd7ee102adb2665894d047c490649e86219327183134", - "sha256:1f0f8f0c497eb9c9f18f21de0750c8d8b4b9c7000b43996a094290b59d0e7523", - "sha256:222b038f08a7ebed1e4e78ccf3c09a1ca4ac3da16de983e66520973443b546bc", - "sha256:243576944f7c1a1205e5cd658533a50eba662c74f9be4c050d51c69bd4532936", - "sha256:2e9223a18f51d00d3ce239c39fc41410489ec7a248a84fab443fbb39c943616c", - "sha256:307aecb65bb77cbfebf2eb6e12009e9034d050c6c69d8a5f3f737b329f4f15fb", - "sha256:31c0b1b8b5a4aebf8fcd227237fc4263aa7fa0ddcd4d288d42f50eff18b0bac4", - "sha256:3b15e03b8ee6a908db48eccf4e4e42397f146ab1e91c6324da44197a45cb9132", - "sha256:3c854c1d2c7d3e47f7120b560d1a30c1ca221e207439608d27bc4d08fd4aeae8", - "sha256:475de8213ed95a6b6283056d180b2442eee38d5948d735cd3d3b52b86dd65b92", - "sha256:50c472c1916540f8b2deef10cdc736cd2b3d1464d3945e4da0333862270dcb15", - "sha256:593efa42160c15c59ee9b66c5f27a453ed3968718e6e58431cdfb2d50d5ad284", - "sha256:65d716b736f16e250435473c5ca01285d73c29f20097decdbb12571d5dfb2c94", - "sha256:733537a182b5d62184f2a72796eb6901299898231a8e4f84c858c68684b25a70", - "sha256:757453848c18d7ab5d5b5f1827293d580f156f1c2c8cef45bfc21f37d8681069", - "sha256:79c32f875fd7c0ed8d642b221cf81feba98183d2ff14d1f37a1bbce6b0347d9f", - "sha256:7f3bad1a9313401ff2964e411ab7d57fb700a2d5478b727e13f156c8f89774a0", - "sha256:7fbf3f5756e7955174a31fb579307d69ffca91ad163467ed123858ce0f3fd4aa", - "sha256:811ca7373da32f1ccee2927dc27dc523462fd30674a80102f86c6753d6681bc6", - "sha256:89400aa1752e09f666cc48708eaa171eef0ebe3d5f74044b614729231763ae69", - "sha256:8c944cf1775235c0857829c275c777a2c3e33032e544bcef614036f337ac37bb", - "sha256:9437a4074b43c177c92c96d051957592afd85ba00d3e92002c8ef45ee75df438", - "sha256:9e17d9cb06c13b4f2ef570355fa45797d10f19ca71395910b249e3f77942a837", - "sha256:9ede881c7618f9cf93e2df0421ee127afdfd267d1b5d0c59bcea771cf160ea4a", - "sha256:a1f76cfc122c9e0f62dbe0460ec9cc7696fc9a0293931a33b8870f78cf83a327", - "sha256:a2ac4245f18057dfec3b0074c4eb366953bca6787f1ec397c004c78176a23d56", - "sha256:a702e66483b1fe602717020a0e90506e759c84a71dbc1616dd55d29d86a9b91f", - "sha256:ad2453b852a1316c8a103c9c970db8fbc262f4f6b930aa6c606df9b2766eee06", - "sha256:af75cf83c2d57717a8493ed2246d34b1f3398cb8a92b10fd7a1858cad8e78f59", - "sha256:afdcc10c01d0db217fc0a64f58c7edd635b8f27787fea0a3054b856a6dff8717", - "sha256:c59a3e59fb95e6d72e71dc915e6d7fa568863fad0a80b33bc7b82d6e9f844973", - "sha256:cad9afc1644b979211989ec3ff7d82110b2ed52995c2f7263e7841c846a75348", - "sha256:d299d379b676812e142fb57662a8d0d810b859421412b4d7af996154c00c31bb", - "sha256:d31650d313bd90d027f4be7663dfa2241079edd780b56ac416b56eebe0a21aab", - "sha256:d874434e0cb7b90f7af2b6e3309b0733cde8ec1476eb47db148ed7deeb2a9494", - "sha256:db0338c4b0951d93d547e0ff8d8ea340fecf5885f5b00b23be5aa99549e14cfd", - "sha256:df04c64e58df96b4427db8d0559e95e2df3138c9916c96f9f6a4dd220db2fdb7", - "sha256:e995efb191f04b01ced307dbd7407ebf6e6dc209b528d75583277b10fd1800ee", - "sha256:eda7f6e92358ac9e1717ce1f0377ed2b9320cea070906ece4e5c11d172a45a39", - "sha256:ee453085279df1bac0996bc97004771a4a052b1f1e23f6101213e3796ff3cb85", - "sha256:ee6621dccce8af666b8c4651f9f43467bfbf409607c604b840b78f4ff3619aeb", - "sha256:eee5e741b43ea1b49d98ab6e40f7e299e97715af2488d1c77a90de4a663a86e2", - "sha256:f3bfd2c2f0e5384276e12b14882bf2c7621f97c35320c3e7132c156ce18436a1", - "sha256:f501e36ac428c1b334c41e196ff6bd550c0353c7314716e80055b1f0a32ba394", - "sha256:f9191be7af41f0b54324ded600e8ddbcabea23e1e8ba419d9a53b241dece821d", - "sha256:fbd8a5fe6c893de21a3c6835071ec116d79334fbdf641743332e442a3466f7ea", - "sha256:fc200cec654311ca2c3f5ab3ce2220521b3d4732f68e1b1e79bef8fcfc1f2b97", - "sha256:ff4800783d85bff132f2cc7d007426ec698cdce08c3062c8d501ad3f4ea3d16c", - "sha256:ffb0eacbadb705c0a6969b0adf468f126b064f3362411df95f6d4f31c40d31c1", - "sha256:fff0b2f249ac642fd735f009b8363c2b46cf406d3caec00e4deeb79b5ff39b40" + "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de", + "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661", + "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26", + "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41", + "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d", + "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981", + "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2", + "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34", + "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f", + "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a", + "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35", + "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223", + "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1", + "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746", + "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90", + "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c", + "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca", + "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8", + "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596", + "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e", + "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd", + "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e", + "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3", + "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e", + "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312", + "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7", + "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572", + "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428", + "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f", + "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07", + "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e", + "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4", + "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136", + "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5", + "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8", + "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d", + "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228", + "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206", + "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa", + "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e", + "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be", + "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5", + "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668", + "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601", + "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057", + "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146", + "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f", + "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8", + "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7", + "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987", + "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19", + "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece" ], "markers": "python_version >= '3.8'", - "version": "==7.3.3" + "version": "==7.5.1" }, "flake8": { "hashes": [ @@ -574,11 +577,11 @@ }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "iniconfig": { "hashes": [ @@ -636,11 +639,11 @@ }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pathspec": { "hashes": [ @@ -652,19 +655,19 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.2" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.5.0" }, "py": { "hashes": [ @@ -716,6 +719,15 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.10.1" }, + "pyusb": { + "hashes": [ + "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", + "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9" + ], + "index": "pypi", + "markers": "python_full_version >= '3.6.0'", + "version": "==1.2.1" + }, "requests": { "hashes": [ "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", @@ -737,7 +749,7 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "types-requests": { @@ -750,11 +762,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.11.0" }, "urllib3": { "hashes": [ diff --git a/robot-server/Pipfile b/robot-server/Pipfile index 2d22c6dc34c..0b70739eac3 100755 --- a/robot-server/Pipfile +++ b/robot-server/Pipfile @@ -37,6 +37,7 @@ sqlalchemy2-stubs = "==0.0.2a21" python-box = "==6.1.0" types-paho-mqtt = "==1.6.0.20240106" performance-metrics = {file = "../performance-metrics", editable = true} +pyusb = "==1.2.1" [packages] anyio = "==3.7.1" diff --git a/robot-server/Pipfile.lock b/robot-server/Pipfile.lock index 2ea9f545696..af344b810f6 100644 --- a/robot-server/Pipfile.lock +++ b/robot-server/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9f64ba7d87b9c9fd510aac5c4a22fa748c1bb3b9936826ef2b4b13454c1c5e2b" + "sha256": "f43123500e774f5b9a92f2be8ae39a04af8df7ba2ae4b2a505f1bb4b751cc30a" }, "pipfile-spec": 6, "requires": { @@ -154,11 +154,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "fastapi": { "hashes": [ @@ -252,70 +252,6 @@ "markers": "python_version >= '3.8'", "version": "==1.4.1" }, - "greenlet": { - "hashes": [ - "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67", - "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6", - "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257", - "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4", - "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676", - "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61", - "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc", - "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca", - "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7", - "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728", - "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305", - "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6", - "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379", - "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414", - "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04", - "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a", - "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf", - "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491", - "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559", - "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e", - "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274", - "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb", - "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b", - "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9", - "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b", - "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be", - "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506", - "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405", - "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113", - "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f", - "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5", - "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230", - "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d", - "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f", - "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a", - "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e", - "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61", - "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6", - "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d", - "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71", - "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22", - "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2", - "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3", - "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067", - "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc", - "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881", - "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3", - "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e", - "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac", - "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53", - "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0", - "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b", - "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83", - "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41", - "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c", - "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf", - "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da", - "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==3.0.3" - }, "h11": { "hashes": [ "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", @@ -528,7 +464,7 @@ }, "opentrons": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "../api" }, "opentrons-hardware": { @@ -540,7 +476,7 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "../shared-data/python" }, "packaging": { @@ -1066,61 +1002,61 @@ "toml" ], "hashes": [ - "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c", - "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63", - "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7", - "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f", - "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8", - "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf", - "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0", - "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384", - "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76", - "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7", - "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d", - "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70", - "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f", - "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818", - "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b", - "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d", - "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec", - "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083", - "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2", - "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9", - "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd", - "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade", - "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e", - "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a", - "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227", - "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87", - "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c", - "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e", - "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c", - "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e", - "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd", - "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec", - "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562", - "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8", - "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677", - "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357", - "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c", - "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd", - "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49", - "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286", - "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1", - "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf", - "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51", - "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409", - "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384", - "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e", - "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978", - "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57", - "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e", - "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2", - "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48", - "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4" + "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de", + "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661", + "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26", + "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41", + "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d", + "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981", + "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2", + "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34", + "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f", + "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a", + "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35", + "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223", + "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1", + "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746", + "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90", + "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c", + "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca", + "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8", + "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596", + "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e", + "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd", + "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e", + "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3", + "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e", + "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312", + "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7", + "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572", + "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428", + "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f", + "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07", + "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e", + "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4", + "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136", + "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5", + "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8", + "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d", + "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228", + "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206", + "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa", + "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e", + "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be", + "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5", + "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668", + "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601", + "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057", + "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146", + "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f", + "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8", + "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7", + "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987", + "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19", + "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece" ], "markers": "python_version >= '3.8'", - "version": "==7.4.4" + "version": "==7.5.1" }, "decoy": { "hashes": [ @@ -1139,11 +1075,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", + "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16" ], "markers": "python_version < '3.11'", - "version": "==1.2.0" + "version": "==1.2.1" }, "execnet": { "hashes": [ @@ -1317,7 +1253,7 @@ }, "opentrons-shared-data": { "editable": true, - "markers": "python_version >= '3.8'", + "markers": "python_version >= '3.10'", "path": "../shared-data/python" }, "packaging": { @@ -1356,19 +1292,19 @@ }, "platformdirs": { "hashes": [ - "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", - "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" ], "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.2.2" }, "pluggy": { "hashes": [ - "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", - "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.4.0" + "version": "==1.5.0" }, "py": { "hashes": [ @@ -1582,6 +1518,15 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.0.post0" }, + "pyusb": { + "hashes": [ + "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", + "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9" + ], + "index": "pypi", + "markers": "python_full_version >= '3.6.0'", + "version": "==1.2.1" + }, "pyyaml": { "hashes": [ "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", @@ -1771,12 +1716,12 @@ }, "types-mock": { "hashes": [ - "sha256:0769cb376dfc75b45215619f17a9fd6333d771cc29ce4a38937f060b1e45530f", - "sha256:7472797986d83016f96fde7f73577d129b0cd8a8d0b783487a7be330d57ba431" + "sha256:5281a645d72e827d70043e3cc144fe33b1c003db084f789dc203aa90e812a5a4", + "sha256:d586a01d39ad919d3ddcd73de6cde73ca7f3c69707219f722d1b8d7733641ad7" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0.20240311" + "version": "==5.1.0.20240425" }, "types-paho-mqtt": { "hashes": [ diff --git a/shared-data/module/definitions/3/absorbanceReaderV1.json b/shared-data/module/definitions/3/absorbanceReaderV1.json new file mode 100644 index 00000000000..7b3172c377d --- /dev/null +++ b/shared-data/module/definitions/3/absorbanceReaderV1.json @@ -0,0 +1,3686 @@ +{ + "$otSharedSchema": "module/schemas/3", + "moduleType": "absorbanceReaderType", + "model": "absorbanceReaderV1", + "labwareOffset": { + "x": 0.0, + "y": 0.0, + "z": 108.96 + }, + "dimensions": { + "bareOverallHeight": 108.96, + "overLabwareHeight": 0.0, + "lidHeight": 61.7, + "xDimension": 172, + "yDimension": 245.2, + "labwareInterfaceXDimension": 128, + "labwareInterfaceYDimension": 86 + }, + "cornerOffsetFromSlot": { + "x": -22.125, + "y": 0, + "z": 0 + }, + "calibrationPoint": { + "x": 14.4, + "y": 64.93, + "z": 97.8 + }, + "config": { + "minBlockTemperature": 0, + "maxBlockTemperature": 99, + "minLidTemperature": 37, + "maxLidTemperature": 110, + "minBlockVolume": 0, + "maxBlockVolume": 100 + }, + "gripperOffsets": { + "default": { + "pickUpOffset": { + "x": 0, + "y": 0, + "z": 4.6 + }, + "dropOffset": { + "x": 0, + "y": 0, + "z": 5.6 + } + } + }, + "displayName": "Thermocycler Module GEN2", + "quirks": [], + "slotTransforms": { + "ot3_standard": { + "B1": { + "labwareOffset": [ + [1, 0, 0, -20.005], + [0, 1, 0, -0.84], + [0, 0, 1, -98], + [0, 0, 0, 1] + ], + "cornerOffsetFromSlot": [ + [1, 0, 0, -20.005], + [0, 1, 0, -0.84], + [0, 0, 1, -98], + [0, 0, 0, 1] + ] + } + } + }, + "compatibleWith": [], + "twoDimensionalRendering": { + "name": "svg", + "type": "element", + "value": "", + "attributes": { + "version": "1.1", + "id": "thermocycler", + "xmlns": "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + "x": "0px", + "y": "0px", + "viewBox": "0 0 172 258", + "style": "enable-background:new 0 0 172 258;", + "xml:space": "preserve" + }, + "children": [ + { + "name": "style", + "type": "element", + "value": "", + "attributes": { + "type": "text/css" + }, + "children": [ + { + "name": "", + "type": "text", + "value": "\n.st0{fill:#FFFFFF;}\n.st1{fill:#E6E6E6;}\n", + "attributes": {}, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "closed" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M145.2,232.7V186c0-4-2.7-7.2-6-7.2H32.5c-3.3,0-5.7,3.2-5.7,7.2v46.7H0.4V0.4h171.2v232.3H145.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st1", + "d": "M139.1,178.8h-106c-3.3,0-6,2.7-6,6v47.9h118v-47.9C145.1,181.5,142.4,178.8,139.1,178.8z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "rect", + "type": "element", + "value": "", + "attributes": { + "x": "4.2", + "y": "0.4", + "class": "st1", + "width": "163.4", + "height": "38.3" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M141,191.8H31.1c-1.1,0-2,0.9-2,2v49.2c0,1.1,0.9,2,2,2H141c1.1,0,2-0.9,2-2v-49.2\n C143,192.7,142.1,191.8,141,191.8z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "rect", + "type": "element", + "value": "", + "attributes": { + "x": "32.7", + "y": "195.4", + "class": "st1", + "width": "106.8", + "height": "49.5" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M130.8,18.5H41.2c-1.6,0-3,1.3-3,3l0,0c0,1.7,1.3,3,3,3h89.6c1.6,0,3-1.3,3-3l0,0\n C133.8,19.9,132.5,18.5,130.8,18.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M130.8,18.3H41.2c-1.7,0-3.2,1.4-3.2,3.2c0,1.7,1.4,3.2,3.2,3.2h89.6c1.7,0,3.2-1.4,3.2-3.2\n C133.9,19.8,132.5,18.3,130.8,18.3z M41.2,24.3c-1.5,0-2.8-1.3-2.8-2.8c0-1.6,1.3-2.8,2.8-2.8h89.6c1.5,0,2.8,1.3,2.8,2.8\n c0,1.6-1.3,2.8-2.8,2.8H41.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M4.4,0.2c-0.1,0-0.2,0.1-0.2,0.2v232.3c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2V0.4C4.6,0.3,4.5,0.2,4.4,0.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M171.6,38.3H0.4c-0.2,0-0.4,0.2-0.4,0.4S0.2,39,0.4,39h171.2c0.2,0,0.4-0.2,0.4-0.4S171.8,38.3,171.6,38.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M167.6,0.2c-0.1,0-0.2,0.1-0.2,0.2v232.4c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2V0.4\n C167.8,0.3,167.7,0.2,167.6,0.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M139.5,242.3c-0.1,0-0.1,0.1-0.1,0.1v2.5c0,0.1,0.1,0.1,0.1,0.1s0.1-0.1,0.1-0.1v-2.5\n C139.6,242.4,139.5,242.3,139.5,242.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M139.1,195.1H139c-0.1,0-0.1,0.1-0.1,0.1s0.1,0.1,0.1,0.1h0.1l0.2,0.1l0.1,0.1l0,0.1c0,0.1,0.1,0.1,0.1,0.1\n s0.1-0.1,0.1-0.1v-0.1c0,0,0,0,0,0l-0.1-0.2l-0.1-0.1c0,0,0,0,0,0L139.1,195.1C139.1,195.1,139.1,195.1,139.1,195.1z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M33.1,195.1H33c0,0,0,0,0,0l-0.1,0c0,0,0,0,0,0l-0.1,0.1l-0.1,0c0,0,0,0,0,0l-0.1,0.2l0,0.1c0,0,0,0,0,0v0.1\n c0,0.1,0.1,0.1,0.1,0.1c0.1,0,0.1-0.1,0.1-0.1v0l0.1-0.1l0-0.1l0,0c0,0,0,0,0,0l0,0l0.1,0h0.1c0.1,0,0.1-0.1,0.1-0.1\n C33.2,195.2,33.1,195.1,33.1,195.1z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M32.6,242.3c-0.1,0-0.1,0.1-0.1,0.1v2.5c0,0.1,0.1,0.1,0.1,0.1c0.1,0,0.1-0.1,0.1-0.1v-2.5\n C32.7,242.4,32.6,242.3,32.6,242.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M0.4,0C0.2,0,0.1,0.2,0.1,0.4v232.3c0,0.2,0.2,0.4,0.4,0.4h28.7c0.2,0,0.4-0.2,0.4-0.4c0-0.2-0.2-0.4-0.4-0.4H0.8V0.7\n h170.5v231.7H143c-0.2,0-0.4,0.2-0.4,0.4s0.2,0.4,0.4,0.4h28.7c0.2,0,0.4-0.2,0.4-0.4V0.4c0-0.2-0.2-0.4-0.4-0.4H0.5\n C0.5,0,0.4,0,0.4,0z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M171.6,4.2H0.4c-0.1,0-0.2,0.1-0.2,0.2c0,0.1,0.1,0.2,0.2,0.2h171.2c0.1,0,0.2-0.1,0.2-0.2\n C171.8,4.3,171.7,4.2,171.6,4.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M150.6,12.4c-5,0-9.1,4.1-9.1,9.1s4.1,9.1,9.1,9.1s9.1-4.1,9.1-9.1S155.6,12.4,150.6,12.4z M150.6,30.2\n c-4.8,0-8.7-3.9-8.7-8.7s3.9-8.7,8.7-8.7s8.7,3.9,8.7,8.7S155.4,30.2,150.6,30.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "ellipse", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "cx": "150.6", + "cy": "21.5", + "rx": "5.8", + "ry": "5.8" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M150.6,15.5c-3.3,0-6,2.7-6,6s2.7,6,6,6s6-2.7,6-6S153.9,15.5,150.6,15.5z M150.6,27.2c-3.1,0-5.7-2.5-5.7-5.7\n s2.5-5.7,5.7-5.7s5.7,2.5,5.7,5.7S153.7,27.2,150.6,27.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "ellipse", + "type": "element", + "value": "", + "attributes": { + "class": "st1", + "cx": "150.6", + "cy": "21.5", + "rx": "3.8", + "ry": "3.8" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M150.6,17.6c-2.2,0-3.9,1.8-3.9,4s1.8,4,3.9,4c2.2,0,3.9-1.8,3.9-4C154.5,19.3,152.8,17.6,150.6,17.6z M150.6,25.1\n c-2,0-3.6-1.6-3.6-3.6s1.6-3.6,3.6-3.6s3.6,1.6,3.6,3.6S152.6,25.1,150.6,25.1z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M141,191.4H31.1c-1.3,0-2.3,1.1-2.3,2.3v51.2c0,0.2,0.2,0.4,0.4,0.4H143c0.2,0,0.4-0.2,0.4-0.4v-51.2\n C143.3,192.5,142.3,191.4,141,191.4z M29.5,244.6v-50.8c0-0.9,0.7-1.6,1.6-1.6H141c0.9,0,1.6,0.7,1.6,1.6v50.8H29.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M139,195.1H33.1c-0.4,0-0.7,0.3-0.7,0.7v49.2c0,0.1,0.1,0.2,0.2,0.2h106.9c0.1,0,0.2-0.1,0.2-0.2v-49.2\n C139.7,195.4,139.4,195.1,139,195.1z M32.8,244.8v-49c0-0.2,0.1-0.3,0.3-0.3H139c0.2,0,0.3,0.1,0.3,0.3v49H32.8z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M139.1,178.4H32.7c-3.5,0-6.3,2.8-6.3,6.3V233h0.7v-48.2c0-3.1,2.5-5.6,5.6-5.6h106.4c3.1,0,5.6,2.5,5.6,5.6v47.7h0.7\n v-47.7C145.4,181.3,142.6,178.4,139.1,178.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M51.7,79.2c-0.1,0-0.1,0.1-0.1,0.1v99.4c0,0.1,0.1,0.1,0.1,0.1c0.1,0,0.1-0.1,0.1-0.1V79.3\n C51.8,79.2,51.8,79.2,51.7,79.2z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M120.4,79.1c-0.1,0-0.2,0.1-0.2,0.2v99.4c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2V79.3\n C120.6,79.2,120.5,79.1,120.4,79.1z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M120.4,79.1H51.6c-0.1,0-0.2,0.1-0.2,0.2c0,0.1,0.1,0.2,0.2,0.2h68.7c0.1,0,0.2-0.1,0.2-0.2\n C120.6,79.2,120.5,79.1,120.4,79.1z" + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "open" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "shading_00000140696093821789790550000002253882697550769834_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M51.7,247.3c0,2.4,0,9.8,0,11.1c0,1.4,0,2.8,1.1,3.9c1.2,1.2,2.6,1.2,4.1,1.2c1.6,0,58,0,59.1,0\n c1.3,0,2.5-0.3,3.3-1.3c1.3-1.4,1-3.3,1-5c0-1.8,0-8.4,0-9.9" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "rect", + "type": "element", + "value": "", + "attributes": { + "x": "55.6", + "y": "246.9", + "class": "st1", + "width": "60.7", + "height": "12.7" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M171.6,38.7H0.4v206.3c0,1.1,0.9,2,2,2h167.3c1.1,0,2-0.9,2-2L171.6,38.7L171.6,38.7z" + }, + "children": [] + }, + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M171.6,38.3H0.4c-0.2,0-0.4,0.2-0.4,0.4v206.3c0,1.3,1.1,2.3,2.3,2.3h167.3c1.3,0,2.3-1.1,2.3-2.3V38.7\n C172,38.5,171.8,38.3,171.6,38.3z M0.7,39h170.6v205.9c0,0.9-0.7,1.6-1.6,1.6H2.3c-0.9,0-1.6-0.7-1.6-1.6\n C0.7,244.9,0.7,39,0.7,39z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "base_grey_00000027585544793631977930000012329166542688174233_" + }, + "children": [ + { + "name": "rect", + "type": "element", + "value": "", + "attributes": { + "x": "4.4", + "y": "39.1", + "class": "st1", + "width": "163.4", + "height": "203.4" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M19.3,70.9v-4.4c0-1.2,1-2.2,2.2-2.2h129c1.2,0,2.2,1,2.2,2.2v4.4h-5.9c-0.6,0-1,0.4-1,1v2.5\n c0,0.6,0.4,1,1,1h5.9v65.3h-5.9c-0.6,0-1,0.4-1,1v2.5c0,0.6,0.4,1,1,1h5.9V156c0,1.2-1,2.2-2.2,2.2h-129l0,0\n c-1.2,0-2.2-1-2.2-2.2v0v-10.8h5.9c0.6,0,1-0.4,1-1v-2.5c0-0.6-0.4-1-1-1h-5.9V75.4h5.9c0.6,0,1-0.4,1-1v-2.5c0-0.6-0.4-1-1-1\n L19.3,70.9" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "class": "st0", + "d": "M143,203v-9.2c0-1.1-0.9-2-2-2H31.1c-1.1,0-2,0.9-2,2v9.2" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "polyline", + "type": "element", + "value": "", + "attributes": { + "class": "st1", + "points": "139.5,203.1 139.5,195.4 32.8,195.4 32.8,203.3 \t\t\t" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "stroke" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M116.5,246.7h-0.4v12.7H55.8v-12.7h-0.4v12.9c0,0.1,0.1,0.2,0.2,0.2h60.7c0.1,0,0.2-0.1,0.2-0.2V246.7z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M120.4,246.6c-0.2,0-0.4,0.2-0.4,0.4v10.2c0,0.3,0,0.5,0,0.8c0,1.5,0.1,3-0.9,4.2c-0.7,0.8-1.7,1.2-3.1,1.2H56.9\n c-1.4,0-2.8,0-3.8-1.1c-1-1.1-1-2.5-1-3.8v-11.4c0-0.2-0.2-0.4-0.4-0.4s-0.4,0.2-0.4,0.4v11.4c0,1.4,0,3,1.2,4.3\n c1.3,1.3,2.8,1.3,4.4,1.3H116c1.5,0,2.7-0.5,3.6-1.5c1.2-1.3,1.1-3.1,1.1-4.6c0-0.3,0-0.5,0-0.8v-10.2\n C120.7,246.7,120.6,246.6,120.4,246.6z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000072973290214693693960000017318416397027368577_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,139.7,45.7,139.7z M45.7,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S47.2,145.3,45.7,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,139.7,54.7,139.7z M54.7,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S56.1,145.3,54.7,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,139.7,63.6,139.7z M63.6,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S65.1,145.3,63.6,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,139.7,72.6,139.7z M72.6,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S74,145.3,72.6,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,139.7,81.6,139.7z M81.6,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S83,145.3,81.6,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,139.7,90.5,139.7z M90.5,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S91.9,145.3,90.5,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,139.7,99.5,139.7z M99.5,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S100.9,145.3,99.5,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,139.7,108.4,139.7z M108.4,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S109.9,145.3,108.4,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,139.7,117.4,139.7z M117.4,145.3\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S118.8,145.3,117.4,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,139.7,126.3,139.7z M126.3,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S127.8,145.3,126.3,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,139.7,135.3,139.7z M135.3,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S136.8,145.3,135.3,145.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,139.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,139.7,36.7,139.7z M36.7,145.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S38.2,145.3,36.7,145.3z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000153665527845359773540000012752985171215028372_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,130.7,45.7,130.7z M45.7,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S47.2,136.3,45.7,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,130.7,54.7,130.7z M54.7,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S56.1,136.3,54.7,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,130.7,63.6,130.7z M63.6,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S65.1,136.3,63.6,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,130.7,72.6,130.7z M72.6,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S74,136.3,72.6,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,130.7,81.6,130.7z M81.6,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S83,136.3,81.6,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,130.7,90.5,130.7z M90.5,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S91.9,136.3,90.5,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,130.7,99.5,130.7z M99.5,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S100.9,136.3,99.5,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,130.7,108.4,130.7z M108.4,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S109.9,136.3,108.4,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,130.7,117.4,130.7z M117.4,136.3\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S118.8,136.3,117.4,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,130.7,126.3,130.7z M126.3,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S127.8,136.3,126.3,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,130.7,135.3,130.7z M135.3,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S136.8,136.3,135.3,136.3z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,130.7c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,130.7,36.7,130.7z M36.7,136.3c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S38.2,136.3,36.7,136.3z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000001654953178113305770000001548480951139594390_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C48.7,123.1,47.3,121.8,45.7,121.8z M45.7,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S47.2,127.4,45.7,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C57.7,123.1,56.3,121.8,54.7,121.8z M54.7,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S56.1,127.4,54.7,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C66.6,123.1,65.3,121.8,63.6,121.8z M63.6,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S65.1,127.4,63.6,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C75.6,123.1,74.2,121.8,72.6,121.8z M72.6,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S74,127.4,72.6,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C84.5,123.1,83.2,121.8,81.6,121.8z M81.6,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S83,127.4,81.6,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C93.5,123.1,92.1,121.8,90.5,121.8z M90.5,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S91.9,127.4,90.5,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C102.4,123.1,101.1,121.8,99.5,121.8z M99.5,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S100.9,127.4,99.5,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C111.4,123.1,110.1,121.8,108.4,121.8z M108.4,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S109.9,127.4,108.4,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C120.3,123.1,119,121.8,117.4,121.8z M117.4,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S118.8,127.4,117.4,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C129.3,123.1,128,121.8,126.3,121.8z M126.3,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S127.8,127.4,126.3,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C138.3,123.1,137,121.8,135.3,121.8z M135.3,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S136.8,127.4,135.3,127.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,121.8c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C39.7,123.1,38.4,121.8,36.7,121.8z M36.7,127.4\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S38.2,127.4,36.7,127.4z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000142157505160117839040000001831267897535693211_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,112.8,45.7,112.8z M45.7,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C48.3,117.2,47.2,118.4,45.7,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,112.8,54.7,112.8z M54.7,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C57.3,117.2,56.1,118.4,54.7,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,112.8,63.6,112.8z M63.6,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C66.3,117.2,65.1,118.4,63.6,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,112.8,72.6,112.8z M72.6,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C75.2,117.2,74,118.4,72.6,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,112.8,81.6,112.8z M81.6,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C84.2,117.2,83,118.4,81.6,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,112.8,90.5,112.8z M90.5,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C93.1,117.2,91.9,118.4,90.5,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,112.8,99.5,112.8z M99.5,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C102.1,117.2,100.9,118.4,99.5,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,112.8,108.4,112.8z M108.4,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C111,117.2,109.9,118.4,108.4,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,112.8,117.4,112.8z M117.4,118.4\n c-1.4,0-2.6-1.2-2.6-2.6c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C120,117.2,118.8,118.4,117.4,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,112.8,126.3,112.8z M126.3,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C129,117.2,127.8,118.4,126.3,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,112.8,135.3,112.8z M135.3,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C137.9,117.2,136.8,118.4,135.3,118.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,112.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,112.8,36.7,112.8z M36.7,118.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C39.4,117.2,38.2,118.4,36.7,118.4z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000023262343608832889980000007837414120611036803_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,103.8,45.7,103.8z M45.7,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C48.3,108.2,47.2,109.4,45.7,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,103.8,54.7,103.8z M54.7,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C57.3,108.2,56.1,109.4,54.7,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,103.8,63.6,103.8z M63.6,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C66.3,108.2,65.1,109.4,63.6,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,103.8,72.6,103.8z M72.6,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C75.2,108.2,74,109.4,72.6,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,103.8,81.6,103.8z M81.6,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C84.2,108.2,83,109.4,81.6,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,103.8,90.5,103.8z M90.5,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C93.1,108.2,91.9,109.4,90.5,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,103.8,99.5,103.8z M99.5,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C102.1,108.2,100.9,109.4,99.5,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,103.8,108.4,103.8z M108.4,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C111,108.2,109.9,109.4,108.4,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,103.8,117.4,103.8z M117.4,109.4\n c-1.4,0-2.6-1.2-2.6-2.6c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C120,108.2,118.8,109.4,117.4,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,103.8,126.3,103.8z M126.3,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C129,108.2,127.8,109.4,126.3,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,103.8,135.3,103.8z M135.3,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C137.9,108.2,136.8,109.4,135.3,109.4z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,103.8c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,103.8,36.7,103.8z M36.7,109.4c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C39.4,108.2,38.2,109.4,36.7,109.4z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000032644834021452807300000012529714203134445742_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,94.9,45.7,94.9z M45.7,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C48.3,99.3,47.2,100.5,45.7,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,94.9,54.7,94.9z M54.7,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C57.3,99.3,56.1,100.5,54.7,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,94.9,63.6,94.9z M63.6,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C66.3,99.3,65.1,100.5,63.6,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,94.9,72.6,94.9z M72.6,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C75.2,99.3,74,100.5,72.6,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,94.9,81.6,94.9z M81.6,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C84.2,99.3,83,100.5,81.6,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,94.9,90.5,94.9z M90.5,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C93.1,99.3,91.9,100.5,90.5,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,94.9,99.5,94.9z M99.5,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C102.1,99.3,100.9,100.5,99.5,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,94.9,108.4,94.9z M108.4,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C111,99.3,109.9,100.5,108.4,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,94.9,117.4,94.9z M117.4,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C120,99.3,118.8,100.5,117.4,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,94.9,126.3,94.9z M126.3,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C129,99.3,127.8,100.5,126.3,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,94.9,135.3,94.9z M135.3,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6C137.9,99.3,136.8,100.5,135.3,100.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,94.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,94.9,36.7,94.9z M36.7,100.5c-1.4,0-2.6-1.2-2.6-2.6\n c0-1.4,1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6C39.4,99.3,38.2,100.5,36.7,100.5z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000046301211336714059340000011006363706714132412_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S47.3,85.9,45.7,85.9z M45.7,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S47.2,91.5,45.7,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S56.3,85.9,54.7,85.9z M54.7,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S56.1,91.5,54.7,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S65.3,85.9,63.6,85.9z M63.6,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S65.1,91.5,63.6,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S74.2,85.9,72.6,85.9z M72.6,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S74,91.5,72.6,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S83.2,85.9,81.6,85.9z M81.6,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S83,91.5,81.6,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S92.1,85.9,90.5,85.9z M90.5,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S91.9,91.5,90.5,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S101.1,85.9,99.5,85.9z M99.5,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S100.9,91.5,99.5,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S110.1,85.9,108.4,85.9z M108.4,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S109.9,91.5,108.4,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3c1.6,0,3-1.3,3-3S119,85.9,117.4,85.9z M117.4,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S118.8,91.5,117.4,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S128,85.9,126.3,85.9z M126.3,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S127.8,91.5,126.3,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S137,85.9,135.3,85.9z M135.3,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S136.8,91.5,135.3,91.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,85.9c-1.6,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3S38.4,85.9,36.7,85.9z M36.7,91.5c-1.4,0-2.6-1.2-2.6-2.6\n s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S38.2,91.5,36.7,91.5z" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": { + "id": "row_1_00000090987415974105529780000012985790832784842890_" + }, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M45.7,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C48.7,78.2,47.3,76.9,45.7,76.9z M45.7,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S47.2,82.5,45.7,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M54.7,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C57.7,78.2,56.3,76.9,54.7,76.9z M54.7,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S56.1,82.5,54.7,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M63.6,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C66.6,78.2,65.3,76.9,63.6,76.9z M63.6,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S65.1,82.5,63.6,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M72.6,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C75.6,78.2,74.2,76.9,72.6,76.9z M72.6,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S74,82.5,72.6,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M81.6,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C84.5,78.2,83.2,76.9,81.6,76.9z M81.6,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S83,82.5,81.6,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M90.5,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C93.5,78.2,92.1,76.9,90.5,76.9z M90.5,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S91.9,82.5,90.5,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M99.5,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C102.4,78.2,101.1,76.9,99.5,76.9z M99.5,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S100.9,82.5,99.5,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M108.4,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C111.4,78.2,110.1,76.9,108.4,76.9z M108.4,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S109.9,82.5,108.4,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M117.4,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3c1.6,0,3-1.3,3-3C120.3,78.2,119,76.9,117.4,76.9z M117.4,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S118.8,82.5,117.4,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M126.3,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C129.3,78.2,128,76.9,126.3,76.9z M126.3,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S127.8,82.5,126.3,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M135.3,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C138.3,78.2,137,76.9,135.3,76.9z M135.3,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6c1.4,0,2.6,1.2,2.6,2.6S136.8,82.5,135.3,82.5z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M36.7,76.9c-1.6,0-3,1.3-3,3c0,1.6,1.3,3,3,3s3-1.3,3-3C39.7,78.2,38.4,76.9,36.7,76.9z M36.7,82.5\n c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6s2.6,1.2,2.6,2.6S38.2,82.5,36.7,82.5z" + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M171.6,208.8H0.4c-0.1,0-0.2,0.1-0.2,0.2c0,0.1,0.1,0.2,0.2,0.2h171.3c0.1,0,0.2-0.1,0.2-0.2\n C171.8,208.9,171.7,208.8,171.6,208.8z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M171.6,212.8H0.4c-0.1,0-0.2,0.1-0.2,0.2c0,0.1,0.1,0.2,0.2,0.2h171.3c0.1,0,0.2-0.1,0.2-0.2\n C171.8,212.9,171.7,212.8,171.6,212.8z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M10.9,202.8h-0.4c-0.1,0-0.2,0.1-0.2,0.2s0.1,0.2,0.2,0.2h0.4c0.3,0,0.6,0.1,0.8,0.4l3.3,4.5c0.4,0.5,0.8,0.9,1.3,1.1\n c0.1,0,0.2,0,0.2-0.1c0-0.1,0-0.2-0.1-0.2c-0.5-0.2-0.9-0.6-1.2-1l-3.3-4.5C11.7,203,11.3,202.8,10.9,202.8z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M161.6,202.8h-0.4c-0.4,0-0.8,0.2-1.1,0.5l-3.3,4.5c-0.3,0.4-0.7,0.8-1.2,1c-0.1,0-0.1,0.1-0.1,0.2\n c0,0.1,0.1,0.1,0.2,0.1c0.5-0.2,1-0.6,1.3-1.1l3.3-4.5c0.2-0.3,0.5-0.4,0.8-0.4h0.4c0.1,0,0.2-0.1,0.2-0.2\n C161.8,202.9,161.7,202.8,161.6,202.8z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M161.6,202.7H10.5c-0.2,0-0.4,0.2-0.4,0.4s0.2,0.4,0.4,0.4h151.2c0.2,0,0.4-0.2,0.4-0.4S161.8,202.7,161.6,202.7z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M0.4,103.9H0.3c-0.1,0-0.1,0.1-0.1,0.1c0,0.1,0.1,0.1,0.1,0.1h0.1c0.1,0,0.1-0.1,0.1-0.1C0.5,104,0.5,103.9,0.4,103.9z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M167.6,38.9c-0.1,0-0.2,0.1-0.2,0.2v203.4H4.6V39.1c0-0.1-0.1-0.2-0.2-0.2c-0.1,0-0.2,0.1-0.2,0.2v203.6\n c0,0.1,0.1,0.2,0.2,0.2h163.2c0.1,0,0.2-0.1,0.2-0.2V39.1C167.8,39,167.7,38.9,167.6,38.9z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M150.5,63.9h-129c-1.4,0-2.6,1.2-2.6,2.6v4.4c0,0.2,0.2,0.4,0.4,0.4h5.9c0.4,0,0.6,0.3,0.6,0.6v2.5\n c0,0.4-0.3,0.6-0.6,0.6h-5.9c-0.2,0-0.4,0.2-0.4,0.4v65.3c0,0.2,0.2,0.4,0.4,0.4h5.9c0.4,0,0.6,0.3,0.6,0.6v2.5\n c0,0.4-0.3,0.6-0.6,0.6h-5.9c-0.2,0-0.4,0.2-0.4,0.4V156c0,1.4,1.2,2.6,2.6,2.6h129c1.4,0,2.6-1.2,2.6-2.6v-10.9\n c0-0.2-0.2-0.4-0.4-0.4h-5.9c-0.4,0-0.6-0.3-0.6-0.6v-2.5c0-0.4,0.3-0.6,0.6-0.6h5.9c0.2,0,0.4-0.2,0.4-0.4V75.4\n c0-0.2-0.2-0.4-0.4-0.4h-5.9c-0.4,0-0.6-0.3-0.6-0.6v-2.5c0-0.4,0.3-0.6,0.6-0.6h5.9c0.2,0,0.4-0.2,0.4-0.4v-4.4\n C153.1,65.1,151.9,63.9,150.5,63.9z M19.7,70.5v-4c0-1,0.8-1.9,1.9-1.9h129c1,0,1.9,0.8,1.9,1.9v4h-5.5c-0.7,0-1.3,0.6-1.3,1.3\n v2.5c0,0.7,0.6,1.3,1.3,1.3h5.5v64.6h-5.5c-0.7,0-1.3,0.6-1.3,1.3v2.5c0,0.7,0.6,1.3,1.3,1.3h5.5V156c0,1-0.8,1.9-1.9,1.9h-129\n c-1,0-1.9-0.8-1.9-1.9v-10.5h5.5c0.7,0,1.3-0.6,1.3-1.3v-2.5c0-0.7-0.6-1.3-1.3-1.3h-5.5V75.7h5.5c0.7,0,1.3-0.6,1.3-1.3v-2.5\n c0-0.7-0.6-1.3-1.3-1.3L19.7,70.5L19.7,70.5z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M47.7,52.7c-3.2,0-5.2,3.4-6.3,5.5c-0.1,0.1-0.1,0.2-0.2,0.3c-0.4,0.8-0.9,1.7-1.8,1.7H21c-3.5,0-6.3,2.8-6.3,6.3v95.9\n c0,3.5,2.8,6.3,6.3,6.3h130c3.5,0,6.3-2.8,6.3-6.3V66.6c0-3.5-2.8-6.3-6.3-6.3h-18.4c-0.9,0-1.3-0.9-1.8-1.7\n c-0.1-0.1-0.1-0.2-0.2-0.3c-1-1.9-2.2-3.9-4.2-5c-0.8-0.4-1.7-0.6-2.5-0.5H48.1C47.9,52.7,47.8,52.7,47.7,52.7z M21,168.1\n c-3.1,0-5.6-2.5-5.6-5.6V66.6c0-3.1,2.5-5.6,5.6-5.6h18.4c1.3,0,1.9-1.2,2.4-2.1c0.1-0.1,0.1-0.2,0.2-0.3\n c1.5-2.7,3.2-5.4,6.1-5.1h76c0,0,0,0,0,0c0.7-0.1,1.5,0.1,2.2,0.4c1.8,0.9,2.9,2.9,3.9,4.7c0.1,0.1,0.1,0.2,0.2,0.3\n c0.5,0.9,1.1,2.1,2.4,2.1H151c3.1,0,5.6,2.5,5.6,5.6v95.9c0,3.1-2.5,5.6-5.6,5.6H21z" + }, + "children": [] + } + ] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M141,191.4H31.1c-1.3,0-2.3,1.1-2.3,2.3v9.2c0,0.2,0.2,0.4,0.4,0.4c0.2,0,0.4-0.2,0.4-0.4v-9.2c0-0.9,0.7-1.6,1.6-1.6H141\n c0.9,0,1.6,0.7,1.6,1.6v9.2c0,0.2,0.2,0.4,0.4,0.4s0.4-0.2,0.4-0.4v-9.2C143.3,192.5,142.3,191.4,141,191.4z" + }, + "children": [] + } + ] + }, + { + "name": "g", + "type": "element", + "value": "", + "attributes": {}, + "children": [ + { + "name": "path", + "type": "element", + "value": "", + "attributes": { + "d": "M139,195.1H33.1c-0.4,0-0.7,0.3-0.7,0.7v7.5c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2v-7.5c0-0.2,0.1-0.3,0.3-0.3H139\n c0.2,0,0.3,0.1,0.3,0.3v7.4c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2v-7.4C139.7,195.4,139.4,195.1,139,195.1z" + }, + "children": [] + } + ] + } + ] + } + ] + } +} diff --git a/shared-data/module/schemas/3.json b/shared-data/module/schemas/3.json index 6ccd1bb8eab..fdafba4c8a9 100644 --- a/shared-data/module/schemas/3.json +++ b/shared-data/module/schemas/3.json @@ -81,13 +81,14 @@ "magneticModuleType", "thermocyclerModuleType", "heaterShakerModuleType", - "magneticBlockType" + "magneticBlockType", + "absorbanceReaderType" ], "type": "string" }, "model": { "type": "string", - "pattern": "^(temperatureModule|magneticModule|thermocyclerModule|heaterShakerModule|magneticBlock)V[0-9]+$" + "pattern": "^(temperatureModule|magneticModule|thermocyclerModule|heaterShakerModule|magneticBlock|absorbanceReader)V[0-9]+$" }, "labwareOffset": { "$ref": "#/definitions/coordinates" }, "dimensions": { diff --git a/shared-data/python/opentrons_shared_data/module/dev_types.py b/shared-data/python/opentrons_shared_data/module/dev_types.py index 326d9b6b764..c6dbbc4acad 100644 --- a/shared-data/python/opentrons_shared_data/module/dev_types.py +++ b/shared-data/python/opentrons_shared_data/module/dev_types.py @@ -18,6 +18,7 @@ ThermocyclerModuleType = Literal["thermocyclerModuleType"] HeaterShakerModuleType = Literal["heaterShakerModuleType"] MagneticBlockType = Literal["magneticBlockType"] +AbsorbanceReaderType = Literal["absorbanceReaderType"] ModuleType = Union[ MagneticModuleType, @@ -25,6 +26,7 @@ ThermocyclerModuleType, HeaterShakerModuleType, MagneticBlockType, + AbsorbanceReaderType, ] MagneticModuleModel = Literal["magneticModuleV1", "magneticModuleV2"] @@ -32,6 +34,7 @@ ThermocyclerModuleModel = Literal["thermocyclerModuleV1", "thermocyclerModuleV2"] HeaterShakerModuleModel = Literal["heaterShakerModuleV1"] MagneticBlockModel = Literal["magneticBlockV1"] +AbsorbanceReaderModel = Literal["absorbanceReaderV1"] ModuleModel = Union[ MagneticModuleModel, @@ -39,6 +42,7 @@ ThermocyclerModuleModel, HeaterShakerModuleModel, MagneticBlockModel, + AbsorbanceReaderModel, ] ModuleSlotTransform = TypedDict(