From 769ab91da89052441d769bc6bf54c703ccd4e84e Mon Sep 17 00:00:00 2001 From: fotobox Date: Mon, 17 Mar 2025 03:47:13 +0100 Subject: [PATCH] added completly new version for haslach 2025 --- .DS_Store | Bin 0 -> 6148 bytes .idea/.gitignore | 3 + .idea/fotobox.iml | 10 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .venv/bin/activate | 76 + .venv/bin/activate.csh | 37 + .venv/bin/activate.fish | 75 + .venv/bin/easy_install | 10 + .venv/bin/easy_install-3.7 | 10 + .venv/bin/normalizer | 10 + .venv/bin/pinout | 10 + .venv/bin/pip | 10 + .venv/bin/pip3 | 10 + .venv/bin/pip3.7 | 10 + .venv/bin/python | 1 + .venv/bin/python3 | 1 + .venv/bin/wdc | 624 ++ .../site/python3.7/pygame/_blit_info.h | 21 + .venv/include/site/python3.7/pygame/_camera.h | 26 + .venv/include/site/python3.7/pygame/_pygame.h | 374 + .../include/site/python3.7/pygame/_surface.h | 30 + .venv/include/site/python3.7/pygame/camera.h | 252 + .venv/include/site/python3.7/pygame/font.h | 15 + .../include/site/python3.7/pygame/freetype.h | 114 + .../site/python3.7/pygame/include/_pygame.h | 765 ++ .../site/python3.7/pygame/include/bitmask.h | 171 + .../site/python3.7/pygame/include/pgcompat.h | 102 + .../site/python3.7/pygame/include/pgimport.h | 67 + .../python3.7/pygame/include/pgplatform.h | 87 + .../site/python3.7/pygame/include/pygame.h | 34 + .../pygame/include/pygame_bufferproxy.h | 56 + .../python3.7/pygame/include/pygame_font.h | 50 + .../pygame/include/pygame_freetype.h | 42 + .../python3.7/pygame/include/pygame_mask.h | 45 + .../python3.7/pygame/include/pygame_mixer.h | 71 + .../site/python3.7/pygame/include/sse2neon.h | 6203 ++++++++++++ .venv/include/site/python3.7/pygame/mask.h | 7 + .venv/include/site/python3.7/pygame/mixer.h | 14 + .venv/include/site/python3.7/pygame/palette.h | 123 + .../site/python3.7/pygame/pgarrinter.h | 26 + .../site/python3.7/pygame/pgbufferproxy.h | 7 + .../include/site/python3.7/pygame/pgcompat.h | 27 + .../include/site/python3.7/pygame/pgopengl.h | 20 + .../site/python3.7/pygame/pgplatform.h | 23 + .venv/include/site/python3.7/pygame/pygame.h | 32 + .venv/include/site/python3.7/pygame/scrap.h | 147 + .../site/python3.7/pygame/simd_blitters.h | 84 + .venv/include/site/python3.7/pygame/surface.h | 361 + .../RPi.GPIO-0.7.1.dist-info/INSTALLER | 1 + .../RPi.GPIO-0.7.1.dist-info/LICENCE.txt | 20 + .../RPi.GPIO-0.7.1.dist-info/METADATA | 263 + .../RPi.GPIO-0.7.1.dist-info/RECORD | 11 + .../RPi.GPIO-0.7.1.dist-info/WHEEL | 5 + .../RPi.GPIO-0.7.1.dist-info/top_level.txt | 1 + .../site-packages/RPi/GPIO/__init__.py | 25 + .../GPIO/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 282 bytes .../_GPIO.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 134980 bytes .../python3.7/site-packages/RPi/__init__.py | 0 .../RPi/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 137 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 281 bytes .../__pycache__/six.cpython-37.pyc | Bin 0 -> 27407 bytes .../typing_extensions.cpython-37.pyc | Bin 0 -> 94035 bytes .../aiohttp-3.8.6.dist-info/INSTALLER | 1 + .../aiohttp-3.8.6.dist-info/LICENSE.txt | 13 + .../aiohttp-3.8.6.dist-info/METADATA | 254 + .../aiohttp-3.8.6.dist-info/RECORD | 117 + .../aiohttp-3.8.6.dist-info/WHEEL | 5 + .../aiohttp-3.8.6.dist-info/top_level.txt | 1 + .../aiohttp/.hash/_cparser.pxd.hash | 1 + .../aiohttp/.hash/_find_header.pxd.hash | 1 + .../aiohttp/.hash/_helpers.pyi.hash | 1 + .../aiohttp/.hash/_helpers.pyx.hash | 1 + .../aiohttp/.hash/_http_parser.pyx.hash | 1 + .../aiohttp/.hash/_http_writer.pyx.hash | 1 + .../aiohttp/.hash/_websocket.pyx.hash | 1 + .../site-packages/aiohttp/.hash/hdrs.py.hash | 1 + .../site-packages/aiohttp/__init__.py | 216 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3655 bytes .../aiohttp/__pycache__/abc.cpython-37.pyc | Bin 0 -> 8597 bytes .../__pycache__/base_protocol.cpython-37.pyc | Bin 0 -> 2777 bytes .../aiohttp/__pycache__/client.cpython-37.pyc | Bin 0 -> 29730 bytes .../client_exceptions.cpython-37.pyc | Bin 0 -> 11332 bytes .../__pycache__/client_proto.cpython-37.pyc | Bin 0 -> 6018 bytes .../__pycache__/client_reqrep.cpython-37.pyc | Bin 0 -> 27826 bytes .../__pycache__/client_ws.cpython-37.pyc | Bin 0 -> 8823 bytes .../__pycache__/connector.cpython-37.pyc | Bin 0 -> 35246 bytes .../__pycache__/cookiejar.cpython-37.pyc | Bin 0 -> 10787 bytes .../__pycache__/formdata.cpython-37.pyc | Bin 0 -> 4443 bytes .../aiohttp/__pycache__/hdrs.cpython-37.pyc | Bin 0 -> 5259 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 25931 bytes .../aiohttp/__pycache__/http.cpython-37.pyc | Bin 0 -> 1288 bytes .../http_exceptions.cpython-37.pyc | Bin 0 -> 4393 bytes .../__pycache__/http_parser.cpython-37.pyc | Bin 0 -> 19155 bytes .../__pycache__/http_websocket.cpython-37.pyc | Bin 0 -> 14966 bytes .../__pycache__/http_writer.cpython-37.pyc | Bin 0 -> 5505 bytes .../aiohttp/__pycache__/locks.cpython-37.pyc | Bin 0 -> 1579 bytes .../aiohttp/__pycache__/log.cpython-37.pyc | Bin 0 -> 420 bytes .../__pycache__/multipart.cpython-37.pyc | Bin 0 -> 26208 bytes .../__pycache__/payload.cpython-37.pyc | Bin 0 -> 13444 bytes .../payload_streamer.cpython-37.pyc | Bin 0 -> 3179 bytes .../__pycache__/pytest_plugin.cpython-37.pyc | Bin 0 -> 9863 bytes .../__pycache__/resolver.cpython-37.pyc | Bin 0 -> 3958 bytes .../__pycache__/streams.cpython-37.pyc | Bin 0 -> 18519 bytes .../__pycache__/tcp_helpers.cpython-37.pyc | Bin 0 -> 1073 bytes .../__pycache__/test_utils.cpython-37.pyc | Bin 0 -> 21643 bytes .../__pycache__/tracing.cpython-37.pyc | Bin 0 -> 15001 bytes .../__pycache__/typedefs.cpython-37.pyc | Bin 0 -> 1469 bytes .../aiohttp/__pycache__/web.cpython-37.pyc | Bin 0 -> 9950 bytes .../__pycache__/web_app.cpython-37.pyc | Bin 0 -> 15105 bytes .../__pycache__/web_exceptions.cpython-37.pyc | Bin 0 -> 12644 bytes .../web_fileresponse.cpython-37.pyc | Bin 0 -> 5928 bytes .../__pycache__/web_log.cpython-37.pyc | Bin 0 -> 7205 bytes .../web_middlewares.cpython-37.pyc | Bin 0 -> 3851 bytes .../__pycache__/web_protocol.cpython-37.pyc | Bin 0 -> 15591 bytes .../__pycache__/web_request.cpython-37.pyc | Bin 0 -> 23952 bytes .../__pycache__/web_response.cpython-37.pyc | Bin 0 -> 21045 bytes .../__pycache__/web_routedef.cpython-37.pyc | Bin 0 -> 7994 bytes .../__pycache__/web_runner.cpython-37.pyc | Bin 0 -> 11641 bytes .../__pycache__/web_server.cpython-37.pyc | Bin 0 -> 2678 bytes .../web_urldispatcher.cpython-37.pyc | Bin 0 -> 42257 bytes .../aiohttp/__pycache__/web_ws.cpython-37.pyc | Bin 0 -> 13271 bytes .../aiohttp/__pycache__/worker.cpython-37.pyc | Bin 0 -> 6950 bytes .../site-packages/aiohttp/_cparser.pxd | 158 + .../site-packages/aiohttp/_find_header.pxd | 2 + .../site-packages/aiohttp/_headers.pxi | 83 + ...helpers.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 106032 bytes .../site-packages/aiohttp/_helpers.pyi | 6 + .../site-packages/aiohttp/_helpers.pyx | 35 + ..._parser.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 687336 bytes .../site-packages/aiohttp/_http_parser.pyx | 836 ++ ..._writer.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 94692 bytes .../site-packages/aiohttp/_http_writer.pyx | 163 + ...bsocket.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 64796 bytes .../site-packages/aiohttp/_websocket.pyx | 56 + .../python3.7/site-packages/aiohttp/abc.py | 207 + .../site-packages/aiohttp/base_protocol.py | 90 + .../python3.7/site-packages/aiohttp/client.py | 1331 +++ .../aiohttp/client_exceptions.py | 342 + .../site-packages/aiohttp/client_proto.py | 251 + .../site-packages/aiohttp/client_reqrep.py | 1135 +++ .../site-packages/aiohttp/client_ws.py | 300 + .../site-packages/aiohttp/connector.py | 1456 +++ .../site-packages/aiohttp/cookiejar.py | 416 + .../site-packages/aiohttp/formdata.py | 172 + .../python3.7/site-packages/aiohttp/hdrs.py | 114 + .../site-packages/aiohttp/helpers.py | 881 ++ .../python3.7/site-packages/aiohttp/http.py | 70 + .../site-packages/aiohttp/http_exceptions.py | 107 + .../site-packages/aiohttp/http_parser.py | 1025 ++ .../site-packages/aiohttp/http_websocket.py | 701 ++ .../site-packages/aiohttp/http_writer.py | 198 + .../python3.7/site-packages/aiohttp/locks.py | 41 + .../python3.7/site-packages/aiohttp/log.py | 8 + .../site-packages/aiohttp/multipart.py | 961 ++ .../site-packages/aiohttp/payload.py | 465 + .../site-packages/aiohttp/payload_streamer.py | 75 + .../python3.7/site-packages/aiohttp/py.typed | 1 + .../site-packages/aiohttp/pytest_plugin.py | 391 + .../site-packages/aiohttp/resolver.py | 160 + .../site-packages/aiohttp/streams.py | 660 ++ .../site-packages/aiohttp/tcp_helpers.py | 37 + .../site-packages/aiohttp/test_utils.py | 706 ++ .../site-packages/aiohttp/tracing.py | 472 + .../site-packages/aiohttp/typedefs.py | 64 + .../python3.7/site-packages/aiohttp/web.py | 588 ++ .../site-packages/aiohttp/web_app.py | 557 ++ .../site-packages/aiohttp/web_exceptions.py | 441 + .../site-packages/aiohttp/web_fileresponse.py | 288 + .../site-packages/aiohttp/web_log.py | 208 + .../site-packages/aiohttp/web_middlewares.py | 119 + .../site-packages/aiohttp/web_protocol.py | 679 ++ .../site-packages/aiohttp/web_request.py | 882 ++ .../site-packages/aiohttp/web_response.py | 825 ++ .../site-packages/aiohttp/web_routedef.py | 216 + .../site-packages/aiohttp/web_runner.py | 381 + .../site-packages/aiohttp/web_server.py | 62 + .../aiohttp/web_urldispatcher.py | 1220 +++ .../python3.7/site-packages/aiohttp/web_ws.py | 487 + .../python3.7/site-packages/aiohttp/worker.py | 269 + .../aiosignal-1.3.1.dist-info/INSTALLER | 1 + .../aiosignal-1.3.1.dist-info/LICENSE | 201 + .../aiosignal-1.3.1.dist-info/METADATA | 128 + .../aiosignal-1.3.1.dist-info/RECORD | 10 + .../aiosignal-1.3.1.dist-info/WHEEL | 5 + .../aiosignal-1.3.1.dist-info/top_level.txt | 1 + .../site-packages/aiosignal/__init__.py | 36 + .../site-packages/aiosignal/__init__.pyi | 12 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1282 bytes .../site-packages/aiosignal/py.typed | 0 .../async_timeout-4.0.3.dist-info/INSTALLER | 1 + .../async_timeout-4.0.3.dist-info/LICENSE | 13 + .../async_timeout-4.0.3.dist-info/METADATA | 131 + .../async_timeout-4.0.3.dist-info/RECORD | 10 + .../async_timeout-4.0.3.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../async_timeout-4.0.3.dist-info/zip-safe | 1 + .../site-packages/async_timeout/__init__.py | 239 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6484 bytes .../site-packages/async_timeout/py.typed | 1 + .../asynctest-0.13.0.dist-info/INSTALLER | 1 + .../asynctest-0.13.0.dist-info/LICENSE.md | 15 + .../asynctest-0.13.0.dist-info/METADATA | 156 + .../asynctest-0.13.0.dist-info/RECORD | 19 + .../asynctest-0.13.0.dist-info/WHEEL | 5 + .../asynctest-0.13.0.dist-info/top_level.txt | 1 + .../asynctest-0.13.0.dist-info/zip-safe | 1 + .../site-packages/asynctest/__init__.py | 30 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 908 bytes .../__pycache__/_fail_on.cpython-37.pyc | Bin 0 -> 4551 bytes .../asynctest/__pycache__/case.cpython-37.pyc | Bin 0 -> 14947 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 732 bytes .../asynctest/__pycache__/mock.cpython-37.pyc | Bin 0 -> 39815 bytes .../__pycache__/selector.cpython-37.pyc | Bin 0 -> 11223 bytes .../site-packages/asynctest/_fail_on.py | 146 + .../python3.7/site-packages/asynctest/case.py | 505 + .../site-packages/asynctest/helpers.py | 24 + .../python3.7/site-packages/asynctest/mock.py | 1382 +++ .../site-packages/asynctest/selector.py | 378 + .../python3.7/site-packages/attr/__init__.py | 103 + .../python3.7/site-packages/attr/__init__.pyi | 388 + .../attr/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2345 bytes .../attr/__pycache__/_cmp.cpython-37.pyc | Bin 0 -> 3941 bytes .../attr/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 2540 bytes .../attr/__pycache__/_config.cpython-37.pyc | Bin 0 -> 958 bytes .../attr/__pycache__/_funcs.cpython-37.pyc | Bin 0 -> 12101 bytes .../attr/__pycache__/_make.cpython-37.pyc | Bin 0 -> 64438 bytes .../attr/__pycache__/_next_gen.cpython-37.pyc | Bin 0 -> 23782 bytes .../__pycache__/_version_info.cpython-37.pyc | Bin 0 -> 2270 bytes .../__pycache__/converters.cpython-37.pyc | Bin 0 -> 3446 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 3284 bytes .../attr/__pycache__/filters.cpython-37.pyc | Bin 0 -> 2324 bytes .../attr/__pycache__/setters.cpython-37.pyc | Bin 0 -> 1553 bytes .../__pycache__/validators.cpython-37.pyc | Bin 0 -> 21153 bytes .../lib/python3.7/site-packages/attr/_cmp.py | 160 + .../lib/python3.7/site-packages/attr/_cmp.pyi | 13 + .../python3.7/site-packages/attr/_compat.py | 103 + .../python3.7/site-packages/attr/_config.py | 31 + .../python3.7/site-packages/attr/_funcs.py | 522 + .../lib/python3.7/site-packages/attr/_make.py | 2960 ++++++ .../python3.7/site-packages/attr/_next_gen.py | 631 ++ .../site-packages/attr/_typing_compat.pyi | 15 + .../site-packages/attr/_version_info.py | 86 + .../site-packages/attr/_version_info.pyi | 9 + .../site-packages/attr/converters.py | 151 + .../site-packages/attr/converters.pyi | 13 + .../site-packages/attr/exceptions.py | 95 + .../site-packages/attr/exceptions.pyi | 17 + .../python3.7/site-packages/attr/filters.py | 72 + .../python3.7/site-packages/attr/filters.pyi | 6 + .../lib/python3.7/site-packages/attr/py.typed | 0 .../python3.7/site-packages/attr/setters.py | 79 + .../python3.7/site-packages/attr/setters.pyi | 20 + .../site-packages/attr/validators.py | 711 ++ .../site-packages/attr/validators.pyi | 83 + .../attrs-24.2.0.dist-info/INSTALLER | 1 + .../attrs-24.2.0.dist-info/METADATA | 242 + .../attrs-24.2.0.dist-info/RECORD | 55 + .../attrs-24.2.0.dist-info/WHEEL | 4 + .../attrs-24.2.0.dist-info/licenses/LICENSE | 21 + .../python3.7/site-packages/attrs/__init__.py | 67 + .../site-packages/attrs/__init__.pyi | 252 + .../attrs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/converters.cpython-37.pyc | Bin 0 -> 170 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 170 bytes .../attrs/__pycache__/filters.cpython-37.pyc | Bin 0 -> 164 bytes .../attrs/__pycache__/setters.cpython-37.pyc | Bin 0 -> 164 bytes .../__pycache__/validators.cpython-37.pyc | Bin 0 -> 170 bytes .../site-packages/attrs/converters.py | 3 + .../site-packages/attrs/exceptions.py | 3 + .../python3.7/site-packages/attrs/filters.py | 3 + .../python3.7/site-packages/attrs/py.typed | 0 .../python3.7/site-packages/attrs/setters.py | 3 + .../site-packages/attrs/validators.py | 3 + .../certifi-2023.5.7.dist-info/INSTALLER | 1 + .../certifi-2023.5.7.dist-info/LICENSE | 21 + .../certifi-2023.5.7.dist-info/METADATA | 69 + .../certifi-2023.5.7.dist-info/RECORD | 14 + .../certifi-2023.5.7.dist-info/WHEEL | 5 + .../certifi-2023.5.7.dist-info/top_level.txt | 1 + .../site-packages/certifi/__init__.py | 4 + .../site-packages/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 253 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 389 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 0 -> 1883 bytes .../site-packages/certifi/cacert.pem | 4589 +++++++++ .../python3.7/site-packages/certifi/core.py | 108 + .../python3.7/site-packages/certifi/py.typed | 0 .../INSTALLER | 1 + .../LICENSE | 21 + .../METADATA | 616 ++ .../charset_normalizer-3.1.0.dist-info/RECORD | 33 + .../charset_normalizer-3.1.0.dist-info/WHEEL | 5 + .../entry_points.txt | 2 + .../top_level.txt | 1 + .../charset_normalizer/__init__.py | 45 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1535 bytes .../__pycache__/api.cpython-37.pyc | Bin 0 -> 10108 bytes .../__pycache__/cd.cpython-37.pyc | Bin 0 -> 9604 bytes .../__pycache__/constant.cpython-37.pyc | Bin 0 -> 13990 bytes .../__pycache__/legacy.cpython-37.pyc | Bin 0 -> 1794 bytes .../__pycache__/md.cpython-37.pyc | Bin 0 -> 15413 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 11407 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 8975 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 246 bytes .../site-packages/charset_normalizer/api.py | 554 ++ .../charset_normalizer/assets/__init__.py | 1440 +++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 11995 bytes .../site-packages/charset_normalizer/cd.py | 390 + .../charset_normalizer/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 166 bytes .../cli/__pycache__/normalizer.cpython-37.pyc | Bin 0 -> 6379 bytes .../charset_normalizer/cli/normalizer.py | 296 + .../charset_normalizer/constant.py | 495 + .../charset_normalizer/legacy.py | 54 + .../site-packages/charset_normalizer/md.py | 571 ++ .../charset_normalizer/models.py | 337 + .../site-packages/charset_normalizer/py.typed | 0 .../site-packages/charset_normalizer/utils.py | 414 + .../charset_normalizer/version.py | 6 + .../colorzero-2.0.dist-info/INSTALLER | 1 + .../colorzero-2.0.dist-info/LICENSE.txt | 25 + .../colorzero-2.0.dist-info/METADATA | 100 + .../colorzero-2.0.dist-info/RECORD | 22 + .../colorzero-2.0.dist-info/WHEEL | 6 + .../colorzero-2.0.dist-info/top_level.txt | 1 + .../site-packages/colorzero/__init__.py | 29 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1110 bytes .../colorzero/__pycache__/attr.cpython-37.pyc | Bin 0 -> 7932 bytes .../__pycache__/color.cpython-37.pyc | Bin 0 -> 37324 bytes .../__pycache__/conversions.cpython-37.pyc | Bin 0 -> 12902 bytes .../__pycache__/deltae.cpython-37.pyc | Bin 0 -> 4805 bytes .../__pycache__/easings.cpython-37.pyc | Bin 0 -> 1133 bytes .../__pycache__/tables.cpython-37.pyc | Bin 0 -> 11104 bytes .../__pycache__/types.cpython-37.pyc | Bin 0 -> 10732 bytes .../python3.7/site-packages/colorzero/attr.py | 191 + .../site-packages/colorzero/color.py | 964 ++ .../site-packages/colorzero/conversions.py | 385 + .../site-packages/colorzero/deltae.py | 178 + .../site-packages/colorzero/easings.py | 33 + .../site-packages/colorzero/tables.py | 460 + .../site-packages/colorzero/types.py | 322 + .../site-packages/dateutil/__init__.py | 8 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 350 bytes .../__pycache__/_common.cpython-37.pyc | Bin 0 -> 1374 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 204 bytes .../__pycache__/easter.cpython-37.pyc | Bin 0 -> 2161 bytes .../__pycache__/relativedelta.cpython-37.pyc | Bin 0 -> 15121 bytes .../dateutil/__pycache__/rrule.cpython-37.pyc | Bin 0 -> 43367 bytes .../dateutil/__pycache__/tzwin.cpython-37.pyc | Bin 0 -> 169 bytes .../dateutil/__pycache__/utils.cpython-37.pyc | Bin 0 -> 2227 bytes .../site-packages/dateutil/_common.py | 43 + .../site-packages/dateutil/_version.py | 5 + .../site-packages/dateutil/easter.py | 89 + .../site-packages/dateutil/parser/__init__.py | 61 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2055 bytes .../parser/__pycache__/_parser.cpython-37.pyc | Bin 0 -> 40369 bytes .../__pycache__/isoparser.cpython-37.pyc | Bin 0 -> 11198 bytes .../site-packages/dateutil/parser/_parser.py | 1613 ++++ .../dateutil/parser/isoparser.py | 416 + .../site-packages/dateutil/relativedelta.py | 599 ++ .../python3.7/site-packages/dateutil/rrule.py | 1737 ++++ .../site-packages/dateutil/tz/__init__.py | 12 + .../tz/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 663 bytes .../tz/__pycache__/_common.cpython-37.pyc | Bin 0 -> 12219 bytes .../tz/__pycache__/_factories.cpython-37.pyc | Bin 0 -> 2860 bytes .../dateutil/tz/__pycache__/tz.cpython-37.pyc | Bin 0 -> 45244 bytes .../tz/__pycache__/win.cpython-37.pyc | Bin 0 -> 11073 bytes .../site-packages/dateutil/tz/_common.py | 419 + .../site-packages/dateutil/tz/_factories.py | 80 + .../python3.7/site-packages/dateutil/tz/tz.py | 1849 ++++ .../site-packages/dateutil/tz/win.py | 370 + .../python3.7/site-packages/dateutil/tzwin.py | 2 + .../python3.7/site-packages/dateutil/utils.py | 71 + .../dateutil/zoneinfo/__init__.py | 167 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 5597 bytes .../__pycache__/rebuild.cpython-37.pyc | Bin 0 -> 2560 bytes .../zoneinfo/dateutil-zoneinfo.tar.gz | Bin 0 -> 174394 bytes .../dateutil/zoneinfo/rebuild.py | 75 + .../python3.7/site-packages/easy_install.py | 5 + .../frozenlist-1.3.3.dist-info/INSTALLER | 1 + .../frozenlist-1.3.3.dist-info/LICENSE | 201 + .../frozenlist-1.3.3.dist-info/METADATA | 150 + .../frozenlist-1.3.3.dist-info/RECORD | 12 + .../frozenlist-1.3.3.dist-info/WHEEL | 5 + .../frozenlist-1.3.3.dist-info/top_level.txt | 1 + .../site-packages/frozenlist/__init__.py | 96 + .../site-packages/frozenlist/__init__.pyi | 47 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3272 bytes ...zenlist.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 149408 bytes .../site-packages/frozenlist/_frozenlist.pyx | 123 + .../site-packages/frozenlist/py.typed | 1 + .../gpiozero-1.6.2.dist-info/INSTALLER | 1 + .../gpiozero-1.6.2.dist-info/LICENSE.rst | 27 + .../gpiozero-1.6.2.dist-info/METADATA | 261 + .../gpiozero-1.6.2.dist-info/RECORD | 64 + .../gpiozero-1.6.2.dist-info/WHEEL | 6 + .../gpiozero-1.6.2.dist-info/entry_points.txt | 21 + .../gpiozero-1.6.2.dist-info/top_level.txt | 2 + .../site-packages/gpiozero/__init__.py | 134 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2376 bytes .../__pycache__/boards.cpython-37.pyc | Bin 0 -> 104214 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 4616 bytes .../__pycache__/devices.cpython-37.pyc | Bin 0 -> 19856 bytes .../gpiozero/__pycache__/exc.cpython-37.pyc | Bin 0 -> 13563 bytes .../gpiozero/__pycache__/fonts.cpython-37.pyc | Bin 0 -> 9444 bytes .../__pycache__/input_devices.cpython-37.pyc | Bin 0 -> 47233 bytes .../internal_devices.cpython-37.pyc | Bin 0 -> 26607 bytes .../__pycache__/mixins.cpython-37.pyc | Bin 0 -> 20558 bytes .../__pycache__/output_devices.cpython-37.pyc | Bin 0 -> 61313 bytes .../__pycache__/spi_devices.cpython-37.pyc | Bin 0 -> 19344 bytes .../__pycache__/threads.cpython-37.pyc | Bin 0 -> 1721 bytes .../gpiozero/__pycache__/tones.cpython-37.pyc | Bin 0 -> 8177 bytes .../gpiozero/__pycache__/tools.cpython-37.pyc | Bin 0 -> 22073 bytes .../site-packages/gpiozero/boards.py | 2927 ++++++ .../site-packages/gpiozero/compat.py | 168 + .../site-packages/gpiozero/devices.py | 628 ++ .../python3.7/site-packages/gpiozero/exc.py | 202 + .../python3.7/site-packages/gpiozero/fonts.py | 236 + .../site-packages/gpiozero/fonts/14seg.txt | 54 + .../site-packages/gpiozero/fonts/7seg.txt | 23 + .../site-packages/gpiozero/input_devices.py | 1374 +++ .../gpiozero/internal_devices.py | 750 ++ .../site-packages/gpiozero/mixins.py | 604 ++ .../site-packages/gpiozero/output_devices.py | 1808 ++++ .../site-packages/gpiozero/pins/__init__.py | 777 ++ .../pins/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 33106 bytes .../pins/__pycache__/data.cpython-37.pyc | Bin 0 -> 61362 bytes .../pins/__pycache__/lgpio.cpython-37.pyc | Bin 0 -> 12480 bytes .../pins/__pycache__/local.cpython-37.pyc | Bin 0 -> 11149 bytes .../pins/__pycache__/mock.cpython-37.pyc | Bin 0 -> 17981 bytes .../pins/__pycache__/native.cpython-37.pyc | Bin 0 -> 20927 bytes .../pins/__pycache__/pi.cpython-37.pyc | Bin 0 -> 11255 bytes .../pins/__pycache__/pigpio.cpython-37.pyc | Bin 0 -> 19880 bytes .../pins/__pycache__/rpigpio.cpython-37.pyc | Bin 0 -> 7968 bytes .../pins/__pycache__/rpio.cpython-37.pyc | Bin 0 -> 7398 bytes .../pins/__pycache__/spi.cpython-37.pyc | Bin 0 -> 2542 bytes .../site-packages/gpiozero/pins/data.py | 1479 +++ .../site-packages/gpiozero/pins/lgpio.py | 359 + .../site-packages/gpiozero/pins/local.py | 308 + .../site-packages/gpiozero/pins/mock.py | 492 + .../site-packages/gpiozero/pins/native.py | 633 ++ .../site-packages/gpiozero/pins/pi.py | 334 + .../site-packages/gpiozero/pins/pigpio.py | 601 ++ .../site-packages/gpiozero/pins/rpigpio.py | 232 + .../site-packages/gpiozero/pins/rpio.py | 226 + .../site-packages/gpiozero/pins/spi.py | 104 + .../site-packages/gpiozero/spi_devices.py | 557 ++ .../site-packages/gpiozero/threads.py | 62 + .../python3.7/site-packages/gpiozero/tones.py | 250 + .../python3.7/site-packages/gpiozero/tools.py | 755 ++ .../site-packages/gpiozerocli/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 145 bytes .../__pycache__/pinout.cpython-37.pyc | Bin 0 -> 2924 bytes .../site-packages/gpiozerocli/pinout.py | 113 + .../idna-3.4.dist-info/INSTALLER | 1 + .../idna-3.4.dist-info/LICENSE.md | 29 + .../site-packages/idna-3.4.dist-info/METADATA | 242 + .../site-packages/idna-3.4.dist-info/RECORD | 22 + .../site-packages/idna-3.4.dist-info/WHEEL | 4 + .../python3.7/site-packages/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 861 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 0 -> 3220 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 0 -> 700 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 0 -> 9871 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 0 -> 23263 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 0 -> 1931 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 0 -> 157 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 0 -> 187396 bytes .../lib/python3.7/site-packages/idna/codec.py | 112 + .../python3.7/site-packages/idna/compat.py | 13 + .../lib/python3.7/site-packages/idna/core.py | 400 + .../python3.7/site-packages/idna/idnadata.py | 2151 +++++ .../python3.7/site-packages/idna/intranges.py | 54 + .../site-packages/idna/package_data.py | 2 + .../lib/python3.7/site-packages/idna/py.typed | 0 .../python3.7/site-packages/idna/uts46data.py | 8600 +++++++++++++++++ .../INSTALLER | 1 + .../LICENSE | 202 + .../METADATA | 134 + .../importlib_metadata-6.7.0.dist-info/RECORD | 25 + .../importlib_metadata-6.7.0.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../importlib_metadata/__init__.py | 1015 ++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 36573 bytes .../__pycache__/_adapters.cpython-37.pyc | Bin 0 -> 2928 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 1512 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 2117 bytes .../__pycache__/_functools.cpython-37.pyc | Bin 0 -> 3095 bytes .../__pycache__/_itertools.cpython-37.pyc | Bin 0 -> 1995 bytes .../__pycache__/_meta.cpython-37.pyc | Bin 0 -> 2837 bytes .../__pycache__/_py39compat.cpython-37.pyc | Bin 0 -> 1144 bytes .../__pycache__/_text.cpython-37.pyc | Bin 0 -> 3050 bytes .../importlib_metadata/_adapters.py | 90 + .../importlib_metadata/_collections.py | 30 + .../importlib_metadata/_compat.py | 74 + .../importlib_metadata/_functools.py | 104 + .../importlib_metadata/_itertools.py | 73 + .../site-packages/importlib_metadata/_meta.py | 63 + .../importlib_metadata/_py39compat.py | 35 + .../site-packages/importlib_metadata/_text.py | 99 + .../site-packages/importlib_metadata/py.typed | 0 .../lxml-4.9.3.dist-info/INSTALLER | 1 + .../lxml-4.9.3.dist-info/LICENSE.txt | 29 + .../lxml-4.9.3.dist-info/LICENSES.txt | 29 + .../lxml-4.9.3.dist-info/METADATA | 98 + .../site-packages/lxml-4.9.3.dist-info/RECORD | 121 + .../site-packages/lxml-4.9.3.dist-info/WHEEL | 5 + .../lxml-4.9.3.dist-info/top_level.txt | 1 + .../site-packages/lxml/ElementInclude.py | 244 + .../python3.7/site-packages/lxml/__init__.py | 23 + .../__pycache__/ElementInclude.cpython-37.pyc | Bin 0 -> 3767 bytes .../lxml/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 657 bytes .../__pycache__/_elementpath.cpython-37.pyc | Bin 0 -> 6451 bytes .../lxml/__pycache__/builder.cpython-37.pyc | Bin 0 -> 5884 bytes .../lxml/__pycache__/cssselect.cpython-37.pyc | Bin 0 -> 3557 bytes .../__pycache__/doctestcompare.cpython-37.pyc | Bin 0 -> 13759 bytes .../__pycache__/pyclasslookup.cpython-37.pyc | Bin 0 -> 198 bytes .../lxml/__pycache__/sax.cpython-37.pyc | Bin 0 -> 8034 bytes .../__pycache__/usedoctest.cpython-37.pyc | Bin 0 -> 388 bytes ...entpath.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 348592 bytes .../site-packages/lxml/_elementpath.py | 345 + .../site-packages/lxml/apihelpers.pxi | 1819 ++++ ...builder.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 188260 bytes .../python3.7/site-packages/lxml/builder.py | 233 + .../site-packages/lxml/classlookup.pxi | 580 ++ .../python3.7/site-packages/lxml/cleanup.pxi | 215 + .../python3.7/site-packages/lxml/cssselect.py | 102 + .../python3.7/site-packages/lxml/debug.pxi | 91 + .../site-packages/lxml/docloader.pxi | 178 + .../site-packages/lxml/doctestcompare.py | 507 + .../lib/python3.7/site-packages/lxml/dtd.pxi | 478 + .../etree.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 3840660 bytes .../lib/python3.7/site-packages/lxml/etree.h | 224 + .../python3.7/site-packages/lxml/etree.pyx | 3683 +++++++ .../python3.7/site-packages/lxml/etree_api.h | 219 + .../site-packages/lxml/extensions.pxi | 871 ++ .../site-packages/lxml/html/ElementSoup.py | 10 + .../site-packages/lxml/html/__init__.py | 1946 ++++ .../__pycache__/ElementSoup.cpython-37.pyc | Bin 0 -> 480 bytes .../html/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 56686 bytes .../__pycache__/_diffcommand.cpython-37.pyc | Bin 0 -> 2186 bytes .../__pycache__/_html5builder.cpython-37.pyc | Bin 0 -> 3504 bytes .../html/__pycache__/_setmixin.cpython-37.pyc | Bin 0 -> 2046 bytes .../html/__pycache__/builder.cpython-37.pyc | Bin 0 -> 2911 bytes .../html/__pycache__/clean.cpython-37.pyc | Bin 0 -> 17573 bytes .../lxml/html/__pycache__/defs.cpython-37.pyc | Bin 0 -> 3055 bytes .../lxml/html/__pycache__/diff.cpython-37.pyc | Bin 0 -> 23944 bytes .../html/__pycache__/formfill.cpython-37.pyc | Bin 0 -> 7319 bytes .../__pycache__/html5parser.cpython-37.pyc | Bin 0 -> 6454 bytes .../__pycache__/soupparser.cpython-37.pyc | Bin 0 -> 7889 bytes .../__pycache__/usedoctest.cpython-37.pyc | Bin 0 -> 410 bytes .../site-packages/lxml/html/_diffcommand.py | 88 + .../site-packages/lxml/html/_html5builder.py | 100 + .../site-packages/lxml/html/_setmixin.py | 56 + .../site-packages/lxml/html/builder.py | 133 + .../clean.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 449092 bytes .../site-packages/lxml/html/clean.py | 785 ++ .../python3.7/site-packages/lxml/html/defs.py | 135 + .../diff.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 586556 bytes .../python3.7/site-packages/lxml/html/diff.py | 884 ++ .../site-packages/lxml/html/formfill.py | 299 + .../site-packages/lxml/html/html5parser.py | 260 + .../site-packages/lxml/html/soupparser.py | 314 + .../site-packages/lxml/html/usedoctest.py | 13 + .../site-packages/lxml/includes/__init__.pxd | 0 .../site-packages/lxml/includes/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 143 bytes .../site-packages/lxml/includes/c14n.pxd | 26 + .../site-packages/lxml/includes/config.pxd | 3 + .../site-packages/lxml/includes/dtdvalid.pxd | 18 + .../site-packages/lxml/includes/etree_defs.h | 427 + .../lxml/includes/etreepublic.pxd | 237 + .../lxml/includes/htmlparser.pxd | 56 + .../lxml/includes/lxml-version.h | 3 + .../site-packages/lxml/includes/relaxng.pxd | 64 + .../lxml/includes/schematron.pxd | 34 + .../site-packages/lxml/includes/tree.pxd | 480 + .../site-packages/lxml/includes/uri.pxd | 5 + .../site-packages/lxml/includes/xinclude.pxd | 22 + .../site-packages/lxml/includes/xmlerror.pxd | 852 ++ .../site-packages/lxml/includes/xmlparser.pxd | 250 + .../site-packages/lxml/includes/xmlschema.pxd | 35 + .../site-packages/lxml/includes/xpath.pxd | 135 + .../site-packages/lxml/includes/xslt.pxd | 191 + .../lxml/isoschematron/__init__.py | 334 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9574 bytes .../resources/rng/iso-schematron.rng | 709 ++ .../resources/xsl/RNG2Schtrn.xsl | 75 + .../resources/xsl/XSD2Schtrn.xsl | 77 + .../iso_abstract_expand.xsl | 313 + .../iso-schematron-xslt1/iso_dsdl_include.xsl | 1160 +++ .../iso_schematron_message.xsl | 55 + .../iso_schematron_skeleton_for_xslt1.xsl | 1796 ++++ .../iso_svrl_for_xslt1.xsl | 588 ++ .../xsl/iso-schematron-xslt1/readme.txt | 84 + .../site-packages/lxml/iterparse.pxi | 440 + .../python3.7/site-packages/lxml/lxml.etree.h | 224 + .../site-packages/lxml/lxml.etree_api.h | 219 + .../site-packages/lxml/nsclasses.pxi | 281 + ...jectify.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 770868 bytes .../site-packages/lxml/objectify.pyx | 2183 +++++ .../site-packages/lxml/objectpath.pxi | 332 + .../python3.7/site-packages/lxml/parser.pxi | 1921 ++++ .../site-packages/lxml/parsertarget.pxi | 194 + .../python3.7/site-packages/lxml/proxy.pxi | 619 ++ .../site-packages/lxml/public-api.pxi | 178 + .../site-packages/lxml/pyclasslookup.py | 3 + .../site-packages/lxml/readonlytree.pxi | 565 ++ .../python3.7/site-packages/lxml/relaxng.pxi | 163 + .../sax.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 297708 bytes .venv/lib/python3.7/site-packages/lxml/sax.py | 278 + .../site-packages/lxml/saxparser.pxi | 867 ++ .../site-packages/lxml/schematron.pxi | 167 + .../site-packages/lxml/serializer.pxi | 1875 ++++ .../site-packages/lxml/usedoctest.py | 13 + .../python3.7/site-packages/lxml/xinclude.pxi | 67 + .../python3.7/site-packages/lxml/xmlerror.pxi | 1648 ++++ .../python3.7/site-packages/lxml/xmlid.pxi | 179 + .../site-packages/lxml/xmlschema.pxi | 212 + .../python3.7/site-packages/lxml/xpath.pxi | 502 + .../lib/python3.7/site-packages/lxml/xslt.pxi | 972 ++ .../python3.7/site-packages/lxml/xsltext.pxi | 242 + .../multidict-6.0.5.dist-info/INSTALLER | 1 + .../multidict-6.0.5.dist-info/LICENSE | 13 + .../multidict-6.0.5.dist-info/METADATA | 132 + .../multidict-6.0.5.dist-info/RECORD | 17 + .../multidict-6.0.5.dist-info/WHEEL | 5 + .../multidict-6.0.5.dist-info/top_level.txt | 1 + .../site-packages/multidict/__init__.py | 48 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 821 bytes .../multidict/__pycache__/_abc.cpython-37.pyc | Bin 0 -> 1942 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 430 bytes .../_multidict_base.cpython-37.pyc | Bin 0 -> 3592 bytes .../__pycache__/_multidict_py.cpython-37.pyc | Bin 0 -> 17151 bytes .../python3.7/site-packages/multidict/_abc.py | 48 + .../site-packages/multidict/_compat.py | 14 + ...ltidict.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 131464 bytes .../multidict/_multidict_base.py | 144 + .../site-packages/multidict/_multidict_py.py | 527 + .../pip-18.1.dist-info/INSTALLER | 1 + .../pip-18.1.dist-info/LICENSE.txt | 20 + .../site-packages/pip-18.1.dist-info/METADATA | 70 + .../site-packages/pip-18.1.dist-info/RECORD | 172 + .../site-packages/pip-18.1.dist-info/WHEEL | 6 + .../pip-18.1.dist-info/entry_points.txt | 5 + .../pip-18.1.dist-info/top_level.txt | 1 + .../python3.7/site-packages/pip/__init__.py | 1 + .../python3.7/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 152 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 406 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1798 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 5007 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 6792 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9791 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 20859 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 11512 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 23133 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4188 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7247 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 0 -> 2671 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 8438 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 20800 bytes .../site-packages/pip/_internal/build_env.py | 142 + .../site-packages/pip/_internal/cache.py | 202 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 229 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 0 -> 5042 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 0 -> 6267 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 14988 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 0 -> 2189 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 0 -> 8893 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 358 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 278 + .../pip/_internal/cli/cmdoptions.py | 714 ++ .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2457 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1259 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3031 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6383 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 4611 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2827 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2021 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1197 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 12175 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8870 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4263 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5844 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2653 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 4874 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 174 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 555 ++ .../pip/_internal/commands/list.py | 306 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 921 ++ .../site-packages/pip/_internal/exceptions.py | 268 + .../site-packages/pip/_internal/index.py | 899 ++ .../site-packages/pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 0 -> 1052 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 0 -> 2387 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 1121 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 0 -> 4719 bytes .../pip/_internal/models/candidate.py | 23 + .../pip/_internal/models/format_control.py | 62 + .../pip/_internal/models/index.py | 29 + .../pip/_internal/models/link.py | 141 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 153 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3330 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 6285 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 9151 bytes .../pip/_internal/operations/check.py | 148 + .../pip/_internal/operations/freeze.py | 264 + .../pip/_internal/operations/prepare.py | 355 + .../site-packages/pip/_internal/pep425tags.py | 317 + .../site-packages/pip/_internal/pyproject.py | 144 + .../pip/_internal/req/__init__.py | 69 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1521 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 0 -> 6919 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 8620 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 22770 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 5734 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 2845 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 12817 bytes .../pip/_internal/req/constructors.py | 298 + .../pip/_internal/req/req_file.py | 340 + .../pip/_internal/req/req_install.py | 860 ++ .../pip/_internal/req/req_set.py | 181 + .../pip/_internal/req/req_tracker.py | 76 + .../pip/_internal/req/req_uninstall.py | 460 + .../site-packages/pip/_internal/resolve.py | 353 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 148 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 7869 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 0 -> 5939 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2522 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1084 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 615 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1506 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3283 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 5316 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 24407 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 0 -> 1897 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 3869 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2348 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 343 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 2760 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1292 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 11817 bytes .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/compat.py | 248 + .../pip/_internal/utils/deprecation.py | 89 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 225 + .../site-packages/pip/_internal/utils/misc.py | 958 ++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 154 + .../pip/_internal/utils/packaging.py | 75 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 509 + .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15514 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3777 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 9082 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3750 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 6352 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 346 + .../pip/_internal/vcs/mercurial.py | 101 + .../pip/_internal/vcs/subversion.py | 213 + .../site-packages/pip/_internal/wheel.py | 831 ++ .../site-packages/pip/_vendor/__init__.py | 114 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2874 bytes .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 237 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 0 -> 5302 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 0 -> 4701 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 0 -> 2866 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 0 -> 975 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 0 -> 4132 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 4699 bytes .../pip/_vendor/pep517/_in_process.py | 182 + .../site-packages/pip/_vendor/pep517/check.py | 194 + .../pip/_vendor/pep517/colorlog.py | 110 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 150 + .../pip/_vendor/pep517/wrappers.py | 134 + .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 421 + .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 + .../pkg_resources-0.0.0.dist-info/LICENSE.txt | 20 + .../pkg_resources-0.0.0.dist-info/METADATA | 13 + .../pkg_resources-0.0.0.dist-info/RECORD | 38 + .../pkg_resources-0.0.0.dist-info/WHEEL | 6 + .../site-packages/pkg_resources/__init__.py | 3236 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 98524 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 597 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 160 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20648 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203003 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24361 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 696 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 534 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 986 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2838 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8846 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3851 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19764 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 465 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10531 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2379 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../pygame-2.5.0.dist-info/INSTALLER | 1 + .../pygame-2.5.0.dist-info/METADATA | 280 + .../pygame-2.5.0.dist-info/RECORD | 752 ++ .../pygame-2.5.0.dist-info/WHEEL | 5 + .../pygame-2.5.0.dist-info/entry_points.txt | 2 + .../pygame-2.5.0.dist-info/top_level.txt | 1 + .../site-packages/pygame/__init__.py | 345 + .../site-packages/pygame/__init__.pyi | 632 ++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 7243 bytes .../__pycache__/_camera_opencv.cpython-37.pyc | Bin 0 -> 4975 bytes .../_camera_vidcapture.cpython-37.pyc | Bin 0 -> 3972 bytes .../pygame/__pycache__/camera.cpython-37.pyc | Bin 0 -> 4806 bytes .../__pycache__/colordict.cpython-37.pyc | Bin 0 -> 21507 bytes .../pygame/__pycache__/cursors.cpython-37.pyc | Bin 0 -> 12384 bytes .../pygame/__pycache__/draw_py.cpython-37.pyc | Bin 0 -> 12540 bytes .../__pycache__/fastevent.cpython-37.pyc | Bin 0 -> 2298 bytes .../__pycache__/freetype.cpython-37.pyc | Bin 0 -> 2277 bytes .../pygame/__pycache__/ftfont.cpython-37.pyc | Bin 0 -> 6412 bytes .../pygame/__pycache__/locals.cpython-37.pyc | Bin 0 -> 424 bytes .../pygame/__pycache__/macosx.cpython-37.pyc | Bin 0 -> 516 bytes .../pygame/__pycache__/midi.cpython-37.pyc | Bin 0 -> 23095 bytes .../pygame/__pycache__/pkgdata.cpython-37.pyc | Bin 0 -> 2443 bytes .../__pycache__/sndarray.cpython-37.pyc | Bin 0 -> 3376 bytes .../pygame/__pycache__/sprite.cpython-37.pyc | Bin 0 -> 52354 bytes .../__pycache__/surfarray.cpython-37.pyc | Bin 0 -> 13311 bytes .../pygame/__pycache__/sysfont.cpython-37.pyc | Bin 0 -> 10602 bytes .../pygame/__pycache__/version.cpython-37.pyc | Bin 0 -> 2467 bytes .../pygame/__pyinstaller/__init__.py | 5 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 307 bytes .../__pycache__/hook-pygame.cpython-37.pyc | Bin 0 -> 1106 bytes .../pygame/__pyinstaller/hook-pygame.py | 45 + ..._camera.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 102392 bytes .../site-packages/pygame/_camera_opencv.py | 208 + .../pygame/_camera_vidcapture.py | 117 + .../site-packages/pygame/_common.pyi | 40 + ...reetype.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 273392 bytes .../site-packages/pygame/_sdl2/__init__.py | 3 + .../site-packages/pygame/_sdl2/__init__.pyi | 3 + .../_sdl2/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 199 bytes .../audio.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 345340 bytes .../site-packages/pygame/_sdl2/audio.pyi | 54 + ...troller.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 204700 bytes .../site-packages/pygame/_sdl2/controller.pyi | 35 + .../mixer.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 302208 bytes .../sdl2.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 102812 bytes .../site-packages/pygame/_sdl2/sdl2.pyi | 16 + .../touch.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 45912 bytes .../site-packages/pygame/_sdl2/touch.pyi | 6 + .../video.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 497236 bytes .../site-packages/pygame/_sdl2/video.pyi | 159 + ..._sprite.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 630352 bytes .../base.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 68596 bytes .../python3.7/site-packages/pygame/base.pyi | 19 + ...erproxy.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 55624 bytes .../site-packages/pygame/bufferproxy.pyi | 15 + .../python3.7/site-packages/pygame/camera.py | 211 + .../python3.7/site-packages/pygame/camera.pyi | 49 + .../color.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 83316 bytes .../python3.7/site-packages/pygame/color.pyi | 56 + .../site-packages/pygame/colordict.py | 692 ++ ...nstants.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 131608 bytes .../site-packages/pygame/constants.pyi | 560 ++ .../python3.7/site-packages/pygame/cursors.py | 844 ++ .../site-packages/pygame/cursors.pyi | 91 + ...display.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 118952 bytes .../site-packages/pygame/display.pyi | 77 + .../site-packages/pygame/docs/__main__.py | 37 + .../docs/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 1113 bytes .../pygame/docs/generated/LGPL.txt | 504 + .../_images/AdvancedInputOutput1.gif | Bin 0 -> 5649 bytes .../_images/AdvancedInputOutput11.gif | Bin 0 -> 5649 bytes .../_images/AdvancedInputOutput2.gif | Bin 0 -> 72233 bytes .../_images/AdvancedInputOutput21.gif | Bin 0 -> 72233 bytes .../_images/AdvancedInputOutput3.gif | Bin 0 -> 6294 bytes .../_images/AdvancedInputOutput31.gif | Bin 0 -> 6294 bytes .../_images/AdvancedInputOutput4.gif | Bin 0 -> 29185 bytes .../_images/AdvancedInputOutput41.gif | Bin 0 -> 29185 bytes .../_images/AdvancedInputOutput5.gif | Bin 0 -> 37349 bytes .../_images/AdvancedInputOutput51.gif | Bin 0 -> 37349 bytes .../_images/AdvancedOutputAlpha1.gif | Bin 0 -> 14915 bytes .../_images/AdvancedOutputAlpha11.gif | Bin 0 -> 14915 bytes .../_images/AdvancedOutputAlpha2.gif | Bin 0 -> 71819 bytes .../_images/AdvancedOutputAlpha21.gif | Bin 0 -> 71819 bytes .../_images/AdvancedOutputAlpha3.gif | Bin 0 -> 30380 bytes .../_images/AdvancedOutputAlpha31.gif | Bin 0 -> 30380 bytes .../_images/AdvancedOutputProcess1.gif | Bin 0 -> 15951 bytes .../_images/AdvancedOutputProcess11.gif | Bin 0 -> 15951 bytes .../_images/AdvancedOutputProcess2.gif | Bin 0 -> 1868 bytes .../_images/AdvancedOutputProcess21.gif | Bin 0 -> 1868 bytes .../_images/AdvancedOutputProcess3.gif | Bin 0 -> 1912 bytes .../_images/AdvancedOutputProcess31.gif | Bin 0 -> 1912 bytes .../_images/AdvancedOutputProcess4.gif | Bin 0 -> 14500 bytes .../_images/AdvancedOutputProcess41.gif | Bin 0 -> 14500 bytes .../_images/AdvancedOutputProcess5.gif | Bin 0 -> 16896 bytes .../_images/AdvancedOutputProcess51.gif | Bin 0 -> 16896 bytes .../_images/AdvancedOutputProcess6.gif | Bin 0 -> 34058 bytes .../_images/AdvancedOutputProcess61.gif | Bin 0 -> 34058 bytes .../_images/Bagic-INPUT-resultscreen.png | Bin 0 -> 5973 bytes .../_images/Bagic-INPUT-resultscreen1.png | Bin 0 -> 5973 bytes .../_images/Bagic-INPUT-sourcecode.png | Bin 0 -> 77061 bytes .../_images/Bagic-INPUT-sourcecode1.png | Bin 0 -> 77061 bytes .../_images/Bagic-PROCESS-resultscreen.png | Bin 0 -> 5348 bytes .../_images/Bagic-PROCESS-resultscreen1.png | Bin 0 -> 5348 bytes .../_images/Bagic-PROCESS-sourcecode.png | Bin 0 -> 66070 bytes .../_images/Bagic-PROCESS-sourcecode1.png | Bin 0 -> 66070 bytes .../_images/Bagic-ouput-result-screen.png | Bin 0 -> 4819 bytes .../_images/Bagic-ouput-result-screen1.png | Bin 0 -> 4819 bytes .../_images/Basic-ouput-sourcecode.png | Bin 0 -> 57466 bytes .../_images/Basic-ouput-sourcecode1.png | Bin 0 -> 57466 bytes .../docs/generated/_images/angle_to.png | Bin 0 -> 25349 bytes .../docs/generated/_images/camera_average.jpg | Bin 0 -> 20881 bytes .../generated/_images/camera_background.jpg | Bin 0 -> 7493 bytes .../docs/generated/_images/camera_green.jpg | Bin 0 -> 10219 bytes .../docs/generated/_images/camera_hsv.jpg | Bin 0 -> 36673 bytes .../docs/generated/_images/camera_mask.jpg | Bin 0 -> 18779 bytes .../docs/generated/_images/camera_rgb.jpg | Bin 0 -> 32488 bytes .../docs/generated/_images/camera_thresh.jpg | Bin 0 -> 4346 bytes .../generated/_images/camera_thresholded.jpg | Bin 0 -> 23678 bytes .../docs/generated/_images/camera_yuv.jpg | Bin 0 -> 20105 bytes .../docs/generated/_images/chimpshot.gif | Bin 0 -> 46010 bytes .../generated/_images/draw_module_example.png | Bin 0 -> 6476 bytes .../docs/generated/_images/intro_ball.gif | Bin 0 -> 5015 bytes .../docs/generated/_images/intro_blade.jpg | Bin 0 -> 2631 bytes .../docs/generated/_images/intro_freedom.jpg | Bin 0 -> 7050 bytes .../_images/introduction-Battleship.png | Bin 0 -> 165586 bytes .../_images/introduction-Battleship1.png | Bin 0 -> 165586 bytes .../_images/introduction-PuyoPuyo.png | Bin 0 -> 31388 bytes .../_images/introduction-PuyoPuyo1.png | Bin 0 -> 31388 bytes .../generated/_images/introduction-TPS.png | Bin 0 -> 136031 bytes .../generated/_images/introduction-TPS1.png | Bin 0 -> 136031 bytes .../docs/generated/_images/joystick_calls.png | Bin 0 -> 30004 bytes .../docs/generated/_images/pygame_lofi.png | Bin 0 -> 134242 bytes .../docs/generated/_images/pygame_logo.png | Bin 0 -> 132068 bytes .../docs/generated/_images/pygame_powered.png | Bin 0 -> 179911 bytes .../_images/pygame_powered_lowres.png | Bin 0 -> 179911 bytes .../docs/generated/_images/pygame_tiny.png | Bin 0 -> 15310 bytes .../generated/_images/surfarray_allblack.png | Bin 0 -> 125 bytes .../generated/_images/surfarray_flipped.png | Bin 0 -> 50835 bytes .../generated/_images/surfarray_redimg.png | Bin 0 -> 23443 bytes .../generated/_images/surfarray_rgbarray.png | Bin 0 -> 50897 bytes .../generated/_images/surfarray_scaledown.png | Bin 0 -> 15109 bytes .../generated/_images/surfarray_scaleup.png | Bin 0 -> 67759 bytes .../generated/_images/surfarray_soften.png | Bin 0 -> 47540 bytes .../generated/_images/surfarray_striped.png | Bin 0 -> 392 bytes .../generated/_images/surfarray_xfade.png | Bin 0 -> 41834 bytes .../docs/generated/_images/tom_basic.png | Bin 0 -> 5139 bytes .../generated/_images/tom_event-flowchart.png | Bin 0 -> 5528 bytes .../docs/generated/_images/tom_formulae.png | Bin 0 -> 6763 bytes .../docs/generated/_images/tom_radians.png | Bin 0 -> 17409 bytes .../docs/generated/_sources/c_api.rst.txt | 25 + .../docs/generated/_sources/filepaths.rst.txt | 17 + .../docs/generated/_sources/index.rst.txt | 213 + .../docs/generated/_sources/logos.rst.txt | 47 + .../_sources/ref/bufferproxy.rst.txt | 113 + .../generated/_sources/ref/camera.rst.txt | 247 + .../docs/generated/_sources/ref/cdrom.rst.txt | 310 + .../docs/generated/_sources/ref/color.rst.txt | 283 + .../generated/_sources/ref/color_list.rst.txt | 2014 ++++ .../generated/_sources/ref/cursors.rst.txt | 251 + .../generated/_sources/ref/display.rst.txt | 737 ++ .../docs/generated/_sources/ref/draw.rst.txt | 557 ++ .../docs/generated/_sources/ref/event.rst.txt | 565 ++ .../generated/_sources/ref/examples.rst.txt | 451 + .../generated/_sources/ref/fastevent.rst.txt | 109 + .../docs/generated/_sources/ref/font.rst.txt | 499 + .../generated/_sources/ref/freetype.rst.txt | 770 ++ .../generated/_sources/ref/gfxdraw.rst.txt | 628 ++ .../docs/generated/_sources/ref/image.rst.txt | 375 + .../generated/_sources/ref/joystick.rst.txt | 697 ++ .../docs/generated/_sources/ref/key.rst.txt | 455 + .../generated/_sources/ref/locals.rst.txt | 27 + .../docs/generated/_sources/ref/mask.rst.txt | 642 ++ .../docs/generated/_sources/ref/math.rst.txt | 1143 +++ .../docs/generated/_sources/ref/midi.rst.txt | 484 + .../docs/generated/_sources/ref/mixer.rst.txt | 605 ++ .../docs/generated/_sources/ref/mouse.rst.txt | 219 + .../docs/generated/_sources/ref/music.rst.txt | 274 + .../generated/_sources/ref/overlay.rst.txt | 79 + .../generated/_sources/ref/pixelarray.rst.txt | 295 + .../generated/_sources/ref/pixelcopy.rst.txt | 104 + .../generated/_sources/ref/pygame.rst.txt | 505 + .../docs/generated/_sources/ref/rect.rst.txt | 604 ++ .../docs/generated/_sources/ref/scrap.rst.txt | 240 + .../_sources/ref/sdl2_controller.rst.txt | 287 + .../generated/_sources/ref/sdl2_video.rst.txt | 334 + .../generated/_sources/ref/sndarray.rst.txt | 95 + .../generated/_sources/ref/sprite.rst.txt | 895 ++ .../generated/_sources/ref/surface.rst.txt | 949 ++ .../generated/_sources/ref/surfarray.rst.txt | 337 + .../docs/generated/_sources/ref/tests.rst.txt | 108 + .../docs/generated/_sources/ref/time.rst.txt | 165 + .../docs/generated/_sources/ref/touch.rst.txt | 66 + .../generated/_sources/ref/transform.rst.txt | 325 + .../pygame/docs/generated/_static/basic.css | 903 ++ .../pygame/docs/generated/_static/doctools.js | 156 + .../_static/documentation_options.js | 14 + .../pygame/docs/generated/_static/file.png | Bin 0 -> 286 bytes .../docs/generated/_static/language_data.js | 199 + .../docs/generated/_static/legacy_logos.zip | Bin 0 -> 51315 bytes .../pygame/docs/generated/_static/minus.png | Bin 0 -> 90 bytes .../pygame/docs/generated/_static/plus.png | Bin 0 -> 90 bytes .../pygame/docs/generated/_static/pygame.css | 707 ++ .../pygame/docs/generated/_static/pygame.ico | Bin 0 -> 1078 bytes .../docs/generated/_static/pygame_lofi.png | Bin 0 -> 134242 bytes .../docs/generated/_static/pygame_lofi.svg | 234 + .../docs/generated/_static/pygame_logo.png | Bin 0 -> 132068 bytes .../docs/generated/_static/pygame_logo.svg | 234 + .../docs/generated/_static/pygame_powered.png | Bin 0 -> 179911 bytes .../docs/generated/_static/pygame_powered.svg | 326 + .../_static/pygame_powered_lowres.png | Bin 0 -> 179911 bytes .../docs/generated/_static/pygame_tiny.png | Bin 0 -> 15310 bytes .../docs/generated/_static/pygments.css | 74 + .../pygame/docs/generated/_static/reset.css | 49 + .../docs/generated/_static/searchtools.js | 566 ++ .../generated/_static/sphinx_highlight.js | 144 + .../pygame/docs/generated/_static/tooltip.css | 44 + .../pygame/docs/generated/c_api.html | 152 + .../pygame/docs/generated/c_api/base.html | 357 + .../docs/generated/c_api/bufferproxy.html | 179 + .../pygame/docs/generated/c_api/color.html | 168 + .../pygame/docs/generated/c_api/display.html | 173 + .../pygame/docs/generated/c_api/event.html | 188 + .../pygame/docs/generated/c_api/freetype.html | 176 + .../pygame/docs/generated/c_api/mixer.html | 209 + .../pygame/docs/generated/c_api/rect.html | 198 + .../pygame/docs/generated/c_api/rwobject.html | 200 + .../pygame/docs/generated/c_api/slots.html | 153 + .../pygame/docs/generated/c_api/surface.html | 190 + .../pygame/docs/generated/c_api/surflock.html | 227 + .../pygame/docs/generated/c_api/version.html | 169 + .../pygame/docs/generated/filepaths.html | 145 + .../pygame/docs/generated/genindex.html | 2672 +++++ .../pygame/docs/generated/index.html | 343 + .../pygame/docs/generated/logos.html | 168 + .../pygame/docs/generated/py-modindex.html | 249 + .../docs/generated/ref/bufferproxy.html | 274 + .../pygame/docs/generated/ref/camera.html | 458 + .../pygame/docs/generated/ref/cdrom.html | 578 ++ .../pygame/docs/generated/ref/color.html | 523 + .../pygame/docs/generated/ref/color_list.html | 2805 ++++++ .../pygame/docs/generated/ref/cursors.html | 438 + .../pygame/docs/generated/ref/display.html | 1006 ++ .../pygame/docs/generated/ref/draw.html | 956 ++ .../pygame/docs/generated/ref/event.html | 796 ++ .../pygame/docs/generated/ref/examples.html | 703 ++ .../pygame/docs/generated/ref/fastevent.html | 277 + .../pygame/docs/generated/ref/font.html | 817 ++ .../pygame/docs/generated/ref/freetype.html | 1261 +++ .../pygame/docs/generated/ref/gfxdraw.html | 1049 ++ .../pygame/docs/generated/ref/image.html | 557 ++ .../pygame/docs/generated/ref/joystick.html | 1136 +++ .../pygame/docs/generated/ref/key.html | 642 ++ .../pygame/docs/generated/ref/locals.html | 157 + .../pygame/docs/generated/ref/mask.html | 1109 +++ .../pygame/docs/generated/ref/math.html | 1818 ++++ .../pygame/docs/generated/ref/midi.html | 826 ++ .../pygame/docs/generated/ref/mixer.html | 977 ++ .../pygame/docs/generated/ref/mouse.html | 397 + .../pygame/docs/generated/ref/music.html | 493 + .../pygame/docs/generated/ref/overlay.html | 222 + .../pygame/docs/generated/ref/pixelarray.html | 477 + .../pygame/docs/generated/ref/pixelcopy.html | 253 + .../pygame/docs/generated/ref/pygame.html | 696 ++ .../pygame/docs/generated/ref/rect.html | 901 ++ .../pygame/docs/generated/ref/scrap.html | 449 + .../docs/generated/ref/sdl2_controller.html | 555 ++ .../pygame/docs/generated/ref/sdl2_video.html | 1062 ++ .../pygame/docs/generated/ref/sndarray.html | 265 + .../pygame/docs/generated/ref/sprite.html | 1381 +++ .../pygame/docs/generated/ref/surface.html | 1332 +++ .../pygame/docs/generated/ref/surfarray.html | 562 ++ .../pygame/docs/generated/ref/tests.html | 232 + .../pygame/docs/generated/ref/time.html | 356 + .../pygame/docs/generated/ref/touch.html | 231 + .../pygame/docs/generated/ref/transform.html | 598 ++ .../pygame/docs/generated/search.html | 94 + .../pygame/docs/generated/searchindex.js | 1 + .../docs/generated/tut/CameraIntro.html | 374 + .../docs/generated/tut/ChimpLineByLine.html | 593 ++ .../docs/generated/tut/DisplayModes.html | 310 + .../pygame/docs/generated/tut/ImportInit.html | 193 + .../pygame/docs/generated/tut/MakeGames.html | 233 + .../pygame/docs/generated/tut/MoveIt.html | 653 ++ .../docs/generated/tut/PygameIntro.html | 419 + .../docs/generated/tut/SpriteIntro.html | 494 + .../docs/generated/tut/SurfarrayIntro.html | 656 ++ .../pygame/docs/generated/tut/chimp.py.html | 338 + .../docs/generated/tut/newbieguide.html | 542 ++ .../pygame/docs/generated/tut/tom_games2.html | 236 + .../pygame/docs/generated/tut/tom_games3.html | 216 + .../pygame/docs/generated/tut/tom_games4.html | 245 + .../pygame/docs/generated/tut/tom_games5.html | 234 + .../pygame/docs/generated/tut/tom_games6.html | 433 + .../draw.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 96736 bytes .../python3.7/site-packages/pygame/draw.pyi | 74 + .../python3.7/site-packages/pygame/draw_py.py | 562 ++ .../event.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 114684 bytes .../python3.7/site-packages/pygame/event.pyi | 51 + .../site-packages/pygame/examples/README.rst | 154 + .../site-packages/pygame/examples/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 147 bytes .../__pycache__/aacircle.cpython-37.pyc | Bin 0 -> 1045 bytes .../__pycache__/aliens.cpython-37.pyc | Bin 0 -> 10206 bytes .../__pycache__/arraydemo.cpython-37.pyc | Bin 0 -> 2675 bytes .../__pycache__/audiocapture.cpython-37.pyc | Bin 0 -> 1619 bytes .../__pycache__/blend_fill.cpython-37.pyc | Bin 0 -> 2565 bytes .../__pycache__/blit_blends.cpython-37.pyc | Bin 0 -> 3887 bytes .../__pycache__/camera.cpython-37.pyc | Bin 0 -> 2620 bytes .../examples/__pycache__/chimp.cpython-37.pyc | Bin 0 -> 5719 bytes .../__pycache__/cursors.cpython-37.pyc | Bin 0 -> 4827 bytes .../__pycache__/dropevent.cpython-37.pyc | Bin 0 -> 1511 bytes .../__pycache__/eventlist.cpython-37.pyc | Bin 0 -> 4886 bytes .../__pycache__/font_viewer.cpython-37.pyc | Bin 0 -> 7521 bytes .../examples/__pycache__/fonty.cpython-37.pyc | Bin 0 -> 1446 bytes .../__pycache__/freetype_misc.cpython-37.pyc | Bin 0 -> 2924 bytes .../__pycache__/glcube.cpython-37.pyc | Bin 0 -> 12402 bytes .../__pycache__/go_over_there.cpython-37.pyc | Bin 0 -> 2200 bytes .../examples/__pycache__/grid.cpython-37.pyc | Bin 0 -> 2163 bytes .../headless_no_windows_needed.cpython-37.pyc | Bin 0 -> 1384 bytes .../__pycache__/joystick.cpython-37.pyc | Bin 0 -> 3155 bytes .../__pycache__/liquid.cpython-37.pyc | Bin 0 -> 1812 bytes .../examples/__pycache__/mask.cpython-37.pyc | Bin 0 -> 4685 bytes .../examples/__pycache__/midi.cpython-37.pyc | Bin 0 -> 20198 bytes .../__pycache__/moveit.cpython-37.pyc | Bin 0 -> 2764 bytes .../music_drop_fade.cpython-37.pyc | Bin 0 -> 6513 bytes .../__pycache__/pixelarray.cpython-37.pyc | Bin 0 -> 2470 bytes .../__pycache__/playmus.cpython-37.pyc | Bin 0 -> 4175 bytes .../__pycache__/resizing_new.cpython-37.pyc | Bin 0 -> 1008 bytes .../__pycache__/scaletest.cpython-37.pyc | Bin 0 -> 3277 bytes .../scrap_clipboard.cpython-37.pyc | Bin 0 -> 2569 bytes .../__pycache__/scroll.cpython-37.pyc | Bin 0 -> 4446 bytes .../__pycache__/setmodescale.cpython-37.pyc | Bin 0 -> 1806 bytes .../examples/__pycache__/sound.cpython-37.pyc | Bin 0 -> 1219 bytes .../sound_array_demos.cpython-37.pyc | Bin 0 -> 3702 bytes .../__pycache__/sprite_texture.cpython-37.pyc | Bin 0 -> 2725 bytes .../examples/__pycache__/stars.cpython-37.pyc | Bin 0 -> 2803 bytes .../__pycache__/testsprite.cpython-37.pyc | Bin 0 -> 4813 bytes .../__pycache__/textinput.cpython-37.pyc | Bin 0 -> 4928 bytes .../__pycache__/vgrade.cpython-37.pyc | Bin 0 -> 3241 bytes .../examples/__pycache__/video.cpython-37.pyc | Bin 0 -> 3243 bytes .../site-packages/pygame/examples/aacircle.py | 41 + .../site-packages/pygame/examples/aliens.py | 396 + .../pygame/examples/arraydemo.py | 120 + .../pygame/examples/audiocapture.py | 78 + .../pygame/examples/blend_fill.py | 114 + .../pygame/examples/blit_blends.py | 197 + .../site-packages/pygame/examples/camera.py | 121 + .../site-packages/pygame/examples/chimp.py | 203 + .../site-packages/pygame/examples/cursors.py | 259 + .../pygame/examples/data/BGR.png | Bin 0 -> 244 bytes .../pygame/examples/data/alien1.gif | Bin 0 -> 3826 bytes .../pygame/examples/data/alien1.jpg | Bin 0 -> 3103 bytes .../pygame/examples/data/alien1.png | Bin 0 -> 3522 bytes .../pygame/examples/data/alien2.gif | Bin 0 -> 3834 bytes .../pygame/examples/data/alien2.png | Bin 0 -> 3526 bytes .../pygame/examples/data/alien3.gif | Bin 0 -> 3829 bytes .../pygame/examples/data/alien3.png | Bin 0 -> 3518 bytes .../pygame/examples/data/arraydemo.bmp | Bin 0 -> 76854 bytes .../pygame/examples/data/asprite.bmp | Bin 0 -> 578 bytes .../pygame/examples/data/background.gif | Bin 0 -> 9133 bytes .../pygame/examples/data/black.ppm | 3076 ++++++ .../pygame/examples/data/blue.gif | Bin 0 -> 84 bytes .../pygame/examples/data/blue.mpg | Bin 0 -> 6144 bytes .../pygame/examples/data/bomb.gif | Bin 0 -> 1170 bytes .../pygame/examples/data/boom.wav | Bin 0 -> 12562 bytes .../pygame/examples/data/brick.png | Bin 0 -> 170 bytes .../pygame/examples/data/car_door.wav | Bin 0 -> 3910 bytes .../pygame/examples/data/chimp.png | Bin 0 -> 826 bytes .../pygame/examples/data/city.png | Bin 0 -> 143 bytes .../pygame/examples/data/crimson.pnm | 5 + .../pygame/examples/data/cursor.png | Bin 0 -> 2708 bytes .../pygame/examples/data/danger.gif | Bin 0 -> 2761 bytes .../pygame/examples/data/explosion1.gif | Bin 0 -> 6513 bytes .../pygame/examples/data/fist.png | Bin 0 -> 86196 bytes .../pygame/examples/data/green.pcx | Bin 0 -> 320 bytes .../pygame/examples/data/grey.pgm | 1028 ++ .../pygame/examples/data/house_lo.mp3 | Bin 0 -> 116320 bytes .../pygame/examples/data/house_lo.ogg | Bin 0 -> 31334 bytes .../pygame/examples/data/house_lo.wav | Bin 0 -> 78464 bytes .../pygame/examples/data/laplacian.png | Bin 0 -> 253 bytes .../pygame/examples/data/liquid.bmp | Bin 0 -> 11734 bytes .../pygame/examples/data/midikeys.png | Bin 0 -> 19666 bytes .../pygame/examples/data/player1.gif | Bin 0 -> 3470 bytes .../pygame/examples/data/punch.wav | Bin 0 -> 4176 bytes .../pygame/examples/data/purple.xpm | 36 + .../pygame/examples/data/red.jpg | Bin 0 -> 1251 bytes .../pygame/examples/data/sans.ttf | Bin 0 -> 133088 bytes .../pygame/examples/data/scarlet.webp | Bin 0 -> 82 bytes .../pygame/examples/data/secosmic_lo.wav | Bin 0 -> 18700 bytes .../pygame/examples/data/shot.gif | Bin 0 -> 129 bytes .../pygame/examples/data/static.png | Bin 0 -> 1202 bytes .../pygame/examples/data/teal.svg | 9 + .../pygame/examples/data/turquoise.tif | Bin 0 -> 1186 bytes .../pygame/examples/data/whiff.wav | Bin 0 -> 5850 bytes .../pygame/examples/data/yellow.tga | Bin 0 -> 3116 bytes .../pygame/examples/dropevent.py | 72 + .../pygame/examples/eventlist.py | 194 + .../pygame/examples/font_viewer.py | 281 + .../site-packages/pygame/examples/fonty.py | 81 + .../pygame/examples/freetype_misc.py | 157 + .../site-packages/pygame/examples/glcube.py | 591 ++ .../pygame/examples/go_over_there.py | 88 + .../site-packages/pygame/examples/grid.py | 64 + .../examples/headless_no_windows_needed.py | 50 + .../site-packages/pygame/examples/joystick.py | 151 + .../site-packages/pygame/examples/liquid.py | 89 + .../site-packages/pygame/examples/mask.py | 202 + .../site-packages/pygame/examples/midi.py | 880 ++ .../site-packages/pygame/examples/moveit.py | 119 + .../pygame/examples/music_drop_fade.py | 249 + .../pygame/examples/pixelarray.py | 142 + .../site-packages/pygame/examples/playmus.py | 165 + .../pygame/examples/resizing_new.py | 44 + .../pygame/examples/scaletest.py | 154 + .../pygame/examples/scrap_clipboard.py | 94 + .../site-packages/pygame/examples/scroll.py | 197 + .../pygame/examples/setmodescale.py | 67 + .../site-packages/pygame/examples/sound.py | 45 + .../pygame/examples/sound_array_demos.py | 217 + .../pygame/examples/sprite_texture.py | 110 + .../site-packages/pygame/examples/stars.py | 100 + .../pygame/examples/testsprite.py | 250 + .../pygame/examples/textinput.py | 235 + .../site-packages/pygame/examples/vgrade.py | 102 + .../site-packages/pygame/examples/video.py | 158 + .../site-packages/pygame/fastevent.py | 88 + .../site-packages/pygame/fastevent.pyi | 11 + .../font.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 67176 bytes .../python3.7/site-packages/pygame/font.pyi | 61 + .../site-packages/pygame/freesansbold.ttf | Bin 0 -> 98600 bytes .../site-packages/pygame/freetype.py | 78 + .../site-packages/pygame/freetype.pyi | 128 + .../python3.7/site-packages/pygame/ftfont.py | 203 + ...gfxdraw.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 124852 bytes .../site-packages/pygame/gfxdraw.pyi | 91 + .../image.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 71356 bytes .../python3.7/site-packages/pygame/image.pyi | 45 + ...mageext.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 56752 bytes ...oystick.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 61696 bytes .../site-packages/pygame/joystick.pyi | 35 + .../key.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 63468 bytes .../python3.7/site-packages/pygame/key.pyi | 17 + .../python3.7/site-packages/pygame/locals.py | 30 + .../python3.7/site-packages/pygame/locals.pyi | 562 ++ .../python3.7/site-packages/pygame/macosx.py | 13 + .../mask.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 106532 bytes .../python3.7/site-packages/pygame/mask.pyi | 59 + .../math.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 135288 bytes .../python3.7/site-packages/pygame/math.pyi | 342 + .../python3.7/site-packages/pygame/midi.py | 717 ++ .../python3.7/site-packages/pygame/midi.pyi | 49 + .../mixer.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 101288 bytes .../python3.7/site-packages/pygame/mixer.pyi | 98 + ...r_music.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 70420 bytes .../site-packages/pygame/mixer_music.pyi | 20 + .../mouse.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 55612 bytes .../python3.7/site-packages/pygame/mouse.pyi | 35 + ...wbuffer.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 59616 bytes ...elarray.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 94372 bytes .../site-packages/pygame/pixelarray.pyi | 41 + ...xelcopy.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 65476 bytes .../site-packages/pygame/pixelcopy.pyi | 20 + .../python3.7/site-packages/pygame/pkgdata.py | 77 + .../python3.7/site-packages/pygame/py.typed | 0 .../python3.7/site-packages/pygame/pygame.ico | Bin 0 -> 145516 bytes .../site-packages/pygame/pygame_icon.bmp | Bin 0 -> 630 bytes .../site-packages/pygame/pygame_icon.icns | Bin 0 -> 264148 bytes .../site-packages/pygame/pygame_icon_mac.bmp | Bin 0 -> 262282 bytes .../pypm.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 195580 bytes .../rect.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 101620 bytes .../python3.7/site-packages/pygame/rect.pyi | 208 + ...wobject.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 60448 bytes .../site-packages/pygame/rwobject.pyi | 18 + .../scrap.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 52916 bytes .../python3.7/site-packages/pygame/scrap.pyi | 11 + .../site-packages/pygame/sndarray.py | 139 + .../site-packages/pygame/sndarray.pyi | 12 + .../python3.7/site-packages/pygame/sprite.py | 1812 ++++ .../python3.7/site-packages/pygame/sprite.pyi | 281 + ...surface.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 345544 bytes .../site-packages/pygame/surface.pyi | 149 + .../site-packages/pygame/surfarray.py | 447 + .../site-packages/pygame/surfarray.pyi | 31 + ...urflock.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 47528 bytes .../site-packages/pygame/surflock.pyi | 2 + .../python3.7/site-packages/pygame/sysfont.py | 517 + .../site-packages/pygame/tests/__init__.py | 40 + .../site-packages/pygame/tests/__main__.py | 143 + .../tests/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1322 bytes .../tests/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 2741 bytes .../__pycache__/base_test.cpython-37.pyc | Bin 0 -> 16314 bytes .../__pycache__/blit_test.cpython-37.pyc | Bin 0 -> 4161 bytes .../bufferproxy_test.cpython-37.pyc | Bin 0 -> 12799 bytes .../__pycache__/camera_test.cpython-37.pyc | Bin 0 -> 340 bytes .../__pycache__/color_test.cpython-37.pyc | Bin 0 -> 43632 bytes .../__pycache__/constants_test.cpython-37.pyc | Bin 0 -> 7805 bytes .../controller_test.cpython-37.pyc | Bin 0 -> 10454 bytes .../__pycache__/cursors_test.cpython-37.pyc | Bin 0 -> 3524 bytes .../__pycache__/display_test.cpython-37.pyc | Bin 0 -> 29223 bytes .../__pycache__/docs_test.cpython-37.pyc | Bin 0 -> 1295 bytes .../__pycache__/draw_test.cpython-37.pyc | Bin 0 -> 151732 bytes .../__pycache__/event_test.cpython-37.pyc | Bin 0 -> 26485 bytes .../__pycache__/font_test.cpython-37.pyc | Bin 0 -> 23126 bytes .../__pycache__/freetype_tags.cpython-37.pyc | Bin 0 -> 338 bytes .../__pycache__/freetype_test.cpython-37.pyc | Bin 0 -> 38801 bytes .../__pycache__/ftfont_tags.cpython-37.pyc | Bin 0 -> 334 bytes .../__pycache__/ftfont_test.cpython-37.pyc | Bin 0 -> 530 bytes .../__pycache__/gfxdraw_test.cpython-37.pyc | Bin 0 -> 22774 bytes ...image__save_gl_surface_test.cpython-37.pyc | Bin 0 -> 1301 bytes .../__pycache__/image_tags.cpython-37.pyc | Bin 0 -> 279 bytes .../__pycache__/image_test.cpython-37.pyc | Bin 0 -> 28210 bytes .../__pycache__/imageext_tags.cpython-37.pyc | Bin 0 -> 285 bytes .../__pycache__/imageext_test.cpython-37.pyc | Bin 0 -> 3865 bytes .../__pycache__/joystick_test.cpython-37.pyc | Bin 0 -> 3693 bytes .../tests/__pycache__/key_test.cpython-37.pyc | Bin 0 -> 6320 bytes .../__pycache__/locals_test.cpython-37.pyc | Bin 0 -> 715 bytes .../__pycache__/mask_test.cpython-37.pyc | Bin 0 -> 170059 bytes .../__pycache__/math_test.cpython-37.pyc | Bin 0 -> 92549 bytes .../__pycache__/midi_test.cpython-37.pyc | Bin 0 -> 14928 bytes .../mixer_music_tags.cpython-37.pyc | Bin 0 -> 291 bytes .../mixer_music_test.cpython-37.pyc | Bin 0 -> 11722 bytes .../__pycache__/mixer_tags.cpython-37.pyc | Bin 0 -> 279 bytes .../__pycache__/mixer_test.cpython-37.pyc | Bin 0 -> 41012 bytes .../__pycache__/mouse_test.cpython-37.pyc | Bin 0 -> 8739 bytes .../pixelarray_test.cpython-37.pyc | Bin 0 -> 40812 bytes .../__pycache__/pixelcopy_test.cpython-37.pyc | Bin 0 -> 19103 bytes .../__pycache__/rect_test.cpython-37.pyc | Bin 0 -> 99168 bytes .../__pycache__/rwobject_test.cpython-37.pyc | Bin 0 -> 5213 bytes .../__pycache__/scrap_tags.cpython-37.pyc | Bin 0 -> 188 bytes .../__pycache__/scrap_test.cpython-37.pyc | Bin 0 -> 9583 bytes .../__pycache__/sndarray_tags.cpython-37.pyc | Bin 0 -> 344 bytes .../__pycache__/sndarray_test.cpython-37.pyc | Bin 0 -> 5555 bytes .../__pycache__/sprite_test.cpython-37.pyc | Bin 0 -> 37888 bytes .../__pycache__/surface_test.cpython-37.pyc | Bin 0 -> 112972 bytes .../__pycache__/surfarray_tags.cpython-37.pyc | Bin 0 -> 385 bytes .../__pycache__/surfarray_test.cpython-37.pyc | Bin 0 -> 19348 bytes .../__pycache__/surflock_test.cpython-37.pyc | Bin 0 -> 2813 bytes .../__pycache__/sysfont_test.cpython-37.pyc | Bin 0 -> 2040 bytes .../__pycache__/threads_test.cpython-37.pyc | Bin 0 -> 6863 bytes .../__pycache__/time_test.cpython-37.pyc | Bin 0 -> 8227 bytes .../__pycache__/touch_test.cpython-37.pyc | Bin 0 -> 3455 bytes .../__pycache__/transform_test.cpython-37.pyc | Bin 0 -> 31149 bytes .../__pycache__/version_test.cpython-37.pyc | Bin 0 -> 1562 bytes .../__pycache__/video_test.cpython-37.pyc | Bin 0 -> 1036 bytes .../site-packages/pygame/tests/base_test.py | 623 ++ .../site-packages/pygame/tests/blit_test.py | 153 + .../pygame/tests/bufferproxy_test.py | 504 + .../site-packages/pygame/tests/camera_test.py | 5 + .../site-packages/pygame/tests/color_test.py | 1360 +++ .../pygame/tests/constants_test.py | 426 + .../pygame/tests/controller_test.py | 357 + .../pygame/tests/cursors_test.py | 290 + .../pygame/tests/display_test.py | 1199 +++ .../site-packages/pygame/tests/docs_test.py | 35 + .../site-packages/pygame/tests/draw_test.py | 6508 +++++++++++++ .../site-packages/pygame/tests/event_test.py | 949 ++ .../tests/fixtures/fonts/A_PyGameMono-8.png | Bin 0 -> 92 bytes .../fonts/PlayfairDisplaySemibold.ttf | Bin 0 -> 236636 bytes .../fixtures/fonts/PyGameMono-18-100dpi.bdf | 165 + .../fixtures/fonts/PyGameMono-18-75dpi.bdf | 143 + .../tests/fixtures/fonts/PyGameMono-8.bdf | 103 + .../tests/fixtures/fonts/PyGameMono.otf | Bin 0 -> 3128 bytes .../tests/fixtures/fonts/test_fixed.otf | Bin 0 -> 58464 bytes .../pygame/tests/fixtures/fonts/test_sans.ttf | Bin 0 -> 133088 bytes .../fixtures/fonts/u13079_PyGameMono-8.png | Bin 0 -> 89 bytes .../fixtures/xbm_cursors/white_sizing.xbm | 8 + .../xbm_cursors/white_sizing_mask.xbm | 8 + .../site-packages/pygame/tests/font_test.py | 749 ++ .../pygame/tests/freetype_tags.py | 11 + .../pygame/tests/freetype_test.py | 1796 ++++ .../site-packages/pygame/tests/ftfont_tags.py | 11 + .../site-packages/pygame/tests/ftfont_test.py | 17 + .../pygame/tests/gfxdraw_test.py | 876 ++ .../tests/image__save_gl_surface_test.py | 46 + .../site-packages/pygame/tests/image_tags.py | 7 + .../site-packages/pygame/tests/image_test.py | 1271 +++ .../pygame/tests/imageext_tags.py | 7 + .../pygame/tests/imageext_test.py | 93 + .../pygame/tests/joystick_test.py | 166 + .../site-packages/pygame/tests/key_test.py | 306 + .../site-packages/pygame/tests/locals_test.py | 17 + .../site-packages/pygame/tests/mask_test.py | 6441 ++++++++++++ .../site-packages/pygame/tests/math_test.py | 2930 ++++++ .../site-packages/pygame/tests/midi_test.py | 463 + .../pygame/tests/mixer_music_tags.py | 7 + .../pygame/tests/mixer_music_test.py | 437 + .../site-packages/pygame/tests/mixer_tags.py | 7 + .../site-packages/pygame/tests/mixer_test.py | 1368 +++ .../site-packages/pygame/tests/mouse_test.py | 348 + .../pygame/tests/pixelarray_test.py | 1667 ++++ .../pygame/tests/pixelcopy_test.py | 710 ++ .../site-packages/pygame/tests/rect_test.py | 3313 +++++++ .../pygame/tests/run_tests__tests/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 161 bytes .../run_tests__test.cpython-37.pyc | Bin 0 -> 3335 bytes .../tests/run_tests__tests/all_ok/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 168 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1584 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1584 bytes .../__pycache__/fake_4_test.cpython-37.pyc | Bin 0 -> 1584 bytes .../__pycache__/fake_5_test.cpython-37.pyc | Bin 0 -> 1584 bytes .../__pycache__/fake_6_test.cpython-37.pyc | Bin 0 -> 1584 bytes ...rtions__ret_code_of_1__test.cpython-37.pyc | Bin 0 -> 1522 bytes .../zero_tests_test.cpython-37.pyc | Bin 0 -> 716 bytes .../run_tests__tests/all_ok/fake_2_test.py | 39 + .../run_tests__tests/all_ok/fake_3_test.py | 39 + .../run_tests__tests/all_ok/fake_4_test.py | 39 + .../run_tests__tests/all_ok/fake_5_test.py | 39 + .../run_tests__tests/all_ok/fake_6_test.py | 39 + .../no_assertions__ret_code_of_1__test.py | 39 + .../all_ok/zero_tests_test.py | 23 + .../run_tests__tests/everything/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 172 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1588 bytes .../incomplete_todo_test.cpython-37.pyc | Bin 0 -> 1617 bytes .../__pycache__/magic_tag_test.cpython-37.pyc | Bin 0 -> 1469 bytes .../__pycache__/sleep_test.cpython-37.pyc | Bin 0 -> 969 bytes .../everything/fake_2_test.py | 39 + .../everything/incomplete_todo_test.py | 39 + .../everything/magic_tag_test.py | 38 + .../run_tests__tests/everything/sleep_test.py | 29 + .../run_tests__tests/exclude/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 169 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1585 bytes .../invisible_tag_test.cpython-37.pyc | Bin 0 -> 1621 bytes .../__pycache__/magic_tag_test.cpython-37.pyc | Bin 0 -> 1466 bytes .../run_tests__tests/exclude/fake_2_test.py | 39 + .../exclude/invisible_tag_test.py | 41 + .../exclude/magic_tag_test.py | 38 + .../run_tests__tests/failures1/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 171 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1587 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1587 bytes .../__pycache__/fake_4_test.cpython-37.pyc | Bin 0 -> 1614 bytes .../run_tests__tests/failures1/fake_2_test.py | 39 + .../run_tests__tests/failures1/fake_3_test.py | 39 + .../run_tests__tests/failures1/fake_4_test.py | 41 + .../run_tests__tests/incomplete/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 172 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1603 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1588 bytes .../incomplete/fake_2_test.py | 39 + .../incomplete/fake_3_test.py | 39 + .../incomplete_todo/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 177 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1613 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1593 bytes .../incomplete_todo/fake_2_test.py | 39 + .../incomplete_todo/fake_3_test.py | 39 + .../infinite_loop/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 175 bytes .../__pycache__/fake_1_test.cpython-37.pyc | Bin 0 -> 1586 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1591 bytes .../infinite_loop/fake_1_test.py | 40 + .../infinite_loop/fake_2_test.py | 39 + .../run_tests__tests/print_stderr/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 174 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1590 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1653 bytes .../__pycache__/fake_4_test.cpython-37.pyc | Bin 0 -> 1617 bytes .../print_stderr/fake_2_test.py | 39 + .../print_stderr/fake_3_test.py | 41 + .../print_stderr/fake_4_test.py | 41 + .../run_tests__tests/print_stdout/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 174 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1590 bytes .../__pycache__/fake_3_test.cpython-37.pyc | Bin 0 -> 1712 bytes .../__pycache__/fake_4_test.cpython-37.pyc | Bin 0 -> 1617 bytes .../print_stdout/fake_2_test.py | 39 + .../print_stdout/fake_3_test.py | 42 + .../print_stdout/fake_4_test.py | 41 + .../tests/run_tests__tests/run_tests__test.py | 145 + .../run_tests__tests/timeout/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 169 bytes .../__pycache__/fake_2_test.cpython-37.pyc | Bin 0 -> 1585 bytes .../__pycache__/sleep_test.cpython-37.pyc | Bin 0 -> 966 bytes .../run_tests__tests/timeout/fake_2_test.py | 39 + .../run_tests__tests/timeout/sleep_test.py | 30 + .../pygame/tests/rwobject_test.py | 139 + .../site-packages/pygame/tests/scrap_tags.py | 26 + .../site-packages/pygame/tests/scrap_test.py | 301 + .../pygame/tests/sndarray_tags.py | 12 + .../pygame/tests/sndarray_test.py | 154 + .../site-packages/pygame/tests/sprite_test.py | 1412 +++ .../pygame/tests/surface_test.py | 4072 ++++++++ .../pygame/tests/surfarray_tags.py | 16 + .../pygame/tests/surfarray_test.py | 743 ++ .../pygame/tests/surflock_test.py | 144 + .../pygame/tests/sysfont_test.py | 51 + .../pygame/tests/test_utils/__init__.py | 201 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 5679 bytes .../__pycache__/arrinter.cpython-37.pyc | Bin 0 -> 12930 bytes .../__pycache__/async_sub.cpython-37.pyc | Bin 0 -> 7056 bytes .../__pycache__/buftools.cpython-37.pyc | Bin 0 -> 17211 bytes .../__pycache__/endian.cpython-37.pyc | Bin 0 -> 641 bytes .../test_utils/__pycache__/png.cpython-37.pyc | Bin 0 -> 123327 bytes .../__pycache__/run_tests.cpython-37.pyc | Bin 0 -> 8744 bytes .../__pycache__/test_machinery.cpython-37.pyc | Bin 0 -> 2791 bytes .../__pycache__/test_runner.cpython-37.pyc | Bin 0 -> 6826 bytes .../pygame/tests/test_utils/arrinter.py | 438 + .../pygame/tests/test_utils/async_sub.py | 301 + .../pygame/tests/test_utils/buftools.py | 606 ++ .../pygame/tests/test_utils/endian.py | 20 + .../pygame/tests/test_utils/png.py | 4005 ++++++++ .../pygame/tests/test_utils/run_tests.py | 349 + .../pygame/tests/test_utils/test_machinery.py | 89 + .../pygame/tests/test_utils/test_runner.py | 324 + .../pygame/tests/threads_test.py | 238 + .../site-packages/pygame/tests/time_test.py | 410 + .../site-packages/pygame/tests/touch_test.py | 97 + .../pygame/tests/transform_test.py | 1420 +++ .../pygame/tests/version_test.py | 48 + .../site-packages/pygame/tests/video_test.py | 26 + .../site-packages/pygame/threads/__init__.py | 271 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6440 bytes .../time.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 59812 bytes .../python3.7/site-packages/pygame/time.pyi | 15 + ...ansform.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 125652 bytes .../site-packages/pygame/transform.pyi | 58 + .../python3.7/site-packages/pygame/version.py | 72 + .../site-packages/pygame/version.pyi | 23 + .../python_dateutil-2.8.2.dist-info/INSTALLER | 1 + .../python_dateutil-2.8.2.dist-info/LICENSE | 54 + .../python_dateutil-2.8.2.dist-info/METADATA | 204 + .../python_dateutil-2.8.2.dist-info/RECORD | 44 + .../python_dateutil-2.8.2.dist-info/WHEEL | 6 + .../top_level.txt | 1 + .../python_dateutil-2.8.2.dist-info/zip-safe | 1 + .../requests-2.31.0.dist-info/INSTALLER | 1 + .../requests-2.31.0.dist-info/LICENSE | 175 + .../requests-2.31.0.dist-info/METADATA | 122 + .../requests-2.31.0.dist-info/RECORD | 42 + .../requests-2.31.0.dist-info/WHEEL | 5 + .../requests-2.31.0.dist-info/top_level.txt | 1 + .../site-packages/requests/__init__.py | 180 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3817 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 0 -> 500 bytes .../_internal_utils.cpython-37.pyc | Bin 0 -> 1579 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 0 -> 16069 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 0 -> 6709 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 0 -> 8315 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 0 -> 571 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 1474 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 0 -> 18717 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 6325 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 0 -> 2759 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 930 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 24422 bytes .../__pycache__/packages.cpython-37.pyc | Bin 0 -> 675 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 19563 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 4177 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 4352 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 24046 bytes .../site-packages/requests/__version__.py | 14 + .../site-packages/requests/_internal_utils.py | 50 + .../site-packages/requests/adapters.py | 538 ++ .../python3.7/site-packages/requests/api.py | 157 + .../python3.7/site-packages/requests/auth.py | 315 + .../python3.7/site-packages/requests/certs.py | 17 + .../site-packages/requests/compat.py | 79 + .../site-packages/requests/cookies.py | 561 ++ .../site-packages/requests/exceptions.py | 141 + .../python3.7/site-packages/requests/help.py | 134 + .../python3.7/site-packages/requests/hooks.py | 33 + .../site-packages/requests/models.py | 1034 ++ .../site-packages/requests/packages.py | 28 + .../site-packages/requests/sessions.py | 833 ++ .../site-packages/requests/status_codes.py | 128 + .../site-packages/requests/structures.py | 99 + .../python3.7/site-packages/requests/utils.py | 1094 +++ .../setuptools-40.8.0.dist-info/AUTHORS.txt | 421 + .../setuptools-40.8.0.dist-info/INSTALLER | 1 + .../setuptools-40.8.0.dist-info/LICENSE.txt | 20 + .../setuptools-40.8.0.dist-info/METADATA | 69 + .../setuptools-40.8.0.dist-info/RECORD | 155 + .../setuptools-40.8.0.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 64 + .../setuptools-40.8.0.dist-info/top_level.txt | 3 + .../setuptools-40.8.0.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 228 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 7658 bytes .../_deprecation_warning.cpython-37.pyc | Bin 0 -> 512 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5093 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 7720 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 17655 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 819 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5228 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 42184 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1939 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1504 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3714 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 818 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2397 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4598 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34395 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3576 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32669 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7166 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 775 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1161 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1384 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15500 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1466 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6756 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1460 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 292 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 6945 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 975 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 154 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 202997 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24355 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 690 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 528 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 980 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2832 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8837 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3839 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19758 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 459 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10525 bytes .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 + .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 ++ .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/build_meta.py | 231 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 700 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2368 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14156 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1747 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 938 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2417 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9671 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8547 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6428 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1343 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 66103 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21654 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 3975 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2875 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 5033 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2255 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4588 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 745 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2494 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 889 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6747 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4487 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8082 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 5153 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6098 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 502 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 321 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 221 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2397 +++++ .../setuptools/command/egg_info.py | 717 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 82 + .../setuptools/command/install_lib.py | 148 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 221 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 196 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 656 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/dist.py | 1285 +++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2377 bytes .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1301 +++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1136 +++ .../site-packages/setuptools/pep425tags.py | 319 + .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 55 + .../site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 260 + .../site-packages/setuptools/unicode_utils.py | 57 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 211 + .../setuptools/windows_support.py | 29 + .../six-1.16.0.dist-info/INSTALLER | 1 + .../six-1.16.0.dist-info/LICENSE | 18 + .../six-1.16.0.dist-info/METADATA | 49 + .../site-packages/six-1.16.0.dist-info/RECORD | 8 + .../site-packages/six-1.16.0.dist-info/WHEEL | 6 + .../six-1.16.0.dist-info/top_level.txt | 1 + .venv/lib/python3.7/site-packages/six.py | 998 ++ .../INSTALLER | 1 + .../typing_extensions-4.7.1.dist-info/LICENSE | 279 + .../METADATA | 69 + .../typing_extensions-4.7.1.dist-info/RECORD | 7 + .../typing_extensions-4.7.1.dist-info/WHEEL | 4 + .../site-packages/typing_extensions.py | 3072 ++++++ .../urllib3-2.0.3.dist-info/INSTALLER | 1 + .../urllib3-2.0.3.dist-info/METADATA | 158 + .../urllib3-2.0.3.dist-info/RECORD | 70 + .../urllib3-2.0.3.dist-info/WHEEL | 4 + .../licenses/LICENSE.txt | 21 + .../site-packages/urllib3/__init__.py | 165 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4061 bytes .../_base_connection.cpython-37.pyc | Bin 0 -> 5564 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 14521 bytes .../_request_methods.cpython-37.pyc | Bin 0 -> 6658 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 212 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 20869 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 0 -> 28464 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 13941 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 0 -> 9826 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 0 -> 2268 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 0 -> 17711 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 30350 bytes .../site-packages/urllib3/_base_connection.py | 173 + .../site-packages/urllib3/_collections.py | 434 + .../site-packages/urllib3/_request_methods.py | 217 + .../site-packages/urllib3/_version.py | 4 + .../site-packages/urllib3/connection.py | 899 ++ .../site-packages/urllib3/connectionpool.py | 1178 +++ .../site-packages/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 148 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 0 -> 16938 bytes .../securetransport.cpython-37.pyc | Bin 0 -> 21382 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 0 -> 6094 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 165 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 0 -> 7646 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 0 -> 11212 bytes .../contrib/_securetransport/bindings.py | 430 + .../contrib/_securetransport/low_level.py | 474 + .../urllib3/contrib/pyopenssl.py | 557 ++ .../urllib3/contrib/securetransport.py | 913 ++ .../site-packages/urllib3/contrib/socks.py | 233 + .../site-packages/urllib3/exceptions.py | 318 + .../python3.7/site-packages/urllib3/fields.py | 345 + .../site-packages/urllib3/filepost.py | 89 + .../site-packages/urllib3/poolmanager.py | 634 ++ .../python3.7/site-packages/urllib3/py.typed | 2 + .../site-packages/urllib3/response.py | 1136 +++ .../site-packages/urllib3/util/__init__.py | 44 + .../util/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 962 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 3369 bytes .../util/__pycache__/proxy.cpython-37.pyc | Bin 0 -> 1012 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 0 -> 6051 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 0 -> 2252 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 0 -> 15125 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 0 -> 11790 bytes .../ssl_match_hostname.cpython-37.pyc | Bin 0 -> 3602 bytes .../__pycache__/ssltransport.cpython-37.pyc | Bin 0 -> 9127 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 0 -> 9626 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 0 -> 10960 bytes .../util/__pycache__/util.cpython-37.pyc | Bin 0 -> 1233 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 0 -> 2389 bytes .../site-packages/urllib3/util/connection.py | 137 + .../site-packages/urllib3/util/proxy.py | 43 + .../site-packages/urllib3/util/request.py | 256 + .../site-packages/urllib3/util/response.py | 101 + .../site-packages/urllib3/util/retry.py | 529 + .../site-packages/urllib3/util/ssl_.py | 510 + .../urllib3/util/ssl_match_hostname.py | 159 + .../urllib3/util/ssltransport.py | 280 + .../site-packages/urllib3/util/timeout.py | 279 + .../site-packages/urllib3/util/url.py | 471 + .../site-packages/urllib3/util/util.py | 42 + .../site-packages/urllib3/util/wait.py | 124 + .../site-packages/webdav3/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 146 bytes .../webdav3/__pycache__/client.cpython-37.pyc | Bin 0 -> 54188 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 2116 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5386 bytes .../webdav3/__pycache__/urn.cpython-37.pyc | Bin 0 -> 2400 bytes .../python3.7/site-packages/webdav3/client.py | 1253 +++ .../site-packages/webdav3/connection.py | 73 + .../site-packages/webdav3/exceptions.py | 102 + .../python3.7/site-packages/webdav3/urn.py | 59 + .../DESCRIPTION.rst | 355 + .../webdavclient3-3.14.6.dist-info/INSTALLER | 1 + .../webdavclient3-3.14.6.dist-info/METADATA | 384 + .../webdavclient3-3.14.6.dist-info/RECORD | 18 + .../webdavclient3-3.14.6.dist-info/WHEEL | 5 + .../metadata.json | 1 + .../top_level.txt | 1 + .../yarl-1.9.4.dist-info/INSTALLER | 1 + .../yarl-1.9.4.dist-info/LICENSE | 202 + .../yarl-1.9.4.dist-info/METADATA | 1086 +++ .../site-packages/yarl-1.9.4.dist-info/NOTICE | 13 + .../site-packages/yarl-1.9.4.dist-info/RECORD | 20 + .../site-packages/yarl-1.9.4.dist-info/WHEEL | 5 + .../yarl-1.9.4.dist-info/top_level.txt | 1 + .../python3.7/site-packages/yarl/__init__.py | 5 + .../python3.7/site-packages/yarl/__init__.pyi | 121 + .../yarl/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 276 bytes .../yarl/__pycache__/_quoting.cpython-37.pyc | Bin 0 -> 470 bytes .../__pycache__/_quoting_py.cpython-37.pyc | Bin 0 -> 4311 bytes .../yarl/__pycache__/_url.cpython-37.pyc | Bin 0 -> 29085 bytes .../python3.7/site-packages/yarl/_quoting.py | 18 + ...oting_c.cpython-37m-arm-linux-gnueabihf.so | Bin 0 -> 225484 bytes .../site-packages/yarl/_quoting_c.pyi | 16 + .../site-packages/yarl/_quoting_c.pyx | 371 + .../site-packages/yarl/_quoting_py.py | 197 + .../lib/python3.7/site-packages/yarl/_url.py | 1200 +++ .../lib/python3.7/site-packages/yarl/py.typed | 1 + .../zipp-3.15.0.dist-info/INSTALLER | 1 + .../zipp-3.15.0.dist-info/LICENSE | 19 + .../zipp-3.15.0.dist-info/METADATA | 106 + .../zipp-3.15.0.dist-info/RECORD | 10 + .../site-packages/zipp-3.15.0.dist-info/WHEEL | 5 + .../zipp-3.15.0.dist-info/top_level.txt | 1 + .../python3.7/site-packages/zipp/__init__.py | 402 + .../zipp/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 12904 bytes .../__pycache__/py310compat.cpython-37.pyc | Bin 0 -> 392 bytes .../site-packages/zipp/py310compat.py | 12 + .venv/pyvenv.cfg | 3 + .../CacheControl-0.11.7-py2.py3-none-any.whl | Bin 0 -> 25197 bytes .../appdirs-1.4.3-py2.py3-none-any.whl | Bin 0 -> 16543 bytes .../certifi-2018.8.24-py2.py3-none-any.whl | Bin 0 -> 152671 bytes .../chardet-3.0.4-py2.py3-none-any.whl | Bin 0 -> 139269 bytes .../colorama-0.3.7-py2.py3-none-any.whl | Bin 0 -> 22127 bytes .../distlib-0.2.8-py2.py3-none-any.whl | Bin 0 -> 149379 bytes .../distro-1.3.0-py2.py3-none-any.whl | Bin 0 -> 19446 bytes .../html5lib-1.0.1-py2.py3-none-any.whl | Bin 0 -> 117801 bytes .../idna-2.6-py2.py3-none-any.whl | Bin 0 -> 60445 bytes .../ipaddress-0.0.0-py2.py3-none-any.whl | Bin 0 -> 24530 bytes .../lockfile-0.12.2-py2.py3-none-any.whl | Bin 0 -> 19752 bytes .../packaging-19.0-py2.py3-none-any.whl | Bin 0 -> 29100 bytes .../pip-18.1-py2.py3-none-any.whl | Bin 0 -> 198470 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 0 -> 124652 bytes .../progress-1.2-py2.py3-none-any.whl | Bin 0 -> 15676 bytes .../pyparsing-2.2.0-py2.py3-none-any.whl | Bin 0 -> 63423 bytes .../pytoml-0.1.2-py2.py3-none-any.whl | Bin 0 -> 13896 bytes .../requests-2.21.0-py2.py3-none-any.whl | Bin 0 -> 65295 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 0 -> 14137 bytes .../setuptools-40.8.0-py2.py3-none-any.whl | Bin 0 -> 468153 bytes .../six-1.12.0-py2.py3-none-any.whl | Bin 0 -> 17683 bytes .../urllib3-1.24.1-py2.py3-none-any.whl | Bin 0 -> 117484 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 0 -> 18263 bytes .../wheel-0.32.3-py2.py3-none-any.whl | Bin 0 -> 28504 bytes Artal.png | Bin 0 -> 83750 bytes __pycache__/uploader.cpython-37.pyc | Bin 0 -> 1026 bytes .../wled_controller_async.cpython-37.pyc | Bin 0 -> 1720 bytes _fotobox.py | 151 + fotobox.py | 283 +- fotobox_fix_teest.py | 240 - logo.png | Bin 0 -> 83750 bytes main.py | 46 +- qr.png | Bin 0 -> 92403 bytes qr_small.bmp | Bin 0 -> 12845754 bytes qr_small.png | Bin 0 -> 33227 bytes uploader.pyc | Bin 0 -> 1298 bytes venv/bin/activate | 76 + venv/bin/activate.csh | 37 + venv/bin/activate.fish | 75 + venv/bin/easy_install | 10 + venv/bin/easy_install-3.7 | 10 + venv/bin/pip | 10 + venv/bin/pip3 | 10 + venv/bin/pip3.7 | 10 + venv/bin/python | 1 + venv/bin/python3 | 1 + .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 281 bytes .../python3.7/site-packages/easy_install.py | 5 + .../pip-18.1.dist-info/INSTALLER | 1 + .../pip-18.1.dist-info/LICENSE.txt | 20 + .../site-packages/pip-18.1.dist-info/METADATA | 70 + .../site-packages/pip-18.1.dist-info/RECORD | 172 + .../site-packages/pip-18.1.dist-info/WHEEL | 6 + .../pip-18.1.dist-info/entry_points.txt | 5 + .../pip-18.1.dist-info/top_level.txt | 1 + .../python3.7/site-packages/pip/__init__.py | 1 + .../python3.7/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 152 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 406 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1798 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 5007 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 6792 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9791 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 20859 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 11512 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 23133 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4188 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7247 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 0 -> 2671 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 8438 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 20800 bytes .../site-packages/pip/_internal/build_env.py | 142 + .../site-packages/pip/_internal/cache.py | 202 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 229 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 0 -> 5042 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 0 -> 6267 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 14988 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 0 -> 2189 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 0 -> 8893 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 358 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 278 + .../pip/_internal/cli/cmdoptions.py | 714 ++ .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2457 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1259 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3031 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6383 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 4611 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2827 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2021 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1197 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 12175 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8870 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4263 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5844 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2653 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 4874 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 174 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 555 ++ .../pip/_internal/commands/list.py | 306 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 921 ++ .../site-packages/pip/_internal/exceptions.py | 268 + .../site-packages/pip/_internal/index.py | 899 ++ .../site-packages/pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 0 -> 1052 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 0 -> 2387 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 1121 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 0 -> 4719 bytes .../pip/_internal/models/candidate.py | 23 + .../pip/_internal/models/format_control.py | 62 + .../pip/_internal/models/index.py | 29 + .../pip/_internal/models/link.py | 141 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 153 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3330 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 6285 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 9151 bytes .../pip/_internal/operations/check.py | 148 + .../pip/_internal/operations/freeze.py | 264 + .../pip/_internal/operations/prepare.py | 355 + .../site-packages/pip/_internal/pep425tags.py | 317 + .../site-packages/pip/_internal/pyproject.py | 144 + .../pip/_internal/req/__init__.py | 69 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1521 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 0 -> 6919 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 8620 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 22770 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 5734 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 2845 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 12817 bytes .../pip/_internal/req/constructors.py | 298 + .../pip/_internal/req/req_file.py | 340 + .../pip/_internal/req/req_install.py | 860 ++ .../pip/_internal/req/req_set.py | 181 + .../pip/_internal/req/req_tracker.py | 76 + .../pip/_internal/req/req_uninstall.py | 460 + .../site-packages/pip/_internal/resolve.py | 353 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 148 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 7869 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 0 -> 5939 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2522 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1084 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 615 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1506 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3283 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 5316 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 24407 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 0 -> 1897 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 3869 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2348 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 343 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 2760 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1292 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 11817 bytes .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/compat.py | 248 + .../pip/_internal/utils/deprecation.py | 89 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 225 + .../site-packages/pip/_internal/utils/misc.py | 958 ++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 154 + .../pip/_internal/utils/packaging.py | 75 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 509 + .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15514 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3777 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 9082 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3750 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 6352 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 346 + .../pip/_internal/vcs/mercurial.py | 101 + .../pip/_internal/vcs/subversion.py | 213 + .../site-packages/pip/_internal/wheel.py | 831 ++ .../site-packages/pip/_vendor/__init__.py | 114 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2874 bytes .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 237 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 0 -> 5302 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 0 -> 4701 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 0 -> 2866 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 0 -> 975 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 0 -> 4132 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 4699 bytes .../pip/_vendor/pep517/_in_process.py | 182 + .../site-packages/pip/_vendor/pep517/check.py | 194 + .../pip/_vendor/pep517/colorlog.py | 110 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 150 + .../pip/_vendor/pep517/wrappers.py | 134 + .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 421 + .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 + .../pkg_resources-0.0.0.dist-info/LICENSE.txt | 20 + .../pkg_resources-0.0.0.dist-info/METADATA | 13 + .../pkg_resources-0.0.0.dist-info/RECORD | 38 + .../pkg_resources-0.0.0.dist-info/WHEEL | 6 + .../site-packages/pkg_resources/__init__.py | 3236 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 98524 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 597 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 160 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20648 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203003 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24361 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 696 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 534 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 986 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2838 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8846 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3851 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19764 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 465 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10531 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2379 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../setuptools-40.8.0.dist-info/AUTHORS.txt | 421 + .../setuptools-40.8.0.dist-info/INSTALLER | 1 + .../setuptools-40.8.0.dist-info/LICENSE.txt | 20 + .../setuptools-40.8.0.dist-info/METADATA | 69 + .../setuptools-40.8.0.dist-info/RECORD | 155 + .../setuptools-40.8.0.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 64 + .../setuptools-40.8.0.dist-info/top_level.txt | 3 + .../setuptools-40.8.0.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 228 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 7658 bytes .../_deprecation_warning.cpython-37.pyc | Bin 0 -> 512 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5093 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 7720 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 17655 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 819 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5228 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 42184 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1939 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1504 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3714 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 818 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2397 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4598 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34395 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3576 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32669 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7166 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 775 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1161 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1384 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15500 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1466 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6756 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1460 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 292 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 6945 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 975 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 154 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 202997 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24355 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 690 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 528 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 980 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2832 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8837 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3839 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19758 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 459 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10525 bytes .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 + .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 ++ .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/build_meta.py | 231 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 700 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2368 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14156 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1747 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 938 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2417 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9671 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8547 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6428 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1343 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 66103 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21654 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 3975 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2875 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 5033 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2255 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4588 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 745 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2494 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 889 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6747 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4487 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8082 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 5153 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6098 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 502 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 321 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 221 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2397 +++++ .../setuptools/command/egg_info.py | 717 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 82 + .../setuptools/command/install_lib.py | 148 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 221 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 196 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 656 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/dist.py | 1285 +++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2377 bytes .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1301 +++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1136 +++ .../site-packages/setuptools/pep425tags.py | 319 + .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 55 + .../site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 260 + .../site-packages/setuptools/unicode_utils.py | 57 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 211 + .../setuptools/windows_support.py | 29 + venv/pyvenv.cfg | 3 + .../CacheControl-0.11.7-py2.py3-none-any.whl | Bin 0 -> 25197 bytes .../appdirs-1.4.3-py2.py3-none-any.whl | Bin 0 -> 16543 bytes .../certifi-2018.8.24-py2.py3-none-any.whl | Bin 0 -> 152671 bytes .../chardet-3.0.4-py2.py3-none-any.whl | Bin 0 -> 139269 bytes .../colorama-0.3.7-py2.py3-none-any.whl | Bin 0 -> 22127 bytes .../distlib-0.2.8-py2.py3-none-any.whl | Bin 0 -> 149379 bytes .../distro-1.3.0-py2.py3-none-any.whl | Bin 0 -> 19446 bytes .../html5lib-1.0.1-py2.py3-none-any.whl | Bin 0 -> 117801 bytes .../idna-2.6-py2.py3-none-any.whl | Bin 0 -> 60445 bytes .../ipaddress-0.0.0-py2.py3-none-any.whl | Bin 0 -> 24530 bytes .../lockfile-0.12.2-py2.py3-none-any.whl | Bin 0 -> 19752 bytes .../packaging-19.0-py2.py3-none-any.whl | Bin 0 -> 29100 bytes .../pip-18.1-py2.py3-none-any.whl | Bin 0 -> 198470 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 0 -> 124652 bytes .../progress-1.2-py2.py3-none-any.whl | Bin 0 -> 15676 bytes .../pyparsing-2.2.0-py2.py3-none-any.whl | Bin 0 -> 63423 bytes .../pytoml-0.1.2-py2.py3-none-any.whl | Bin 0 -> 13896 bytes .../requests-2.21.0-py2.py3-none-any.whl | Bin 0 -> 65295 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 0 -> 14137 bytes .../setuptools-40.8.0-py2.py3-none-any.whl | Bin 0 -> 468153 bytes .../six-1.12.0-py2.py3-none-any.whl | Bin 0 -> 17683 bytes .../urllib3-1.24.1-py2.py3-none-any.whl | Bin 0 -> 117484 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 0 -> 18263 bytes .../wheel-0.32.3-py2.py3-none-any.whl | Bin 0 -> 28504 bytes wled_controller_async.py | 34 + 2333 files changed, 409208 insertions(+), 341 deletions(-) create mode 100644 .DS_Store create mode 100644 .idea/.gitignore create mode 100644 .idea/fotobox.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .venv/bin/activate create mode 100644 .venv/bin/activate.csh create mode 100644 .venv/bin/activate.fish create mode 100755 .venv/bin/easy_install create mode 100755 .venv/bin/easy_install-3.7 create mode 100755 .venv/bin/normalizer create mode 100755 .venv/bin/pinout create mode 100755 .venv/bin/pip create mode 100755 .venv/bin/pip3 create mode 100755 .venv/bin/pip3.7 create mode 120000 .venv/bin/python create mode 120000 .venv/bin/python3 create mode 100755 .venv/bin/wdc create mode 100644 .venv/include/site/python3.7/pygame/_blit_info.h create mode 100644 .venv/include/site/python3.7/pygame/_camera.h create mode 100644 .venv/include/site/python3.7/pygame/_pygame.h create mode 100644 .venv/include/site/python3.7/pygame/_surface.h create mode 100644 .venv/include/site/python3.7/pygame/camera.h create mode 100644 .venv/include/site/python3.7/pygame/font.h create mode 100644 .venv/include/site/python3.7/pygame/freetype.h create mode 100644 .venv/include/site/python3.7/pygame/include/_pygame.h create mode 100644 .venv/include/site/python3.7/pygame/include/bitmask.h create mode 100644 .venv/include/site/python3.7/pygame/include/pgcompat.h create mode 100644 .venv/include/site/python3.7/pygame/include/pgimport.h create mode 100644 .venv/include/site/python3.7/pygame/include/pgplatform.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame_bufferproxy.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame_font.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame_freetype.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame_mask.h create mode 100644 .venv/include/site/python3.7/pygame/include/pygame_mixer.h create mode 100644 .venv/include/site/python3.7/pygame/include/sse2neon.h create mode 100644 .venv/include/site/python3.7/pygame/mask.h create mode 100644 .venv/include/site/python3.7/pygame/mixer.h create mode 100644 .venv/include/site/python3.7/pygame/palette.h create mode 100644 .venv/include/site/python3.7/pygame/pgarrinter.h create mode 100644 .venv/include/site/python3.7/pygame/pgbufferproxy.h create mode 100644 .venv/include/site/python3.7/pygame/pgcompat.h create mode 100644 .venv/include/site/python3.7/pygame/pgopengl.h create mode 100644 .venv/include/site/python3.7/pygame/pgplatform.h create mode 100644 .venv/include/site/python3.7/pygame/pygame.h create mode 100644 .venv/include/site/python3.7/pygame/scrap.h create mode 100644 .venv/include/site/python3.7/pygame/simd_blitters.h create mode 100644 .venv/include/site/python3.7/pygame/surface.h create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/LICENCE.txt create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/RPi/GPIO/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/RPi/GPIO/__pycache__/__init__.cpython-37.pyc create mode 100755 .venv/lib/python3.7/site-packages/RPi/_GPIO.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/RPi/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/RPi/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_cparser.pxd.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_find_header.pxd.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyi.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyx.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_http_parser.pyx.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_http_writer.pyx.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/_websocket.pyx.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/.hash/hdrs.py.hash create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/abc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/base_protocol.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/client.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_proto.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_reqrep.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_ws.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/connector.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/cookiejar.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/formdata.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/hdrs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/helpers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/http.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_parser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_websocket.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_writer.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/locks.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/log.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/multipart.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload_streamer.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/pytest_plugin.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/resolver.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/streams.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/tcp_helpers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/test_utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/tracing.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/typedefs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_app.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_fileresponse.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_log.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_middlewares.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_protocol.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_request.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_response.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_routedef.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_runner.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_server.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_urldispatcher.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_ws.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/__pycache__/worker.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_cparser.pxd create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_find_header.pxd create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_headers.pxi create mode 100755 .venv/lib/python3.7/site-packages/aiohttp/_helpers.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_helpers.pyi create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_helpers.pyx create mode 100755 .venv/lib/python3.7/site-packages/aiohttp/_http_parser.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_http_parser.pyx create mode 100755 .venv/lib/python3.7/site-packages/aiohttp/_http_writer.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_http_writer.pyx create mode 100755 .venv/lib/python3.7/site-packages/aiohttp/_websocket.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/_websocket.pyx create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/abc.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/base_protocol.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/client.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/client_exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/client_proto.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/client_reqrep.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/client_ws.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/connector.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/cookiejar.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/formdata.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/hdrs.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/helpers.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/http.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/http_exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/http_parser.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/http_websocket.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/http_writer.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/locks.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/log.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/multipart.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/payload.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/payload_streamer.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/py.typed create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/pytest_plugin.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/resolver.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/streams.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/tcp_helpers.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/test_utils.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/tracing.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/typedefs.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_app.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_fileresponse.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_log.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_middlewares.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_protocol.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_request.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_response.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_routedef.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_runner.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_server.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/web_ws.py create mode 100644 .venv/lib/python3.7/site-packages/aiohttp/worker.py create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/aiosignal/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/aiosignal/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/aiosignal/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/aiosignal/py.typed create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/zip-safe create mode 100644 .venv/lib/python3.7/site-packages/async_timeout/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/async_timeout/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/async_timeout/py.typed create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/LICENSE.md create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/zip-safe create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/_fail_on.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/case.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/helpers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/mock.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/__pycache__/selector.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/asynctest/_fail_on.py create mode 100644 .venv/lib/python3.7/site-packages/asynctest/case.py create mode 100644 .venv/lib/python3.7/site-packages/asynctest/helpers.py create mode 100644 .venv/lib/python3.7/site-packages/asynctest/mock.py create mode 100644 .venv/lib/python3.7/site-packages/asynctest/selector.py create mode 100644 .venv/lib/python3.7/site-packages/attr/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/attr/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_cmp.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_config.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_funcs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_make.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_next_gen.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/_version_info.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/converters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/filters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/setters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/__pycache__/validators.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attr/_cmp.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_cmp.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/_compat.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_config.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_funcs.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_make.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_next_gen.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_typing_compat.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/_version_info.py create mode 100644 .venv/lib/python3.7/site-packages/attr/_version_info.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/converters.py create mode 100644 .venv/lib/python3.7/site-packages/attr/converters.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/attr/exceptions.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/filters.py create mode 100644 .venv/lib/python3.7/site-packages/attr/filters.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/py.typed create mode 100644 .venv/lib/python3.7/site-packages/attr/setters.py create mode 100644 .venv/lib/python3.7/site-packages/attr/setters.pyi create mode 100644 .venv/lib/python3.7/site-packages/attr/validators.py create mode 100644 .venv/lib/python3.7/site-packages/attr/validators.pyi create mode 100644 .venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/licenses/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/attrs/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/attrs/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/converters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/filters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/setters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/__pycache__/validators.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/attrs/converters.py create mode 100644 .venv/lib/python3.7/site-packages/attrs/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/attrs/filters.py create mode 100644 .venv/lib/python3.7/site-packages/attrs/py.typed create mode 100644 .venv/lib/python3.7/site-packages/attrs/setters.py create mode 100644 .venv/lib/python3.7/site-packages/attrs/validators.py create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/certifi/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/certifi/__main__.py create mode 100644 .venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/certifi/__pycache__/__main__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/certifi/cacert.pem create mode 100644 .venv/lib/python3.7/site-packages/certifi/core.py create mode 100644 .venv/lib/python3.7/site-packages/certifi/py.typed create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/cd.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/constant.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/legacy.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/md.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/api.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/cd.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/normalizer.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/constant.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/legacy.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/md.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/models.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/py.typed create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/utils.py create mode 100644 .venv/lib/python3.7/site-packages/charset_normalizer/version.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/attr.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/color.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/conversions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/deltae.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/easings.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/tables.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/__pycache__/types.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/colorzero/attr.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/color.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/conversions.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/deltae.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/easings.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/tables.py create mode 100644 .venv/lib/python3.7/site-packages/colorzero/types.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/_common.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/_version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/easter.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/relativedelta.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/rrule.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/tzwin.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/__pycache__/utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/_common.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/_version.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/easter.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/_parser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/isoparser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/_parser.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/parser/isoparser.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/relativedelta.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/rrule.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_common.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_factories.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/tz.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/win.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/_common.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/_factories.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/tz.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tz/win.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/tzwin.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/utils.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/zoneinfo/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/rebuild.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz create mode 100644 .venv/lib/python3.7/site-packages/dateutil/zoneinfo/rebuild.py create mode 100644 .venv/lib/python3.7/site-packages/easy_install.py create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/frozenlist/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/frozenlist/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/frozenlist/__pycache__/__init__.cpython-37.pyc create mode 100755 .venv/lib/python3.7/site-packages/frozenlist/_frozenlist.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/frozenlist/_frozenlist.pyx create mode 100644 .venv/lib/python3.7/site-packages/frozenlist/py.typed create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/LICENSE.rst create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/boards.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/devices.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/exc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/fonts.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/input_devices.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/internal_devices.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/mixins.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/output_devices.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/spi_devices.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/threads.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/tones.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/__pycache__/tools.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/boards.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/compat.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/devices.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/exc.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/fonts.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/fonts/14seg.txt create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/fonts/7seg.txt create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/input_devices.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/internal_devices.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/mixins.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/output_devices.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/data.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/lgpio.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/local.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/mock.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/native.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/pi.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/pigpio.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/rpigpio.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/rpio.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/spi.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/data.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/lgpio.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/local.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/mock.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/native.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/pi.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/pigpio.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/rpigpio.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/rpio.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/pins/spi.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/spi_devices.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/threads.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/tones.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozero/tools.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozerocli/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/pinout.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/gpiozerocli/pinout.py create mode 100644 .venv/lib/python3.7/site-packages/idna-3.4.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/idna-3.4.dist-info/LICENSE.md create mode 100644 .venv/lib/python3.7/site-packages/idna-3.4.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/idna-3.4.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/idna-3.4.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/idna/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/codec.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/core.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/idnadata.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/intranges.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/package_data.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/__pycache__/uts46data.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/idna/codec.py create mode 100644 .venv/lib/python3.7/site-packages/idna/compat.py create mode 100644 .venv/lib/python3.7/site-packages/idna/core.py create mode 100644 .venv/lib/python3.7/site-packages/idna/idnadata.py create mode 100644 .venv/lib/python3.7/site-packages/idna/intranges.py create mode 100644 .venv/lib/python3.7/site-packages/idna/package_data.py create mode 100644 .venv/lib/python3.7/site-packages/idna/py.typed create mode 100644 .venv/lib/python3.7/site-packages/idna/uts46data.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_adapters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_collections.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_functools.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_itertools.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_meta.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_py39compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_text.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_adapters.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_collections.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_compat.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_functools.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_itertools.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_meta.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_py39compat.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/_text.py create mode 100644 .venv/lib/python3.7/site-packages/importlib_metadata/py.typed create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSES.txt create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/lxml/ElementInclude.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/ElementInclude.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/_elementpath.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/builder.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/cssselect.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/doctestcompare.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/pyclasslookup.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/sax.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/__pycache__/usedoctest.cpython-37.pyc create mode 100755 .venv/lib/python3.7/site-packages/lxml/_elementpath.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/_elementpath.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/apihelpers.pxi create mode 100755 .venv/lib/python3.7/site-packages/lxml/builder.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/builder.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/classlookup.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/cleanup.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/cssselect.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/debug.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/docloader.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/doctestcompare.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/dtd.pxi create mode 100755 .venv/lib/python3.7/site-packages/lxml/etree.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/etree.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/etree.pyx create mode 100644 .venv/lib/python3.7/site-packages/lxml/etree_api.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/extensions.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/ElementSoup.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/ElementSoup.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/_diffcommand.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/_html5builder.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/_setmixin.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/builder.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/clean.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/defs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/diff.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/formfill.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/html5parser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/soupparser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/__pycache__/usedoctest.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/_diffcommand.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/_html5builder.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/_setmixin.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/builder.py create mode 100755 .venv/lib/python3.7/site-packages/lxml/html/clean.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/clean.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/defs.py create mode 100755 .venv/lib/python3.7/site-packages/lxml/html/diff.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/diff.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/formfill.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/html5parser.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/soupparser.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/html/usedoctest.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/__init__.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/c14n.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/config.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/dtdvalid.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/etree_defs.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/etreepublic.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/htmlparser.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/lxml-version.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/relaxng.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/schematron.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/tree.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/uri.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xinclude.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xmlerror.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xmlparser.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xmlschema.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xpath.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/includes/xslt.pxd create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/rng/iso-schematron.rng create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_abstract_expand.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_dsdl_include.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_message.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_skeleton_for_xslt1.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_svrl_for_xslt1.xsl create mode 100644 .venv/lib/python3.7/site-packages/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt create mode 100644 .venv/lib/python3.7/site-packages/lxml/iterparse.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/lxml.etree.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/lxml.etree_api.h create mode 100644 .venv/lib/python3.7/site-packages/lxml/nsclasses.pxi create mode 100755 .venv/lib/python3.7/site-packages/lxml/objectify.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/objectify.pyx create mode 100644 .venv/lib/python3.7/site-packages/lxml/objectpath.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/parser.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/parsertarget.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/proxy.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/public-api.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/pyclasslookup.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/readonlytree.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/relaxng.pxi create mode 100755 .venv/lib/python3.7/site-packages/lxml/sax.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/lxml/sax.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/saxparser.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/schematron.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/serializer.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/usedoctest.py create mode 100644 .venv/lib/python3.7/site-packages/lxml/xinclude.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xmlerror.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xmlid.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xmlschema.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xpath.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xslt.pxi create mode 100644 .venv/lib/python3.7/site-packages/lxml/xsltext.pxi create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/multidict-6.0.5.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/multidict/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/multidict/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/multidict/__pycache__/_abc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/multidict/__pycache__/_compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/multidict/__pycache__/_multidict_base.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/multidict/__pycache__/_multidict_py.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/multidict/_abc.py create mode 100644 .venv/lib/python3.7/site-packages/multidict/_compat.py create mode 100755 .venv/lib/python3.7/site-packages/multidict/_multidict.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/multidict/_multidict_base.py create mode 100644 .venv/lib/python3.7/site-packages/multidict/_multidict_py.py create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/pip/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/__main__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/build_env.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cache.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/check.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/completion.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/configuration.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/download.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/help.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/install.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/list.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/search.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/show.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/configuration.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/download.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/index.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/locations.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/candidate.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/index.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/models/link.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/check.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/pyproject.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/resolve.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/models.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_internal/wheel.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 .venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pkg_resources/py31compat.py create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame-2.5.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/_camera_opencv.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/_camera_vidcapture.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/camera.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/colordict.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/cursors.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/draw_py.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/fastevent.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/freetype.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/ftfont.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/locals.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/macosx.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/midi.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/pkgdata.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/sndarray.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/sprite.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/surfarray.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/sysfont.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pycache__/version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pyinstaller/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pyinstaller/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pyinstaller/__pycache__/hook-pygame.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/__pyinstaller/hook-pygame.py create mode 100755 .venv/lib/python3.7/site-packages/pygame/_camera.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_camera_opencv.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/_camera_vidcapture.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/_common.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_freetype.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/__pycache__/__init__.cpython-37.pyc create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/audio.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/audio.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/controller.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/controller.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/mixer.cpython-37m-arm-linux-gnueabihf.so create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/sdl2.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/sdl2.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/touch.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/touch.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sdl2/video.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/_sdl2/video.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/_sprite.cpython-37m-arm-linux-gnueabihf.so create mode 100755 .venv/lib/python3.7/site-packages/pygame/base.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/base.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/bufferproxy.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/bufferproxy.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/camera.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/camera.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/color.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/color.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/colordict.py create mode 100755 .venv/lib/python3.7/site-packages/pygame/constants.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/constants.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/cursors.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/cursors.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/display.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/display.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/__main__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/__pycache__/__main__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/LGPL.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput11.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput2.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput21.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput3.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput31.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput4.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput41.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput5.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedInputOutput51.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha11.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha2.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha21.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha3.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputAlpha31.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess11.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess2.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess21.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess3.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess31.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess4.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess41.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess5.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess51.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess6.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/AdvancedOutputProcess61.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-INPUT-resultscreen.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-INPUT-resultscreen1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-INPUT-sourcecode.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-INPUT-sourcecode1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-PROCESS-resultscreen.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-PROCESS-resultscreen1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-PROCESS-sourcecode.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-PROCESS-sourcecode1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-ouput-result-screen.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Bagic-ouput-result-screen1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Basic-ouput-sourcecode.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/Basic-ouput-sourcecode1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/angle_to.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_average.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_background.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_green.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_hsv.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_mask.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_rgb.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_thresh.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_thresholded.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/camera_yuv.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/chimpshot.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/draw_module_example.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/intro_ball.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/intro_blade.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/intro_freedom.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-Battleship.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-Battleship1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-PuyoPuyo.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-PuyoPuyo1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-TPS.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/introduction-TPS1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/joystick_calls.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/pygame_lofi.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/pygame_logo.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/pygame_powered.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/pygame_powered_lowres.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/pygame_tiny.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_allblack.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_flipped.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_redimg.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_rgbarray.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_scaledown.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_scaleup.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_soften.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_striped.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/surfarray_xfade.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/tom_basic.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/tom_event-flowchart.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/tom_formulae.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_images/tom_radians.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/c_api.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/filepaths.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/index.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/logos.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/bufferproxy.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/camera.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/cdrom.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/color.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/color_list.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/cursors.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/display.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/draw.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/event.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/examples.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/fastevent.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/font.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/freetype.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/gfxdraw.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/image.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/joystick.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/key.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/locals.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/mask.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/math.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/midi.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/mixer.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/mouse.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/music.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/overlay.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/pixelarray.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/pixelcopy.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/pygame.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/rect.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/scrap.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/sdl2_controller.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/sdl2_video.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/sndarray.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/sprite.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/surface.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/surfarray.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/tests.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/time.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/touch.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_sources/ref/transform.rst.txt create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/basic.css create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/doctools.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/documentation_options.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/file.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/language_data.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/legacy_logos.zip create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/minus.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/plus.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame.css create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame.ico create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_lofi.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_lofi.svg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_logo.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_logo.svg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_powered.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_powered.svg create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_powered_lowres.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygame_tiny.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/pygments.css create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/reset.css create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/searchtools.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/sphinx_highlight.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/_static/tooltip.css create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/base.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/bufferproxy.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/color.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/display.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/event.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/freetype.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/mixer.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/rect.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/rwobject.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/slots.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/surface.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/surflock.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/c_api/version.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/filepaths.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/genindex.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/index.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/logos.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/py-modindex.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/bufferproxy.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/camera.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/cdrom.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/color.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/color_list.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/cursors.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/display.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/draw.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/event.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/examples.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/fastevent.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/font.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/freetype.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/gfxdraw.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/image.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/joystick.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/key.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/locals.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/mask.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/math.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/midi.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/mixer.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/mouse.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/music.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/overlay.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/pixelarray.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/pixelcopy.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/pygame.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/rect.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/scrap.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/sdl2_controller.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/sdl2_video.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/sndarray.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/sprite.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/surface.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/surfarray.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/tests.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/time.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/touch.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/ref/transform.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/search.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/searchindex.js create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/CameraIntro.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/ChimpLineByLine.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/DisplayModes.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/ImportInit.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/MakeGames.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/MoveIt.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/PygameIntro.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/SpriteIntro.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/SurfarrayIntro.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/chimp.py.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/newbieguide.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/tom_games2.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/tom_games3.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/tom_games4.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/tom_games5.html create mode 100644 .venv/lib/python3.7/site-packages/pygame/docs/generated/tut/tom_games6.html create mode 100755 .venv/lib/python3.7/site-packages/pygame/draw.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/draw.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/draw_py.py create mode 100755 .venv/lib/python3.7/site-packages/pygame/event.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/event.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/README.rst create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/aacircle.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/aliens.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/arraydemo.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/audiocapture.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/blend_fill.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/blit_blends.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/camera.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/chimp.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/cursors.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/dropevent.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/eventlist.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/font_viewer.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/fonty.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/freetype_misc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/glcube.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/go_over_there.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/grid.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/headless_no_windows_needed.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/joystick.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/liquid.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/mask.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/midi.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/moveit.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/music_drop_fade.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/pixelarray.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/playmus.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/resizing_new.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/scaletest.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/scrap_clipboard.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/scroll.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/setmodescale.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/sound.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/sound_array_demos.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/sprite_texture.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/stars.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/testsprite.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/textinput.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/vgrade.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/__pycache__/video.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/aacircle.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/aliens.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/arraydemo.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/audiocapture.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/blend_fill.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/blit_blends.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/camera.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/chimp.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/cursors.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/BGR.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien1.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien1.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien2.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien2.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien3.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/alien3.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/arraydemo.bmp create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/asprite.bmp create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/background.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/black.ppm create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/blue.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/blue.mpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/bomb.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/boom.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/brick.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/car_door.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/chimp.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/city.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/crimson.pnm create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/cursor.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/danger.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/explosion1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/fist.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/green.pcx create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/grey.pgm create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/house_lo.mp3 create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/house_lo.ogg create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/house_lo.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/laplacian.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/liquid.bmp create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/midikeys.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/player1.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/punch.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/purple.xpm create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/red.jpg create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/sans.ttf create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/scarlet.webp create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/secosmic_lo.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/shot.gif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/static.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/teal.svg create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/turquoise.tif create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/whiff.wav create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/data/yellow.tga create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/dropevent.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/eventlist.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/font_viewer.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/fonty.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/freetype_misc.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/glcube.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/go_over_there.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/grid.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/headless_no_windows_needed.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/joystick.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/liquid.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/mask.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/midi.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/moveit.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/music_drop_fade.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/pixelarray.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/playmus.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/resizing_new.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/scaletest.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/scrap_clipboard.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/scroll.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/setmodescale.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/sound.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/sound_array_demos.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/sprite_texture.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/stars.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/testsprite.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/textinput.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/vgrade.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/examples/video.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/fastevent.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/fastevent.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/font.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/font.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/freesansbold.ttf create mode 100644 .venv/lib/python3.7/site-packages/pygame/freetype.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/freetype.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/ftfont.py create mode 100755 .venv/lib/python3.7/site-packages/pygame/gfxdraw.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/gfxdraw.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/image.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/image.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/imageext.cpython-37m-arm-linux-gnueabihf.so create mode 100755 .venv/lib/python3.7/site-packages/pygame/joystick.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/joystick.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/key.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/key.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/locals.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/locals.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/macosx.py create mode 100755 .venv/lib/python3.7/site-packages/pygame/mask.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/mask.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/math.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/math.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/midi.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/midi.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/mixer.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/mixer.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/mixer_music.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/mixer_music.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/mouse.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/mouse.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/newbuffer.cpython-37m-arm-linux-gnueabihf.so create mode 100755 .venv/lib/python3.7/site-packages/pygame/pixelarray.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/pixelarray.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/pixelcopy.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/pixelcopy.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/pkgdata.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/py.typed create mode 100644 .venv/lib/python3.7/site-packages/pygame/pygame.ico create mode 100644 .venv/lib/python3.7/site-packages/pygame/pygame_icon.bmp create mode 100644 .venv/lib/python3.7/site-packages/pygame/pygame_icon.icns create mode 100644 .venv/lib/python3.7/site-packages/pygame/pygame_icon_mac.bmp create mode 100755 .venv/lib/python3.7/site-packages/pygame/pypm.cpython-37m-arm-linux-gnueabihf.so create mode 100755 .venv/lib/python3.7/site-packages/pygame/rect.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/rect.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/rwobject.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/rwobject.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/scrap.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/scrap.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/sndarray.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/sndarray.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/sprite.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/sprite.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/surface.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/surface.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/surfarray.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/surfarray.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/surflock.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/surflock.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/sysfont.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__main__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/__main__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/base_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/blit_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/bufferproxy_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/camera_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/color_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/constants_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/controller_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/cursors_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/display_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/docs_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/draw_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/event_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/font_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/freetype_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/freetype_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/ftfont_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/ftfont_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/gfxdraw_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/image__save_gl_surface_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/image_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/image_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/imageext_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/imageext_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/joystick_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/key_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/locals_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mask_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/math_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/midi_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mixer_music_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mixer_music_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mixer_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mixer_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/mouse_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/pixelarray_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/pixelcopy_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/rect_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/rwobject_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/scrap_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/scrap_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/sndarray_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/sndarray_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/sprite_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/surface_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/surfarray_tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/surfarray_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/surflock_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/sysfont_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/threads_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/time_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/touch_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/transform_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/version_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/__pycache__/video_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/base_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/blit_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/bufferproxy_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/camera_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/color_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/constants_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/controller_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/cursors_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/display_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/docs_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/draw_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/event_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/A_PyGameMono-8.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/PlayfairDisplaySemibold.ttf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/PyGameMono-18-100dpi.bdf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/PyGameMono-18-75dpi.bdf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/PyGameMono-8.bdf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/PyGameMono.otf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/test_fixed.otf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/test_sans.ttf create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/fonts/u13079_PyGameMono-8.png create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/xbm_cursors/white_sizing.xbm create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/fixtures/xbm_cursors/white_sizing_mask.xbm create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/font_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/freetype_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/freetype_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/ftfont_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/ftfont_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/gfxdraw_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/image__save_gl_surface_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/image_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/image_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/imageext_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/imageext_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/joystick_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/key_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/locals_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mask_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/math_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/midi_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mixer_music_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mixer_music_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mixer_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mixer_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/mouse_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/pixelarray_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/pixelcopy_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/rect_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/__pycache__/run_tests__test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/fake_4_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/fake_5_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/fake_6_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/no_assertions__ret_code_of_1__test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/__pycache__/zero_tests_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/fake_4_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/fake_5_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/fake_6_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/no_assertions__ret_code_of_1__test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/all_ok/zero_tests_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__pycache__/incomplete_todo_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__pycache__/magic_tag_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/__pycache__/sleep_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/incomplete_todo_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/magic_tag_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/everything/sleep_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/__pycache__/invisible_tag_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/__pycache__/magic_tag_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/invisible_tag_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/exclude/magic_tag_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/__pycache__/fake_4_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/failures1/fake_4_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/incomplete_todo/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/__pycache__/fake_1_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/fake_1_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/infinite_loop/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/__pycache__/fake_4_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_4_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/__pycache__/fake_3_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/__pycache__/fake_4_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_3_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_4_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/run_tests__test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/__pycache__/fake_2_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/__pycache__/sleep_test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/fake_2_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/run_tests__tests/timeout/sleep_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/rwobject_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/scrap_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/scrap_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/sndarray_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/sndarray_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/sprite_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/surface_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/surfarray_tags.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/surfarray_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/surflock_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/sysfont_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/arrinter.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/async_sub.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/buftools.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/endian.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/png.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/run_tests.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/test_machinery.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/__pycache__/test_runner.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/arrinter.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/async_sub.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/buftools.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/endian.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/png.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/run_tests.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/test_machinery.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/test_utils/test_runner.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/threads_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/time_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/touch_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/transform_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/version_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/tests/video_test.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/threads/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/threads/__pycache__/__init__.cpython-37.pyc create mode 100755 .venv/lib/python3.7/site-packages/pygame/time.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/time.pyi create mode 100755 .venv/lib/python3.7/site-packages/pygame/transform.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/pygame/transform.pyi create mode 100644 .venv/lib/python3.7/site-packages/pygame/version.py create mode 100644 .venv/lib/python3.7/site-packages/pygame/version.pyi create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/python_dateutil-2.8.2.dist-info/zip-safe create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/requests-2.31.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/requests/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/__version__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/_internal_utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/adapters.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/api.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/auth.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/certs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/cookies.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/help.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/hooks.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/models.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/packages.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/sessions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/status_codes.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/structures.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__pycache__/utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/requests/__version__.py create mode 100644 .venv/lib/python3.7/site-packages/requests/_internal_utils.py create mode 100644 .venv/lib/python3.7/site-packages/requests/adapters.py create mode 100644 .venv/lib/python3.7/site-packages/requests/api.py create mode 100644 .venv/lib/python3.7/site-packages/requests/auth.py create mode 100644 .venv/lib/python3.7/site-packages/requests/certs.py create mode 100644 .venv/lib/python3.7/site-packages/requests/compat.py create mode 100644 .venv/lib/python3.7/site-packages/requests/cookies.py create mode 100644 .venv/lib/python3.7/site-packages/requests/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/requests/help.py create mode 100644 .venv/lib/python3.7/site-packages/requests/hooks.py create mode 100644 .venv/lib/python3.7/site-packages/requests/models.py create mode 100644 .venv/lib/python3.7/site-packages/requests/packages.py create mode 100644 .venv/lib/python3.7/site-packages/requests/sessions.py create mode 100644 .venv/lib/python3.7/site-packages/requests/status_codes.py create mode 100644 .venv/lib/python3.7/site-packages/requests/structures.py create mode 100644 .venv/lib/python3.7/site-packages/requests/utils.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/dependency_links.txt create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/zip-safe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/_vendor/six.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/archive_util.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/build_meta.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/cli-32.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/cli-64.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/cli.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/alias.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/build_clib.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/build_ext.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/build_py.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/develop.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/dist_info.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/easy_install.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/egg_info.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/install.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/install_lib.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/py36compat.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/register.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/rotate.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/saveopts.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/sdist.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/setopt.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/test.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/upload.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/config.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/dep_util.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/depends.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/dist.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/extension.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/extern/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/setuptools/glibc.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/glob.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/gui-32.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/gui-64.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/gui.exe create mode 100644 .venv/lib/python3.7/site-packages/setuptools/launch.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/monkey.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/msvc.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/namespaces.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/package_index.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/pep425tags.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/py27compat.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/py31compat.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/py33compat.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/sandbox.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl create mode 100644 .venv/lib/python3.7/site-packages/setuptools/script.tmpl create mode 100644 .venv/lib/python3.7/site-packages/setuptools/site-patch.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/ssl_support.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/unicode_utils.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/version.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/wheel.py create mode 100644 .venv/lib/python3.7/site-packages/setuptools/windows_support.py create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/six-1.16.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/six.py create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions-4.7.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions-4.7.1.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions-4.7.1.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions-4.7.1.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions-4.7.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/typing_extensions.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3-2.0.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/urllib3-2.0.3.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/urllib3-2.0.3.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/urllib3-2.0.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/urllib3-2.0.3.dist-info/licenses/LICENSE.txt create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/_base_connection.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/_collections.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/_request_methods.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/_version.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/connection.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/connectionpool.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/fields.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/filepost.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/poolmanager.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/__pycache__/response.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/_base_connection.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/_collections.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/_request_methods.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/_version.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/connection.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/connectionpool.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/socks.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/bindings.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/low_level.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/securetransport.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/contrib/socks.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/fields.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/filepost.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/poolmanager.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/py.typed create mode 100644 .venv/lib/python3.7/site-packages/urllib3/response.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/connection.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/proxy.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/request.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/response.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/retry.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssl_.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssltransport.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/timeout.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/url.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/util.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/__pycache__/wait.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/connection.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/proxy.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/request.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/response.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/retry.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/ssl_.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/ssl_match_hostname.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/ssltransport.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/timeout.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/url.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/util.py create mode 100644 .venv/lib/python3.7/site-packages/urllib3/util/wait.py create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__pycache__/client.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__pycache__/connection.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__pycache__/exceptions.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/webdav3/__pycache__/urn.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/webdav3/client.py create mode 100644 .venv/lib/python3.7/site-packages/webdav3/connection.py create mode 100644 .venv/lib/python3.7/site-packages/webdav3/exceptions.py create mode 100644 .venv/lib/python3.7/site-packages/webdav3/urn.py create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/DESCRIPTION.rst create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/metadata.json create mode 100644 .venv/lib/python3.7/site-packages/webdavclient3-3.14.6.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/NOTICE create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/yarl-1.9.4.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/yarl/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/yarl/__init__.pyi create mode 100644 .venv/lib/python3.7/site-packages/yarl/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/yarl/__pycache__/_quoting.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/yarl/__pycache__/_quoting_py.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/yarl/__pycache__/_url.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/yarl/_quoting.py create mode 100755 .venv/lib/python3.7/site-packages/yarl/_quoting_c.cpython-37m-arm-linux-gnueabihf.so create mode 100644 .venv/lib/python3.7/site-packages/yarl/_quoting_c.pyi create mode 100644 .venv/lib/python3.7/site-packages/yarl/_quoting_c.pyx create mode 100644 .venv/lib/python3.7/site-packages/yarl/_quoting_py.py create mode 100644 .venv/lib/python3.7/site-packages/yarl/_url.py create mode 100644 .venv/lib/python3.7/site-packages/yarl/py.typed create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/METADATA create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/RECORD create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.7/site-packages/zipp-3.15.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.7/site-packages/zipp/__init__.py create mode 100644 .venv/lib/python3.7/site-packages/zipp/__pycache__/__init__.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/zipp/__pycache__/py310compat.cpython-37.pyc create mode 100644 .venv/lib/python3.7/site-packages/zipp/py310compat.py create mode 100644 .venv/pyvenv.cfg create mode 100644 .venv/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/appdirs-1.4.3-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/certifi-2018.8.24-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/colorama-0.3.7-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/distlib-0.2.8-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/distro-1.3.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/idna-2.6-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/ipaddress-0.0.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/packaging-19.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pip-18.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/progress-1.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pyparsing-2.2.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pytoml-0.1.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/requests-2.21.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/setuptools-40.8.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/six-1.12.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/urllib3-1.24.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/wheel-0.32.3-py2.py3-none-any.whl create mode 100755 Artal.png create mode 100644 __pycache__/uploader.cpython-37.pyc create mode 100644 __pycache__/wled_controller_async.cpython-37.pyc create mode 100755 _fotobox.py delete mode 100644 fotobox_fix_teest.py create mode 100644 logo.png create mode 100644 qr.png create mode 100644 qr_small.bmp create mode 100644 qr_small.png create mode 100644 uploader.pyc create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100755 venv/bin/easy_install create mode 100755 venv/bin/easy_install-3.7 create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.7 create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 100644 venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolve.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/models.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/pkg_resources-0.0.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/dependency_links.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/zip-safe create mode 100644 venv/lib/python3.7/site-packages/setuptools/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/archive_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/build_meta.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/alias.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_clib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_ext.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_py.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/develop.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/dist_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_lib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/py36compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/register.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/rotate.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/saveopts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/sdist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/setopt.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/test.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/config.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dep_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/depends.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extension.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/glibc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/glob.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/launch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/monkey.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/msvc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/namespaces.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/package_index.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py27compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py33compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/sandbox.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/script.tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/site-patch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/ssl_support.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/unicode_utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/wheel.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/windows_support.py create mode 100644 venv/pyvenv.cfg create mode 100644 venv/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/appdirs-1.4.3-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/certifi-2018.8.24-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/colorama-0.3.7-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/distlib-0.2.8-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/distro-1.3.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/idna-2.6-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/ipaddress-0.0.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/packaging-19.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pip-18.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/progress-1.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pyparsing-2.2.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pytoml-0.1.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/requests-2.21.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/setuptools-40.8.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/six-1.12.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/urllib3-1.24.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/wheel-0.32.3-py2.py3-none-any.whl create mode 100644 wled_controller_async.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bafc689 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3623a7f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.venv/bin/activate b/.venv/bin/activate new file mode 100644 index 0000000..36944f6 --- /dev/null +++ b/.venv/bin/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "$1" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/pi/fotobox/.venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(.venv) " != x ] ; then + PS1="(.venv) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r +fi diff --git a/.venv/bin/activate.csh b/.venv/bin/activate.csh new file mode 100644 index 0000000..4d6d4cc --- /dev/null +++ b/.venv/bin/activate.csh @@ -0,0 +1,37 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/pi/fotobox/.venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if (".venv" != "") then + set env_name = ".venv" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.venv/bin/activate.fish b/.venv/bin/activate.fish new file mode 100644 index 0000000..3836dc7 --- /dev/null +++ b/.venv/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/pi/fotobox/.venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(.venv) " + printf "%s%s" "(.venv) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/.venv/bin/easy_install b/.venv/bin/easy_install new file mode 100755 index 0000000..54b176c --- /dev/null +++ b/.venv/bin/easy_install @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/easy_install-3.7 b/.venv/bin/easy_install-3.7 new file mode 100755 index 0000000..54b176c --- /dev/null +++ b/.venv/bin/easy_install-3.7 @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/normalizer b/.venv/bin/normalizer new file mode 100755 index 0000000..8cbc9a3 --- /dev/null +++ b/.venv/bin/normalizer @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from charset_normalizer.cli.normalizer import cli_detect + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/.venv/bin/pinout b/.venv/bin/pinout new file mode 100755 index 0000000..67fde91 --- /dev/null +++ b/.venv/bin/pinout @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from gpiozerocli.pinout import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip b/.venv/bin/pip new file mode 100755 index 0000000..f4b10fa --- /dev/null +++ b/.venv/bin/pip @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip3 b/.venv/bin/pip3 new file mode 100755 index 0000000..f4b10fa --- /dev/null +++ b/.venv/bin/pip3 @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip3.7 b/.venv/bin/pip3.7 new file mode 100755 index 0000000..f4b10fa --- /dev/null +++ b/.venv/bin/pip3.7 @@ -0,0 +1,10 @@ +#!/home/pi/fotobox/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/python b/.venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/bin/python3 b/.venv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/.venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/.venv/bin/wdc b/.venv/bin/wdc new file mode 100755 index 0000000..ef0896a --- /dev/null +++ b/.venv/bin/wdc @@ -0,0 +1,624 @@ +#!/usr/bin/python +# PYTHON_ARGCOMPLETE_OK + +from __future__ import print_function + +import argparse +import getpass +import os +import platform +import shlex +import struct +import subprocess +import sys +from base64 import b64decode, b64encode +from distutils.util import strtobool + +import argcomplete + +from webdav3.client import Client, WebDavException, NotConnection, Urn + + +def get_terminal_size(): + current_os = platform.system() + tuple_xy = None + if current_os == 'Windows': + tuple_xy = _get_terminal_size_windows() + if tuple_xy is None: + tuple_xy = _get_terminal_size_input() + if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'): + tuple_xy = _get_terminal_size_linux() + if tuple_xy is None: + tuple_xy = 80, 25 + return tuple_xy + + +def _get_terminal_size_windows(): + try: + from ctypes import windll, create_string_buffer + h = windll.kernel32.GetStdHandle(-12) + csbi = create_string_buffer(22) + res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) + if res: + (bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) + sizex = right - left + 1 + sizey = bottom - top + 1 + return sizex, sizey + except: + pass + + +def _get_terminal_size_input(): + try: + cols = int(subprocess.check_call(shlex.split('tput cols'))) + rows = int(subprocess.check_call(shlex.split('tput lines'))) + return (cols, rows) + except: + pass + + +def _get_terminal_size_linux(): + + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + return struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except: + pass + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + try: + cr = (os.environ['LINES'], os.environ['COLUMNS']) + except: + return None + return int(cr[1]), int(cr[0]) + + +class ProgressBar: + + def __init__(self): + self.precise = 0 + self.total = 0 + + def show(self): + progress_line = self._progress_line() + import sys + if self.precise == 100: + print(progress_line, end="") + else: + print(progress_line, end="") + sys.stdout.write("\r") + + def _progress_line(self): + sizex, sizey = get_terminal_size() + available_width = sizex + precise = self._get_field_precise() + ratio = self._get_field_ratio() + available_width -= len(precise) + len(ratio) + progress = self._get_field_progress(available_width-2) + return "{precise} {progress} {ratio}".format(precise=precise, progress=progress, ratio=ratio) + + def _get_field_precise(self): + line = "{precise}%".format(precise=self.precise) + return "{:<4}".format(line) + + def _get_field_ratio(self): + current = float(self.precise * self.total / 100) + total = float(self.total) + current_line = "{:.2f}".format(current) + total_line = "{:.2f}".format(total) + line = "{current}/{total}".format(current=current_line, total=total_line) + available = len(total_line) * 2 + 1 + format_line = "{prefix}{value}{sufix}".format(prefix="{:>", value=available, sufix="}") + line = format_line.format(line) + return line + + def _get_field_progress(self, width): + available_width = width - 2 + current = int(self.precise * available_width / 100) + available_width -= current + 1 + tip = ">" if not self.precise == 100 else "" + progress = "{arrow}{tip}{space}".format(arrow="=" * current, tip=tip, space=" " * available_width) + return "[{progress}]".format(progress=progress) + + def callback(self, current, total): + if total and not self.total: + self.total = total + if not total: + return + precise = int(float(current) * 100 / total) + if self.precise == precise: + return + else: + self.precise = precise + self.show() + +setting_keys = ['webdav_hostname', 'webdav_root', 'webdav_login', 'webdav_password', 'webdav_token', + 'proxy_hostname', 'proxy_login', 'proxy_password', + 'cert_path', 'key_path'] + +crypto_keys = ['webdav_password', 'webdav_token', 'proxy_password'] + + +def encoding(source): + + if not source: + return "" + return b64encode(source.encode('utf-8')) + + +def decoding(source): + + if not source: + return "" + return b64decode(source).decode('utf-8') + + +def import_options(): + + options = dict() + for setting_key in setting_keys: + options[setting_key] = os.environ.get(setting_key.upper()) + + for crypto_key in crypto_keys: + if not options[crypto_key]: + continue + options[crypto_key] = decoding(options[crypto_key]) + + return options + + +def valid(options): + + if 'webdav_hostname' not in options: + return False + + if not options['webdav_token'] and not options['webdav_login']: + return False + + if options['webdav_login'] and not options['webdav_password']: + return False + + return True + + +class Formatter(argparse.RawTextHelpFormatter): + + def _get_default_metavar_for_optional(self, action): + if not action.option_strings: + return action.dest + else: + return "" + + def _format_action_invocation(self, action): + if not action.option_strings: + default = self._get_default_metavar_for_optional(action) + metavar, = self._metavar_formatter(action, default)(1) + return metavar + + else: + parts = [] + + if action.nargs == 0: + parts.extend(action.option_strings) + else: + default = self._get_default_metavar_for_optional(action) + args_string = self._format_args(action, default) + for option_string in action.option_strings: + parts.append(option_string) + + return '%s %s' % (', '.join(parts), args_string) + + return ', '.join(parts) + + def _metavar_formatter(self, action, default_metavar): + if action.metavar is not None: + result = action.metavar + else: + result = default_metavar + + def format(tuple_size): + if isinstance(result, tuple): + return result + else: + return (result, ) * tuple_size + return format + + +def logging_exception(exception): + print(exception) + + +def urn_completer(prefix, **kwargs): + + options = import_options() + try: + client = Client(options) + + prefix_urn = Urn(prefix) + if prefix_urn.is_dir(): + return (prefix+filename for filename in client.list(prefix_urn.path())) + else: + parent = prefix_urn.parent() + prefix_filename = prefix_urn.filename() + prefix_filename_length = len(prefix_filename) + return (prefix + filename[prefix_filename_length:] for filename in client.list(parent) if filename.startswith(prefix_filename)) + except WebDavException: + pass + + return tuple() + +if __name__ == "__main__": + + epilog = """ + Examples: + -------- + $ wdc login https://webdav.server.ru + webdav_login: login + webdav_password: password + success + $ wdc login https://webdav.server.ru --token xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + not success + $ wdc check + success + $ wdc check file1 + not success + $ wdc free + 245234120344 + $ wdc ls dir1 + file1 + ... + fileN + $ wdc mkdir dir2 + $ wdc copy dir1/file1 -t dir2/file1 + $ wdc move dir2/file1 -t dir2/file2 + $ wdc download dir1/file1 -t ~/Downloads/file1 + $ wdc download dir1/ -t ~/Downloads/dir1/ + $ wdc upload dir2/file2 -f ~/Documents/file1 + $ wdc upload dir2/ -f ~/Documents/ + $ wdc publish di2/file2 + https://yadi.sk/i/vWtTUcBucAc6k + $ wdc unpublish dir2/file2 + $ wdc pull dir1/ -t ~/Documents/dir1/ + $ wdc push dir1/ -f ~/Documents/dir1/ + $ wdc info dir1/file1 + {'name': 'file1', 'modified': 'Thu, 23 Oct 2014 16:16:37 GMT', + 'size': '3460064', 'created': '2014-10-23T16:16:37Z'} + """ + + usage = """ + wdc [-h] [-v] + wdc login https://webdav.server.ru [--token] [-r] [-p] [-c] [-k] + wdc [action] [path] [-t] [-f] + """ + + actions = "login logout check info free ls clean mkdir copy move download upload publish unpublish push pull".split() + actions_help = "check, info, free, ls, clean, mkdir, copy, move,\ndownload, upload, publish, unpublish, push, pull" + + parser = argparse.ArgumentParser(prog='wdc', formatter_class=Formatter, epilog=epilog, usage=usage) + parser.add_argument("action", help=actions_help, choices=actions) + + from webdav3.client import __version__ as version + version_text = "{name} {version}".format(name="%(prog)s", version=version) + parser.add_argument("-v", '--version', action='version', version=version_text) + parser.add_argument("-r", "--root", help="example: dir1/dir2") + parser.add_argument("--token", help="example: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") + parser.add_argument("-c", "--cert-path", help="example: /etc/ssl/certs/certificate.crt") + parser.add_argument("-k", "--key-path", help="example: /etc/ssl/private/certificate.key") + parser.add_argument("-p", "--proxy", help="example: http://127.0.0.1:8080") + parser.add_argument("path", help="example: dir1/dir2/file1", nargs='?').completer = urn_completer + parser.add_argument("-f", '--from-path', help="example: ~/Documents/file1") + parser.add_argument("-t", "--to-path", help="example for download and pull: ~/Download/file1\nexample for copy and move: dir1/dir2").completer = urn_completer + + argcomplete.autocomplete(parser, exclude=("-h", "--help", "--proxy", "-p", "-r", "--root", "-c", "--cert-path", "-t", "--to-path", "-v", "--version", "-f", "--from-path", "-k", "--key-path")) + args = parser.parse_args() + action = args.action + + if action == 'login': + env = dict() + if not args.path: + try: + env['webdav_hostname'] = raw_input("webdav_hostname: ") + except NameError: + env['webdav_hostname'] = input("webdav_hostname: ") + else: + env['webdav_hostname'] = args.path + + if not args.token: + try: + env['webdav_login'] = raw_input("webdav_login: ") + except NameError: + env['webdav_login'] = input("webdav_login: ") + env['webdav_password'] = getpass.getpass("webdav_password: ") + else: + env['webdav_token'] = args.token + + if args.proxy: + env['proxy_hostname'] = args.proxy + try: + env['proxy_login'] = raw_input("proxy_login: ") + except NameError: + env['proxy_login'] = input("proxy_login: ") + env['proxy_password'] = getpass.getpass("proxy_password: ") + + if args.root: + env['webdav_root'] = args.root + + if args.cert_path: + env['cert_path'] = args.cert_path + + if args.key_path: + env['key_path'] = args.key_path + + try: + client = Client(env) + check = client.check() + text = "success" if check else "not success" + print(text) + + if check: + for crypto_key in crypto_keys: + if crypto_key not in env: + continue + if not env[crypto_key]: + continue + env[crypto_key] = encoding(env[crypto_key]) + + for (key, value) in env.items(): + os.putenv(key.upper(), value) + os.system('bash') + + except WebDavException as e: + print("not success") + sys.exit() + else: + options = import_options() + if not valid(options): + print("First log on webdav server using the following command: wdc login.") + sys.exit() + + elif action == "logout": + os.system("exit") + + elif action == 'check': + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + check = client.check(args.path) if args.path else client.check() + text = "success" if check else "not success" + print(text) + except WebDavException as e: + logging_exception(e) + + elif action == 'free': + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + free_size = client.free() + print(free_size) + except WebDavException as e: + logging_exception(e) + + elif action == 'ls': + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + paths = client.list(args.path) if args.path else client.list() + for path in paths: + print(path) + except WebDavException as e: + logging_exception(e) + + elif action == 'clean': + if not args.path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.clean(args.path) + except WebDavException as e: + logging_exception(e) + + elif action == 'mkdir': + if not args.path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.mkdir(args.path) + except WebDavException as e: + logging_exception(e) + + elif action == 'copy': + if not args.path or not args.to_path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.copy(remote_path_from=args.path, remote_path_to=args.to_path) + except WebDavException as e: + logging_exception(e) + + elif action == 'move': + if not args.path or not args.to_path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.move(remote_path_from=args.path, remote_path_to=args.to_path) + except WebDavException as e: + logging_exception(e) + + elif action == 'download': + if not args.path or not args.to_path: + parser.print_help() + else: + options = import_options() + progress_bar = ProgressBar() + + def download_progress(download_t, download_d, upload_t, upload_d): + progress_bar.callback(current=download_d, total=download_t) + + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + if not os.path.exists(path=args.to_path): + client.download(remote_path=args.path, local_path=args.to_path, progress=download_progress) + print("\n") + else: + try: + choice = raw_input("Local path exists, do you want to overwrite it? [Y/n] ") + except NameError: + choice = input("Local path exists, do you want to overwrite it? [Y/n] ") + try: + yes = strtobool(choice.lower()) + if yes: + client.download(remote_path=args.path, local_path=args.to_path, progress=download_progress) + print("\n") + except ValueError: + print("Incorrect answer") + except WebDavException as e: + logging_exception(e) + + elif action == 'upload': + if not args.path or not args.from_path: + parser.print_help() + else: + options = import_options() + progress_bar = ProgressBar() + + def upload_progress(download_t, download_d, upload_t, upload_d): + progress_bar.callback(current=upload_d, total=upload_t) + + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + if not client.check(remote_path=args.path): + client.upload(remote_path=args.path, local_path=args.from_path, progress=upload_progress) + print("\n") + else: + try: + choice = raw_input("Remote resource exists, do you want to overwrite it? [Y/n] ") + except NameError: + choice = input("Remote resource exists, do you want to overwrite it? [Y/n] ") + try: + yes = strtobool(choice.lower()) + if yes: + client.upload(remote_path=args.path, local_path=args.from_path, progress=upload_progress) + print("\n") + except ValueError: + print("Incorrect answer") + except WebDavException as e: + logging_exception(e) + + elif action == 'publish': + if not args.path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + link = client.publish(args.path) + print(link) + except WebDavException as e: + logging_exception(e) + + elif action == 'unpublish': + if not args.path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.unpublish(args.path) + except WebDavException as e: + logging_exception(e) + + elif action == 'push': + if not args.path or not args.from_path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.push(remote_directory=args.path, local_directory=args.from_path) + except WebDavException as e: + logging_exception(e) + + elif action == 'pull': + if not args.path or not args.to_path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + client.pull(remote_directory=args.path, local_directory=args.to_path) + except WebDavException as e: + logging_exception(e) + + elif action == 'info': + if not args.path: + parser.print_help() + else: + options = import_options() + try: + client = Client(options) + connection = client.check() + if not connection: + raise NotConnection(options["webdav_hostname"]) + info = client.info(args.path) + print(info) + except WebDavException as e: + logging_exception(e) + + else: + parser.print_help() diff --git a/.venv/include/site/python3.7/pygame/_blit_info.h b/.venv/include/site/python3.7/pygame/_blit_info.h new file mode 100644 index 0000000..5320d0b --- /dev/null +++ b/.venv/include/site/python3.7/pygame/_blit_info.h @@ -0,0 +1,21 @@ +#define NO_PYGAME_C_API +#include "_surface.h" + +/* The structure passed to the low level blit functions */ +typedef struct { + int width; + int height; + Uint8 *s_pixels; + int s_pxskip; + int s_skip; + Uint8 *d_pixels; + int d_pxskip; + int d_skip; + SDL_PixelFormat *src; + SDL_PixelFormat *dst; + Uint8 src_blanket_alpha; + int src_has_colorkey; + Uint32 src_colorkey; + SDL_BlendMode src_blend; + SDL_BlendMode dst_blend; +} SDL_BlitInfo; diff --git a/.venv/include/site/python3.7/pygame/_camera.h b/.venv/include/site/python3.7/pygame/_camera.h new file mode 100644 index 0000000..075ef6f --- /dev/null +++ b/.venv/include/site/python3.7/pygame/_camera.h @@ -0,0 +1,26 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef _CAMERA_H +#define _CAMERA_H + +#include "_pygame.h" +#include "camera.h" + +#endif diff --git a/.venv/include/site/python3.7/pygame/_pygame.h b/.venv/include/site/python3.7/pygame/_pygame.h new file mode 100644 index 0000000..e3521b3 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/_pygame.h @@ -0,0 +1,374 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* This will use PYGAMEAPI_EXTERN_SLOTS instead + * of PYGAMEAPI_DEFINE_SLOTS for base modules. + */ +#ifndef _PYGAME_INTERNAL_H +#define _PYGAME_INTERNAL_H + +#include "pgplatform.h" +/* + If PY_SSIZE_T_CLEAN is defined before including Python.h, length is a + Py_ssize_t rather than an int for all # variants of formats (s#, y#, etc.) +*/ +#define PY_SSIZE_T_CLEAN +#include + +/* Ensure PyPy-specific code is not in use when running on GraalPython (PR + * #2580) */ +#if defined(GRAALVM_PYTHON) && defined(PYPY_VERSION) +#undef PYPY_VERSION +#endif + +#include + +/* SDL 1.2 constants removed from SDL 2 */ +typedef enum { + SDL_HWSURFACE = 0, + SDL_RESIZABLE = SDL_WINDOW_RESIZABLE, + SDL_ASYNCBLIT = 0, + SDL_OPENGL = SDL_WINDOW_OPENGL, + SDL_OPENGLBLIT = 0, + SDL_ANYFORMAT = 0, + SDL_HWPALETTE = 0, + SDL_DOUBLEBUF = 0, + SDL_FULLSCREEN = SDL_WINDOW_FULLSCREEN, + SDL_HWACCEL = 0, + SDL_SRCCOLORKEY = 0, + SDL_RLEACCELOK = 0, + SDL_SRCALPHA = 0, + SDL_NOFRAME = SDL_WINDOW_BORDERLESS, + SDL_GL_SWAP_CONTROL = 0, + TIMER_RESOLUTION = 0 +} PygameVideoFlags; + +/* the wheel button constants were removed from SDL 2 */ +typedef enum { + PGM_BUTTON_LEFT = SDL_BUTTON_LEFT, + PGM_BUTTON_RIGHT = SDL_BUTTON_RIGHT, + PGM_BUTTON_MIDDLE = SDL_BUTTON_MIDDLE, + PGM_BUTTON_WHEELUP = 4, + PGM_BUTTON_WHEELDOWN = 5, + PGM_BUTTON_X1 = SDL_BUTTON_X1 + 2, + PGM_BUTTON_X2 = SDL_BUTTON_X2 + 2, + PGM_BUTTON_KEEP = 0x80 +} PygameMouseFlags; + +typedef enum { + /* Any SDL_* events here are for backward compatibility. */ + SDL_NOEVENT = 0, + + SDL_ACTIVEEVENT = SDL_USEREVENT, + SDL_VIDEORESIZE, + SDL_VIDEOEXPOSE, + + PGE_MIDIIN, + PGE_MIDIOUT, + PGE_KEYREPEAT, /* Special internal pygame event, for managing key-presses + */ + + /* DO NOT CHANGE THE ORDER OF EVENTS HERE */ + PGE_WINDOWSHOWN, + PGE_WINDOWHIDDEN, + PGE_WINDOWEXPOSED, + PGE_WINDOWMOVED, + PGE_WINDOWRESIZED, + PGE_WINDOWSIZECHANGED, + PGE_WINDOWMINIMIZED, + PGE_WINDOWMAXIMIZED, + PGE_WINDOWRESTORED, + PGE_WINDOWENTER, + PGE_WINDOWLEAVE, + PGE_WINDOWFOCUSGAINED, + PGE_WINDOWFOCUSLOST, + PGE_WINDOWCLOSE, + PGE_WINDOWTAKEFOCUS, + PGE_WINDOWHITTEST, + PGE_WINDOWICCPROFCHANGED, + PGE_WINDOWDISPLAYCHANGED, + + /* Here we define PGPOST_* events, events that act as a one-to-one + * proxy for SDL events (and some extra events too!), the proxy is used + * internally when pygame users use event.post() + * + * At a first glance, these may look redundant, but they are really + * important, especially with event blocking. If proxy events are + * not there, blocked events dont make it to our event filter, and + * that can break a lot of stuff. + * + * IMPORTANT NOTE: Do not post events directly with these proxy types, + * use the appropriate functions from event.c, that handle these proxy + * events for you. + * Proxy events are for internal use only */ + PGPOST_EVENTBEGIN, /* mark start of proxy-events */ + PGPOST_ACTIVEEVENT = PGPOST_EVENTBEGIN, + PGPOST_APP_TERMINATING, + PGPOST_APP_LOWMEMORY, + PGPOST_APP_WILLENTERBACKGROUND, + PGPOST_APP_DIDENTERBACKGROUND, + PGPOST_APP_WILLENTERFOREGROUND, + PGPOST_APP_DIDENTERFOREGROUND, + PGPOST_AUDIODEVICEADDED, + PGPOST_AUDIODEVICEREMOVED, + PGPOST_CLIPBOARDUPDATE, + PGPOST_CONTROLLERAXISMOTION, + PGPOST_CONTROLLERBUTTONDOWN, + PGPOST_CONTROLLERBUTTONUP, + PGPOST_CONTROLLERDEVICEADDED, + PGPOST_CONTROLLERDEVICEREMOVED, + PGPOST_CONTROLLERDEVICEREMAPPED, + PGPOST_CONTROLLERTOUCHPADDOWN, + PGPOST_CONTROLLERTOUCHPADMOTION, + PGPOST_CONTROLLERTOUCHPADUP, + PGPOST_CONTROLLERSENSORUPDATE, + PGPOST_DOLLARGESTURE, + PGPOST_DOLLARRECORD, + PGPOST_DROPFILE, + PGPOST_DROPTEXT, + PGPOST_DROPBEGIN, + PGPOST_DROPCOMPLETE, + PGPOST_FINGERMOTION, + PGPOST_FINGERDOWN, + PGPOST_FINGERUP, + PGPOST_KEYDOWN, + PGPOST_KEYMAPCHANGED, + PGPOST_KEYUP, + PGPOST_JOYAXISMOTION, + PGPOST_JOYBALLMOTION, + PGPOST_JOYHATMOTION, + PGPOST_JOYBUTTONDOWN, + PGPOST_JOYBUTTONUP, + PGPOST_JOYDEVICEADDED, + PGPOST_JOYDEVICEREMOVED, + PGPOST_LOCALECHANGED, + PGPOST_MIDIIN, + PGPOST_MIDIOUT, + PGPOST_MOUSEMOTION, + PGPOST_MOUSEBUTTONDOWN, + PGPOST_MOUSEBUTTONUP, + PGPOST_MOUSEWHEEL, + PGPOST_MULTIGESTURE, + PGPOST_NOEVENT, + PGPOST_QUIT, + PGPOST_RENDER_TARGETS_RESET, + PGPOST_RENDER_DEVICE_RESET, + PGPOST_SYSWMEVENT, + PGPOST_TEXTEDITING, + PGPOST_TEXTINPUT, + PGPOST_VIDEORESIZE, + PGPOST_VIDEOEXPOSE, + PGPOST_WINDOWSHOWN, + PGPOST_WINDOWHIDDEN, + PGPOST_WINDOWEXPOSED, + PGPOST_WINDOWMOVED, + PGPOST_WINDOWRESIZED, + PGPOST_WINDOWSIZECHANGED, + PGPOST_WINDOWMINIMIZED, + PGPOST_WINDOWMAXIMIZED, + PGPOST_WINDOWRESTORED, + PGPOST_WINDOWENTER, + PGPOST_WINDOWLEAVE, + PGPOST_WINDOWFOCUSGAINED, + PGPOST_WINDOWFOCUSLOST, + PGPOST_WINDOWCLOSE, + PGPOST_WINDOWTAKEFOCUS, + PGPOST_WINDOWHITTEST, + PGPOST_WINDOWICCPROFCHANGED, + PGPOST_WINDOWDISPLAYCHANGED, + + PGE_USEREVENT, /* this event must stay in this position only */ + + PG_NUMEVENTS = + SDL_LASTEVENT /* Not an event. Indicates end of user events. */ +} PygameEventCode; + +/* SDL1 ACTIVEEVENT state attribute can take the following values */ +/* These constant values are directly picked from SDL1 source */ +#define SDL_APPMOUSEFOCUS 0x01 +#define SDL_APPINPUTFOCUS 0x02 +#define SDL_APPACTIVE 0x04 + +/* Surface flags: based on SDL 1.2 flags */ +typedef enum { + PGS_SWSURFACE = 0x00000000, + PGS_HWSURFACE = 0x00000001, + PGS_ASYNCBLIT = 0x00000004, + + PGS_ANYFORMAT = 0x10000000, + PGS_HWPALETTE = 0x20000000, + PGS_DOUBLEBUF = 0x40000000, + PGS_FULLSCREEN = 0x80000000, + PGS_SCALED = 0x00000200, + + PGS_OPENGL = 0x00000002, + PGS_OPENGLBLIT = 0x0000000A, + PGS_RESIZABLE = 0x00000010, + PGS_NOFRAME = 0x00000020, + PGS_SHOWN = 0x00000040, /* Added from SDL 2 */ + PGS_HIDDEN = 0x00000080, /* Added from SDL 2 */ + + PGS_HWACCEL = 0x00000100, + PGS_SRCCOLORKEY = 0x00001000, + PGS_RLEACCELOK = 0x00002000, + PGS_RLEACCEL = 0x00004000, + PGS_SRCALPHA = 0x00010000, + PGS_PREALLOC = 0x01000000 +} PygameSurfaceFlags; + +// TODO Implement check below in a way that does not break CI +/* New buffer protocol (PEP 3118) implemented on all supported Py versions. +#if !defined(Py_TPFLAGS_HAVE_NEWBUFFER) +#error No support for PEP 3118/Py_TPFLAGS_HAVE_NEWBUFFER. Please use a +supported Python version. #endif */ + +#define RAISE(x, y) (PyErr_SetString((x), (y)), NULL) +#define DEL_ATTR_NOT_SUPPORTED_CHECK(name, value) \ + do { \ + if (!value) { \ + PyErr_Format(PyExc_AttributeError, "Cannot delete attribute %s", \ + name); \ + return -1; \ + } \ + } while (0) + +#define DEL_ATTR_NOT_SUPPORTED_CHECK_NO_NAME(value) \ + do { \ + if (!value) { \ + PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute"); \ + return -1; \ + } \ + } while (0) + +/* + * Initialization checks + */ + +#define VIDEO_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_VIDEO)) \ + return RAISE(pgExc_SDLError, "video system not initialized") + +#define JOYSTICK_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_JOYSTICK)) \ + return RAISE(pgExc_SDLError, "joystick system not initialized") + +/* thread check */ +#ifdef WITH_THREAD +#define PG_CHECK_THREADS() (1) +#else /* ~WITH_THREAD */ +#define PG_CHECK_THREADS() \ + (RAISE(PyExc_NotImplementedError, "Python built without thread support")) +#endif /* ~WITH_THREAD */ + +#define PyType_Init(x) (((x).ob_type) = &PyType_Type) + +/* CPython 3.6 had initial and undocumented FASTCALL support, but we play it + * safe by not relying on implementation details */ +#if PY_VERSION_HEX < 0x03070000 + +/* Macro for naming a pygame fastcall wrapper function */ +#define PG_FASTCALL_NAME(func) _##func##_fastcall_wrap + +/* used to forward declare compat functions */ +#define PG_DECLARE_FASTCALL_FUNC(func, self_type) \ + static PyObject *PG_FASTCALL_NAME(func)(self_type * self, PyObject * args) + +/* Using this macro on a function defined with the FASTCALL calling convention + * adds a wrapper definition that uses regular python VARARGS convention. + * Since it is guaranteed that the 'args' object is a tuple, we can directly + * call PySequence_Fast_ITEMS and PyTuple_GET_SIZE on it (which are macros that + * assume the same, and don't do error checking) */ +#define PG_WRAP_FASTCALL_FUNC(func, self_type) \ + PG_DECLARE_FASTCALL_FUNC(func, self_type) \ + { \ + return func(self, (PyObject *const *)PySequence_Fast_ITEMS(args), \ + PyTuple_GET_SIZE(args)); \ + } + +#define PG_FASTCALL METH_VARARGS + +#else /* PY_VERSION_HEX >= 0x03070000 */ +/* compat macros are no-op on python versions that support fastcall */ +#define PG_FASTCALL_NAME(func) func +#define PG_DECLARE_FASTCALL_FUNC(func, self_type) +#define PG_WRAP_FASTCALL_FUNC(func, self_type) + +#define PG_FASTCALL METH_FASTCALL + +#endif /* PY_VERSION_HEX >= 0x03070000 */ + +/* + * event module internals + */ +struct pgEventObject { + PyObject_HEAD int type; + PyObject *dict; +}; + +/* + * surflock module internals + */ +typedef struct { + PyObject_HEAD PyObject *surface; + PyObject *lockobj; + PyObject *weakrefs; +} pgLifetimeLockObject; + +/* + * surface module internals + */ +struct pgSubSurface_Data { + PyObject *owner; + int pixeloffset; + int offsetx, offsety; +}; + +/* + * color module internals + */ +struct pgColorObject { + PyObject_HEAD Uint8 data[4]; + Uint8 len; +}; + +/* + * include public API + */ +#include "include/_pygame.h" + +/* Slot counts. + * Remember to keep these constants up to date. + */ + +#define PYGAMEAPI_RECT_NUMSLOTS 5 +#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2 +#define PYGAMEAPI_DISPLAY_NUMSLOTS 2 +#define PYGAMEAPI_SURFACE_NUMSLOTS 4 +#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8 +#define PYGAMEAPI_RWOBJECT_NUMSLOTS 6 +#define PYGAMEAPI_PIXELARRAY_NUMSLOTS 2 +#define PYGAMEAPI_COLOR_NUMSLOTS 5 +#define PYGAMEAPI_MATH_NUMSLOTS 2 +#define PYGAMEAPI_BASE_NUMSLOTS 27 +#define PYGAMEAPI_EVENT_NUMSLOTS 6 + +#endif /* _PYGAME_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/_surface.h b/.venv/include/site/python3.7/pygame/_surface.h new file mode 100644 index 0000000..b2b4644 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/_surface.h @@ -0,0 +1,30 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef _SURFACE_H +#define _SURFACE_H + +#include "_pygame.h" +#include "surface.h" + +#endif diff --git a/.venv/include/site/python3.7/pygame/camera.h b/.venv/include/site/python3.7/pygame/camera.h new file mode 100644 index 0000000..3079a9a --- /dev/null +++ b/.venv/include/site/python3.7/pygame/camera.h @@ -0,0 +1,252 @@ +#ifndef CAMERA_H +#define CAMERA_H +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "pygame.h" +#include "pgcompat.h" +#include "doc/camera_doc.h" + +#if defined(__unix__) +#include +#include +#include +#include +#include + +#include /* low-level i/o */ +#include +#include +#include +#include +#include +#include +#include + +/* on freebsd there is no asm/types */ +#ifdef linux +#include /* for videodev2.h */ +#endif + +#include +#endif + +#if defined(__WIN32__) +#define PYGAME_WINDOWS_CAMERA 1 + +#include +#include +#include +#include +#include +#include +#endif + +/* some constants used which are not defined on non-v4l machines. */ +#ifndef V4L2_PIX_FMT_RGB24 +#define V4L2_PIX_FMT_RGB24 'RGB3' +#endif +#ifndef V4L2_PIX_FMT_RGB444 +#define V4L2_PIX_FMT_RGB444 'R444' +#endif +#ifndef V4L2_PIX_FMT_YUYV +#define V4L2_PIX_FMT_YUYV 'YUYV' +#endif +#ifndef V4L2_PIX_FMT_XBGR32 +#define V4L2_PIX_FMT_XBGR32 'XR24' +#endif + +#define CLEAR(x) memset(&(x), 0, sizeof(x)) +#define SAT(c) \ + if (c & (~255)) { \ + if (c < 0) \ + c = 0; \ + else \ + c = 255; \ + } +#define SAT2(c) ((c) & (~255) ? ((c) < 0 ? 0 : 255) : (c)) +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 +#define RGB_OUT 1 +#define YUV_OUT 2 +#define HSV_OUT 4 +#define CAM_V4L \ + 1 /* deprecated. the incomplete support in pygame was removed */ +#define CAM_V4L2 2 + +struct buffer { + void *start; + size_t length; +}; + +#if defined(__unix__) +typedef struct pgCameraObject { + PyObject_HEAD char *device_name; + int camera_type; + unsigned long pixelformat; + unsigned int color_out; + struct buffer *buffers; + unsigned int n_buffers; + int width; + int height; + int size; + int hflip; + int vflip; + int brightness; + int fd; +} pgCameraObject; +#elif defined(PYGAME_WINDOWS_CAMERA) +typedef struct pgCameraObject { + PyObject_HEAD WCHAR *device_name; + IMFSourceReader *reader; + IMFTransform *transform; + IMFVideoProcessorControl *control; + IMFMediaBuffer *buf; + IMFMediaBuffer *raw_buf; + int buffer_ready; + short open; /* used to signal the update_function to exit */ + HANDLE t_handle; + HRESULT t_error; + int t_error_line; + int width; + int height; + int hflip; + int vflip; + int last_vflip; + int color_out; + unsigned long pixelformat; +} pgCameraObject; + +#else +/* generic definition. + */ + +typedef struct pgCameraObject { + PyObject_HEAD char *device_name; + int camera_type; + unsigned long pixelformat; + unsigned int color_out; + struct buffer *buffers; + unsigned int n_buffers; + int width; + int height; + int size; + int hflip; + int vflip; + int brightness; + int fd; +} pgCameraObject; +#endif + +/* internal functions for colorspace conversion */ +void +colorspace(SDL_Surface *src, SDL_Surface *dst, int cspace); +void +rgb24_to_rgb(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +bgr32_to_rgb(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +rgb444_to_rgb(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +rgb_to_yuv(const void *src, void *dst, int length, unsigned long source, + SDL_PixelFormat *format); +void +rgb_to_hsv(const void *src, void *dst, int length, unsigned long source, + SDL_PixelFormat *format); +void +yuyv_to_rgb(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +yuyv_to_yuv(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +uyvy_to_rgb(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +uyvy_to_yuv(const void *src, void *dst, int length, SDL_PixelFormat *format); +void +sbggr8_to_rgb(const void *src, void *dst, int width, int height, + SDL_PixelFormat *format); +void +yuv420_to_rgb(const void *src, void *dst, int width, int height, + SDL_PixelFormat *format); +void +yuv420_to_yuv(const void *src, void *dst, int width, int height, + SDL_PixelFormat *format); + +#if defined(__unix__) +/* internal functions specific to v4l2 */ +char ** +v4l2_list_cameras(int *num_devices); +int +v4l2_get_control(int fd, int id, int *value); +int +v4l2_set_control(int fd, int id, int value); +PyObject * +v4l2_read_raw(pgCameraObject *self); +int +v4l2_xioctl(int fd, int request, void *arg); +int +v4l2_process_image(pgCameraObject *self, const void *image, int buffer_size, + SDL_Surface *surf); +int +v4l2_query_buffer(pgCameraObject *self); +int +v4l2_read_frame(pgCameraObject *self, SDL_Surface *surf, int *errno_code); +int +v4l2_stop_capturing(pgCameraObject *self); +int +v4l2_start_capturing(pgCameraObject *self); +int +v4l2_uninit_device(pgCameraObject *self); +int +v4l2_init_mmap(pgCameraObject *self); +int +v4l2_init_device(pgCameraObject *self); +int +v4l2_close_device(pgCameraObject *self); +int +v4l2_open_device(pgCameraObject *self); + +#elif defined(PYGAME_WINDOWS_CAMERA) +/* internal functions specific to WINDOWS */ +WCHAR ** +windows_list_cameras(int *num_devices); +int +windows_init_device(pgCameraObject *self); +int +windows_open_device(pgCameraObject *self); +IMFActivate * +windows_device_from_name(WCHAR *device_name); +int +windows_close_device(pgCameraObject *self); +int +windows_read_frame(pgCameraObject *self, SDL_Surface *surf); +int +windows_frame_ready(pgCameraObject *self, int *result); +PyObject * +windows_read_raw(pgCameraObject *self); +int +windows_process_image(pgCameraObject *self, BYTE *data, DWORD buffer_size, + SDL_Surface *surf); +void +windows_dealloc_device(pgCameraObject *self); +int +windows_init_device(pgCameraObject *self); + +#endif + +#endif /* !CAMERA_H */ diff --git a/.venv/include/site/python3.7/pygame/font.h b/.venv/include/site/python3.7/pygame/font.h new file mode 100644 index 0000000..f5eedb2 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/font.h @@ -0,0 +1,15 @@ +#ifndef PGFONT_INTERNAL_H +#define PGFONT_INTERNAL_H + +#include + +/* test font initialization */ +#define FONT_INIT_CHECK() \ + if (!(*(int *)PyFONT_C_API[2])) \ + return RAISE(pgExc_SDLError, "font system not initialized") + +#include "include/pygame_font.h" + +#define PYGAMEAPI_FONT_NUMSLOTS 3 + +#endif /* ~PGFONT_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/freetype.h b/.venv/include/site/python3.7/pygame/freetype.h new file mode 100644 index 0000000..fd86bc2 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/freetype.h @@ -0,0 +1,114 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef _PYGAME_FREETYPE_INTERNAL_H_ +#define _PYGAME_FREETYPE_INTERNAL_H_ + +#include "pgcompat.h" +#include "pgplatform.h" + +#include +#include FT_FREETYPE_H +#include FT_CACHE_H +#include FT_XFREE86_H +#include FT_TRIGONOMETRY_H + +/********************************************************** + * Global module constants + **********************************************************/ + +/* Render styles */ +#define FT_STYLE_NORMAL 0x00 +#define FT_STYLE_STRONG 0x01 +#define FT_STYLE_OBLIQUE 0x02 +#define FT_STYLE_UNDERLINE 0x04 +#define FT_STYLE_WIDE 0x08 +#define FT_STYLE_DEFAULT 0xFF + +/* Bounding box modes */ +#define FT_BBOX_EXACT FT_GLYPH_BBOX_SUBPIXELS +#define FT_BBOX_EXACT_GRIDFIT FT_GLYPH_BBOX_GRIDFIT +#define FT_BBOX_PIXEL FT_GLYPH_BBOX_TRUNCATE +#define FT_BBOX_PIXEL_GRIDFIT FT_GLYPH_BBOX_PIXELS + +/* Rendering flags */ +#define FT_RFLAG_NONE (0) +#define FT_RFLAG_ANTIALIAS (1 << 0) +#define FT_RFLAG_AUTOHINT (1 << 1) +#define FT_RFLAG_VERTICAL (1 << 2) +#define FT_RFLAG_HINTED (1 << 3) +#define FT_RFLAG_KERNING (1 << 4) +#define FT_RFLAG_TRANSFORM (1 << 5) +#define FT_RFLAG_PAD (1 << 6) +#define FT_RFLAG_ORIGIN (1 << 7) +#define FT_RFLAG_UCS4 (1 << 8) +#define FT_RFLAG_USE_BITMAP_STRIKES (1 << 9) +#define FT_RFLAG_DEFAULTS \ + (FT_RFLAG_HINTED | FT_RFLAG_USE_BITMAP_STRIKES | FT_RFLAG_ANTIALIAS) + +#define FT_RENDER_NEWBYTEARRAY 0x0 +#define FT_RENDER_NEWSURFACE 0x1 +#define FT_RENDER_EXISTINGSURFACE 0x2 + +/********************************************************** + * Global module types + **********************************************************/ + +typedef struct _scale_s { + FT_UInt x, y; +} Scale_t; +typedef FT_Angle Angle_t; + +struct fontinternals_; +struct freetypeinstance_; + +typedef struct { + FT_Long font_index; + FT_Open_Args open_args; +} pgFontId; + +typedef struct { + PyObject_HEAD pgFontId id; + PyObject *path; + int is_scalable; + int is_bg_col_set; + + Scale_t face_size; + FT_Int16 style; + FT_Int16 render_flags; + double strength; + double underline_adjustment; + FT_UInt resolution; + Angle_t rotation; + FT_Matrix transform; + FT_Byte fgcolor[4]; + FT_Byte bgcolor[4]; + + struct freetypeinstance_ *freetype; /* Personal reference */ + struct fontinternals_ *_internals; +} pgFontObject; + +#define pgFont_IS_ALIVE(o) (((pgFontObject *)(o))->_internals != 0) + +/* import public API */ +#include "include/pygame_freetype.h" + +#define PYGAMEAPI_FREETYPE_NUMSLOTS 2 + +#endif /* ~_PYGAME_FREETYPE_INTERNAL_H_ */ diff --git a/.venv/include/site/python3.7/pygame/include/_pygame.h b/.venv/include/site/python3.7/pygame/include/_pygame.h new file mode 100644 index 0000000..4ab06e6 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/_pygame.h @@ -0,0 +1,765 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef _PYGAME_H +#define _PYGAME_H + +/** This header file includes all the definitions for the + ** base pygame extensions. This header only requires + ** Python includes (and SDL.h for functions that use SDL types). + ** The reason for functions prototyped with #define's is + ** to allow for maximum Python portability. It also uses + ** Python as the runtime linker, which allows for late binding. + '' For more information on this style of development, read + ** the Python docs on this subject. + ** http://www.python.org/doc/current/ext/using-cobjects.html + ** + ** If using this to build your own derived extensions, + ** you'll see that the functions available here are mainly + ** used to help convert between python objects and SDL objects. + ** Since this library doesn't add a lot of functionality to + ** the SDL library, it doesn't need to offer a lot either. + ** + ** When initializing your extension module, you must manually + ** import the modules you want to use. (this is the part about + ** using python as the runtime linker). Each module has its + ** own import_xxx() routine. You need to perform this import + ** after you have initialized your own module, and before + ** you call any routines from that module. Since every module + ** in pygame does this, there are plenty of examples. + ** + ** The base module does include some useful conversion routines + ** that you are free to use in your own extension. + **/ + +#include "pgplatform.h" +#include + +/* version macros (defined since version 1.9.5) */ +#define PG_MAJOR_VERSION 2 +#define PG_MINOR_VERSION 5 +#define PG_PATCH_VERSION 0 +#define PG_VERSIONNUM(MAJOR, MINOR, PATCH) \ + (1000 * (MAJOR) + 100 * (MINOR) + (PATCH)) +#define PG_VERSION_ATLEAST(MAJOR, MINOR, PATCH) \ + (PG_VERSIONNUM(PG_MAJOR_VERSION, PG_MINOR_VERSION, PG_PATCH_VERSION) >= \ + PG_VERSIONNUM(MAJOR, MINOR, PATCH)) + +#include "pgcompat.h" + +/* Flag indicating a pg_buffer; used for assertions within callbacks */ +#ifndef NDEBUG +#define PyBUF_PYGAME 0x4000 +#endif +#define PyBUF_HAS_FLAG(f, F) (((f) & (F)) == (F)) + +/* Array information exchange struct C type; inherits from Py_buffer + * + * Pygame uses its own Py_buffer derived C struct as an internal representation + * of an imported array buffer. The extended Py_buffer allows for a + * per-instance release callback, + */ +typedef void (*pybuffer_releaseproc)(Py_buffer *); + +typedef struct pg_bufferinfo_s { + Py_buffer view; + PyObject *consumer; /* Input: Borrowed reference */ + pybuffer_releaseproc release_buffer; +} pg_buffer; + +#include "pgimport.h" + +/* + * BASE module + */ +#ifndef PYGAMEAPI_BASE_INTERNAL +#define pgExc_SDLError ((PyObject *)PYGAMEAPI_GET_SLOT(base, 0)) + +#define pg_RegisterQuit \ + (*(void (*)(void (*)(void)))PYGAMEAPI_GET_SLOT(base, 1)) + +/** + * \brief Convert number like object *obj* to C int and in *val*. + * + * \param obj The Python object to convert. + * \param val A pointer to the C integer to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + * \note This function will convert floats to integers. + */ +#define pg_IntFromObj \ + (*(int (*)(PyObject *, int *))PYGAMEAPI_GET_SLOT(base, 2)) + +/** + * \brief Convert number like object at position *i* in sequence *obj* + * to C int and place in argument *val*. + * + * \param obj The Python object to convert. + * \param i The index of the object to convert. + * \param val A pointer to the C integer to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + * \note This function will convert floats to integers. + */ +#define pg_IntFromObjIndex \ + (*(int (*)(PyObject *, int, int *))PYGAMEAPI_GET_SLOT(base, 3)) + +/** + * \brief Convert the two number like objects in length 2 sequence *obj* to C + * int and place in arguments *val1* and *val2*. + * + * \param obj The Python two element sequence object to convert. + * \param val A pointer to the C integer to store the result. + * \param val2 A pointer to the C integer to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + * \note This function will convert floats to integers. + */ +#define pg_TwoIntsFromObj \ + (*(int (*)(PyObject *, int *, int *))PYGAMEAPI_GET_SLOT(base, 4)) + +/** + * \brief Convert number like object *obj* to C float and in *val*. + * + * \param obj The Python object to convert. + * \param val A pointer to the C float to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + */ +#define pg_FloatFromObj \ + (*(int (*)(PyObject *, float *))PYGAMEAPI_GET_SLOT(base, 5)) + +/** + * \brief Convert number like object at position *i* in sequence *obj* to C + * float and place in argument *val*. + * + * \param obj The Python object to convert. + * \param i The index of the object to convert. + * \param val A pointer to the C float to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + */ +#define pg_FloatFromObjIndex \ + (*(int (*)(PyObject *, int, float *))PYGAMEAPI_GET_SLOT(base, 6)) + +/** + * \brief Convert the two number like objects in length 2 sequence *obj* to C + * float and place in arguments *val1* and *val2*. + * + * \param obj The Python two element sequence object to convert. + * \param val A pointer to the C float to store the result. + * \param val2 A pointer to the C float to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + */ +#define pg_TwoFloatsFromObj \ + (*(int (*)(PyObject *, float *, float *))PYGAMEAPI_GET_SLOT(base, 7)) + +/** + * \brief Convert number like object *obj* to C Uint32 and in *val*. + * + * \param obj The Python object to convert. + * \param val A pointer to the C int to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + */ +#define pg_UintFromObj \ + (*(int (*)(PyObject *, Uint32 *))PYGAMEAPI_GET_SLOT(base, 8)) + +/** + * \brief Convert number like object at position *i* in sequence *obj* to C + * Uint32 and place in argument *val*. + * + * \param obj The Python object to convert. + * \param i The index of the object to convert. + * \param val A pointer to the C int to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + */ +#define pg_UintFromObjIndex \ + (*(int (*)(PyObject *, int, Uint32 *))PYGAMEAPI_GET_SLOT(base, 9)) + +/** + * \brief Initialize all of the pygame modules. + * \returns 1 on success, 0 on failure with PyErr set. + */ +#define pg_mod_autoinit (*(int (*)(const char *))PYGAMEAPI_GET_SLOT(base, 10)) + +/** + * \brief Quit all of the pygame modules. + */ +#define pg_mod_autoquit (*(void (*)(const char *))PYGAMEAPI_GET_SLOT(base, 11)) + +/** + * \brief Convert the color represented by object *obj* into a red, green, + * blue, alpha length 4 C array *RGBA*. + * + * The object must be a length 3 or 4 sequence of numbers having values between + * 0 and 255 inclusive. For a length 3 sequence an alpha value of 255 is + * assumed. + * + * \param obj The Python object to convert. + * \param RGBA A pointer to the C array to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + */ +#define pg_RGBAFromObj \ + (*(int (*)(PyObject *, Uint8 *))PYGAMEAPI_GET_SLOT(base, 12)) + +/** + * \brief Given a Py_buffer, return a python dictionary representing the array + * interface. + * + * \param view_p A pointer to the Py_buffer to convert to a dictionary. + * + * \returns A Python dictionary representing the array interface of the object. + */ +#define pgBuffer_AsArrayInterface \ + (*(PyObject * (*)(Py_buffer *)) PYGAMEAPI_GET_SLOT(base, 13)) + +/** + * \brief Given a Py_buffer, return a python capsule representing the array + * interface. + * + * \param view_p A pointer to the Py_buffer to convert to a capsule. + * + * \returns A Python capsule representing the array interface of the object. + */ +#define pgBuffer_AsArrayStruct \ + (*(PyObject * (*)(Py_buffer *)) PYGAMEAPI_GET_SLOT(base, 14)) + +/** + * \brief Get a buffer object from a given Python object. + * + * \param obj The Python object to get the buffer from. + * \param pg_view_p A pointer to a pg_buffer struct to store the buffer in. + * \param flags The desired buffer access mode. + * + * \returns 0 on success, -1 on failure. + * + * \note This function attempts to get a buffer object from a given Python + * object. If the object supports the buffer protocol, it will be used to + * create the buffer. If not, it will try to get an array interface or + * dictionary representation of the object and use that to create the buffer. + * If none of these methods work, it will raise a ValueError. + * + */ +#define pgObject_GetBuffer \ + (*(int (*)(PyObject *, pg_buffer *, int))PYGAMEAPI_GET_SLOT(base, 15)) + +/** + * \brief Release a pg_buffer object. + * + * \param pg_view_p The pg_buffer object to release. + * + * \note This function releases a pg_buffer object. + * \note some calls to this function expect this function to not clear + * previously set errors. + */ +#define pgBuffer_Release (*(void (*)(pg_buffer *))PYGAMEAPI_GET_SLOT(base, 16)) + +/** + * \brief Write the array interface dictionary buffer description *dict* into a + * Pygame buffer description struct *pg_view_p*. + * + * \param pg_view_p The Pygame buffer description struct to write into. + * \param dict The array interface dictionary to read from. + * \param flags The PyBUF flags describing the view type requested. + * + * \returns 0 on success, or -1 on failure. + */ +#define pgDict_AsBuffer \ + (*(int (*)(pg_buffer *, PyObject *, int))PYGAMEAPI_GET_SLOT(base, 17)) + +#define pgExc_BufferError ((PyObject *)PYGAMEAPI_GET_SLOT(base, 18)) + +/** + * \brief Get the default SDL window created by a pygame.display.set_mode() + * call, or *NULL*. + * + * \return The default window, or *NULL* if no window has been created. + */ +#define pg_GetDefaultWindow \ + (*(SDL_Window * (*)(void)) PYGAMEAPI_GET_SLOT(base, 19)) + +/** + * \brief Set the default SDL window created by a pygame.display.set_mode() + * call. The previous window, if any, is destroyed. Argument *win* may be + * *NULL*. This function is called by pygame.display.set_mode(). + * + * \param win The new default window. May be NULL. + */ +#define pg_SetDefaultWindow \ + (*(void (*)(SDL_Window *))PYGAMEAPI_GET_SLOT(base, 20)) + +/** + * \brief Return a borrowed reference to the Pygame default window display + * surface, or *NULL* if no default window is open. + * + * \return The default renderer, or *NULL* if no renderer has been created. + */ +#define pg_GetDefaultWindowSurface \ + (*(pgSurfaceObject * (*)(void)) PYGAMEAPI_GET_SLOT(base, 21)) + +/** + * \brief Set the Pygame default window display surface. The previous + * surface, if any, is destroyed. Argument *screen* may be *NULL*. This + * function is called by pygame.display.set_mode(). + * + * \param screen The new default window display surface. May be NULL. + */ +#define pg_SetDefaultWindowSurface \ + (*(void (*)(pgSurfaceObject *))PYGAMEAPI_GET_SLOT(base, 22)) + +/** + * \returns NULL if the environment variable PYGAME_BLEND_ALPHA_SDL2 is not + * set, otherwise returns a pointer to the environment variable. + */ +#define pg_EnvShouldBlendAlphaSDL2 \ + (*(char *(*)(void))PYGAMEAPI_GET_SLOT(base, 23)) + +/** + * \brief Convert number like object *obj* to C double and in *val*. + * + * \param obj The Python object to convert. + * \param val A pointer to the C double to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + */ +#define pg_DoubleFromObj \ + (*(int (*)(PyObject *, double *))PYGAMEAPI_GET_SLOT(base, 24)) + +/** + * \brief Convert number like object at position *i* in sequence *obj* to C + * double and place in argument *val*. + * + * \param obj The Python object to convert. + * \param i The index of the object to convert. + * \param val A pointer to the C double to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + * + * \note This function will clear any Python errors. + */ +#define pg_DoubleFromObjIndex \ + (*(int (*)(PyObject *, int, double *))PYGAMEAPI_GET_SLOT(base, 25)) + +/** + * \brief Convert the two number like objects in length 2 sequence *obj* to C + * double and place in arguments *val1* and *val2*. + * + * \param obj The Python two element sequence object to convert. + * \param val A pointer to the C double to store the result. + * \param val2 A pointer to the C double to store the result. + * \returns 1 if the conversion was successful, 0 otherwise. + */ +#define pg_TwoDoublesFromObj \ + (*(int (*)(PyObject *, double *, double *))PYGAMEAPI_GET_SLOT(base, 26)) + +#define import_pygame_base() IMPORT_PYGAME_MODULE(base) +#endif /* ~PYGAMEAPI_BASE_INTERNAL */ + +typedef struct { + PyObject_HEAD SDL_Rect r; + PyObject *weakreflist; +} pgRectObject; + +#define pgRect_AsRect(x) (((pgRectObject *)x)->r) +#ifndef PYGAMEAPI_RECT_INTERNAL +#define pgRect_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(rect, 0)) + +#define pgRect_Check(x) ((x)->ob_type == &pgRect_Type) +#define pgRect_New (*(PyObject * (*)(SDL_Rect *)) PYGAMEAPI_GET_SLOT(rect, 1)) + +#define pgRect_New4 \ + (*(PyObject * (*)(int, int, int, int)) PYGAMEAPI_GET_SLOT(rect, 2)) + +#define pgRect_FromObject \ + (*(SDL_Rect * (*)(PyObject *, SDL_Rect *)) PYGAMEAPI_GET_SLOT(rect, 3)) + +#define pgRect_Normalize (*(void (*)(SDL_Rect *))PYGAMEAPI_GET_SLOT(rect, 4)) + +#define import_pygame_rect() IMPORT_PYGAME_MODULE(rect) +#endif /* ~PYGAMEAPI_RECT_INTERNAL */ + +/* + * JOYSTICK module + */ +typedef struct pgJoystickObject { + PyObject_HEAD int id; + SDL_Joystick *joy; + + /* Joysticks form an intrusive linked list. + * + * Note that we don't maintain refcounts for these so they are weakrefs + * from the Python side. + */ + struct pgJoystickObject *next; + struct pgJoystickObject *prev; +} pgJoystickObject; + +#define pgJoystick_AsID(x) (((pgJoystickObject *)x)->id) +#define pgJoystick_AsSDL(x) (((pgJoystickObject *)x)->joy) + +#ifndef PYGAMEAPI_JOYSTICK_INTERNAL +#define pgJoystick_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(joystick, 0)) + +#define pgJoystick_Check(x) ((x)->ob_type == &pgJoystick_Type) +#define pgJoystick_New (*(PyObject * (*)(int)) PYGAMEAPI_GET_SLOT(joystick, 1)) + +#define import_pygame_joystick() IMPORT_PYGAME_MODULE(joystick) +#endif + +/* + * DISPLAY module + */ + +typedef struct { + Uint32 hw_available : 1; + Uint32 wm_available : 1; + Uint32 blit_hw : 1; + Uint32 blit_hw_CC : 1; + Uint32 blit_hw_A : 1; + Uint32 blit_sw : 1; + Uint32 blit_sw_CC : 1; + Uint32 blit_sw_A : 1; + Uint32 blit_fill : 1; + Uint32 video_mem; + SDL_PixelFormat *vfmt; + SDL_PixelFormat vfmt_data; + int current_w; + int current_h; +} pg_VideoInfo; + +typedef struct { + PyObject_HEAD pg_VideoInfo info; +} pgVidInfoObject; + +#define pgVidInfo_AsVidInfo(x) (((pgVidInfoObject *)x)->info) + +#ifndef PYGAMEAPI_DISPLAY_INTERNAL +#define pgVidInfo_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(display, 0)) + +#define pgVidInfo_Check(x) ((x)->ob_type == &pgVidInfo_Type) +#define pgVidInfo_New \ + (*(PyObject * (*)(pg_VideoInfo *)) PYGAMEAPI_GET_SLOT(display, 1)) + +#define import_pygame_display() IMPORT_PYGAME_MODULE(display) +#endif /* ~PYGAMEAPI_DISPLAY_INTERNAL */ + +/* + * SURFACE module + */ +struct pgSubSurface_Data; +struct SDL_Surface; + +typedef struct { + PyObject_HEAD struct SDL_Surface *surf; + int owner; + struct pgSubSurface_Data *subsurface; /* ptr to subsurface data (if a + * subsurface)*/ + PyObject *weakreflist; + PyObject *locklist; + PyObject *dependency; +} pgSurfaceObject; +#define pgSurface_AsSurface(x) (((pgSurfaceObject *)x)->surf) + +#ifndef PYGAMEAPI_SURFACE_INTERNAL +#define pgSurface_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(surface, 0)) + +#define pgSurface_Check(x) \ + (PyObject_IsInstance((x), (PyObject *)&pgSurface_Type)) +#define pgSurface_New2 \ + (*(pgSurfaceObject * (*)(SDL_Surface *, int)) \ + PYGAMEAPI_GET_SLOT(surface, 1)) + +#define pgSurface_SetSurface \ + (*(int (*)(pgSurfaceObject *, SDL_Surface *, int))PYGAMEAPI_GET_SLOT( \ + surface, 3)) + +#define pgSurface_Blit \ + (*(int (*)(pgSurfaceObject *, pgSurfaceObject *, SDL_Rect *, SDL_Rect *, \ + int))PYGAMEAPI_GET_SLOT(surface, 2)) + +#define import_pygame_surface() \ + do { \ + IMPORT_PYGAME_MODULE(surface); \ + if (PyErr_Occurred() != NULL) \ + break; \ + IMPORT_PYGAME_MODULE(surflock); \ + } while (0) + +#define pgSurface_New(surface) pgSurface_New2((surface), 1) +#define pgSurface_NewNoOwn(surface) pgSurface_New2((surface), 0) + +#endif /* ~PYGAMEAPI_SURFACE_INTERNAL */ + +/* + * SURFLOCK module + * auto imported/initialized by surface + */ +#ifndef PYGAMEAPI_SURFLOCK_INTERNAL +#define pgLifetimeLock_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(surflock, 0)) + +#define pgLifetimeLock_Check(x) ((x)->ob_type == &pgLifetimeLock_Type) + +#define pgSurface_Prep(x) \ + if ((x)->subsurface) \ + (*(*(void (*)(pgSurfaceObject *))PYGAMEAPI_GET_SLOT(surflock, 1)))(x) + +#define pgSurface_Unprep(x) \ + if ((x)->subsurface) \ + (*(*(void (*)(pgSurfaceObject *))PYGAMEAPI_GET_SLOT(surflock, 2)))(x) + +#define pgSurface_Lock \ + (*(int (*)(pgSurfaceObject *))PYGAMEAPI_GET_SLOT(surflock, 3)) + +#define pgSurface_Unlock \ + (*(int (*)(pgSurfaceObject *))PYGAMEAPI_GET_SLOT(surflock, 4)) + +#define pgSurface_LockBy \ + (*(int (*)(pgSurfaceObject *, PyObject *))PYGAMEAPI_GET_SLOT(surflock, 5)) + +#define pgSurface_UnlockBy \ + (*(int (*)(pgSurfaceObject *, PyObject *))PYGAMEAPI_GET_SLOT(surflock, 6)) + +#define pgSurface_LockLifetime \ + (*(PyObject * (*)(PyObject *, PyObject *)) PYGAMEAPI_GET_SLOT(surflock, 7)) +#endif + +/* + * EVENT module + */ +typedef struct pgEventObject pgEventObject; + +#ifndef PYGAMEAPI_EVENT_INTERNAL +#define pgEvent_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(event, 0)) + +#define pgEvent_Check(x) ((x)->ob_type == &pgEvent_Type) + +#define pgEvent_New \ + (*(PyObject * (*)(SDL_Event *)) PYGAMEAPI_GET_SLOT(event, 1)) + +#define pgEvent_New2 \ + (*(PyObject * (*)(int, PyObject *)) PYGAMEAPI_GET_SLOT(event, 2)) + +#define pgEvent_FillUserEvent \ + (*(int (*)(pgEventObject *, SDL_Event *))PYGAMEAPI_GET_SLOT(event, 3)) + +#define pg_EnableKeyRepeat (*(int (*)(int, int))PYGAMEAPI_GET_SLOT(event, 4)) + +#define pg_GetKeyRepeat (*(void (*)(int *, int *))PYGAMEAPI_GET_SLOT(event, 5)) + +#define import_pygame_event() IMPORT_PYGAME_MODULE(event) +#endif + +/* + * RWOBJECT module + * the rwobject are only needed for C side work, not accessible from python. + */ +#ifndef PYGAMEAPI_RWOBJECT_INTERNAL +#define pgRWops_FromObject \ + (*(SDL_RWops * (*)(PyObject *, char **)) PYGAMEAPI_GET_SLOT(rwobject, 0)) + +#define pgRWops_IsFileObject \ + (*(int (*)(SDL_RWops *))PYGAMEAPI_GET_SLOT(rwobject, 1)) + +#define pg_EncodeFilePath \ + (*(PyObject * (*)(PyObject *, PyObject *)) PYGAMEAPI_GET_SLOT(rwobject, 2)) + +#define pg_EncodeString \ + (*(PyObject * (*)(PyObject *, const char *, const char *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 3)) + +#define pgRWops_FromFileObject \ + (*(SDL_RWops * (*)(PyObject *)) PYGAMEAPI_GET_SLOT(rwobject, 4)) + +#define pgRWops_ReleaseObject \ + (*(int (*)(SDL_RWops *))PYGAMEAPI_GET_SLOT(rwobject, 5)) + +#define import_pygame_rwobject() IMPORT_PYGAME_MODULE(rwobject) + +#endif + +/* + * PixelArray module + */ +#ifndef PYGAMEAPI_PIXELARRAY_INTERNAL +#define PyPixelArray_Type ((PyTypeObject *)PYGAMEAPI_GET_SLOT(pixelarray, 0)) + +#define PyPixelArray_Check(x) ((x)->ob_type == &PyPixelArray_Type) +#define PyPixelArray_New (*(PyObject * (*)) PYGAMEAPI_GET_SLOT(pixelarray, 1)) + +#define import_pygame_pixelarray() IMPORT_PYGAME_MODULE(pixelarray) +#endif /* PYGAMEAPI_PIXELARRAY_INTERNAL */ + +/* + * Color module + */ +typedef struct pgColorObject pgColorObject; + +#ifndef PYGAMEAPI_COLOR_INTERNAL +#define pgColor_Type (*(PyObject *)PYGAMEAPI_GET_SLOT(color, 0)) + +#define pgColor_Check(x) ((x)->ob_type == &pgColor_Type) +#define pgColor_New (*(PyObject * (*)(Uint8 *)) PYGAMEAPI_GET_SLOT(color, 1)) + +#define pgColor_NewLength \ + (*(PyObject * (*)(Uint8 *, Uint8)) PYGAMEAPI_GET_SLOT(color, 3)) + +#define pg_RGBAFromColorObj \ + (*(int (*)(PyObject *, Uint8 *))PYGAMEAPI_GET_SLOT(color, 2)) + +#define pg_RGBAFromFuzzyColorObj \ + (*(int (*)(PyObject *, Uint8 *))PYGAMEAPI_GET_SLOT(color, 4)) + +#define pgColor_AsArray(x) (((pgColorObject *)x)->data) +#define pgColor_NumComponents(x) (((pgColorObject *)x)->len) + +#define import_pygame_color() IMPORT_PYGAME_MODULE(color) +#endif /* PYGAMEAPI_COLOR_INTERNAL */ + +/* + * Math module + */ +#ifndef PYGAMEAPI_MATH_INTERNAL +#define pgVector2_Check(x) \ + ((x)->ob_type == (PyTypeObject *)PYGAMEAPI_GET_SLOT(math, 0)) + +#define pgVector3_Check(x) \ + ((x)->ob_type == (PyTypeObject *)PYGAMEAPI_GET_SLOT(math, 1)) +/* +#define pgVector2_New \ + (*(PyObject*(*)) \ + PYGAMEAPI_GET_SLOT(PyGAME_C_API, 1)) +*/ +#define import_pygame_math() IMPORT_PYGAME_MODULE(math) +#endif /* PYGAMEAPI_MATH_INTERNAL */ + +#define IMPORT_PYGAME_MODULE _IMPORT_PYGAME_MODULE + +/* + * base pygame API slots + * disable slots with NO_PYGAME_C_API + */ +#ifdef PYGAME_H +PYGAMEAPI_DEFINE_SLOTS(base); +PYGAMEAPI_DEFINE_SLOTS(rect); +PYGAMEAPI_DEFINE_SLOTS(cdrom); +PYGAMEAPI_DEFINE_SLOTS(joystick); +PYGAMEAPI_DEFINE_SLOTS(display); +PYGAMEAPI_DEFINE_SLOTS(surface); +PYGAMEAPI_DEFINE_SLOTS(surflock); +PYGAMEAPI_DEFINE_SLOTS(event); +PYGAMEAPI_DEFINE_SLOTS(rwobject); +PYGAMEAPI_DEFINE_SLOTS(pixelarray); +PYGAMEAPI_DEFINE_SLOTS(color); +PYGAMEAPI_DEFINE_SLOTS(math); +#else /* ~PYGAME_H */ +PYGAMEAPI_EXTERN_SLOTS(base); +PYGAMEAPI_EXTERN_SLOTS(rect); +PYGAMEAPI_EXTERN_SLOTS(cdrom); +PYGAMEAPI_EXTERN_SLOTS(joystick); +PYGAMEAPI_EXTERN_SLOTS(display); +PYGAMEAPI_EXTERN_SLOTS(surface); +PYGAMEAPI_EXTERN_SLOTS(surflock); +PYGAMEAPI_EXTERN_SLOTS(event); +PYGAMEAPI_EXTERN_SLOTS(rwobject); +PYGAMEAPI_EXTERN_SLOTS(pixelarray); +PYGAMEAPI_EXTERN_SLOTS(color); +PYGAMEAPI_EXTERN_SLOTS(math); +#endif /* ~PYGAME_H */ + +#endif /* PYGAME_H */ + +/* Use the end of this file for other cross module inline utility + * functions There seems to be no good reason to stick to macro only + * functions in Python 3. + */ + +static PG_INLINE PyObject * +pg_tuple_couple_from_values_int(int val1, int val2) +{ + /* This function turns two input integers into a python tuple object. + * Currently, 5th November 2022, this is faster than using Py_BuildValue + * to do the same thing. + */ + PyObject *tup = PyTuple_New(2); + if (!tup) { + return NULL; + } + + PyObject *tmp = PyLong_FromLong(val1); + if (!tmp) { + Py_DECREF(tup); + return NULL; + } + PyTuple_SET_ITEM(tup, 0, tmp); + + tmp = PyLong_FromLong(val2); + if (!tmp) { + Py_DECREF(tup); + return NULL; + } + PyTuple_SET_ITEM(tup, 1, tmp); + + return tup; +} + +static PG_INLINE PyObject * +pg_tuple_triple_from_values_int(int val1, int val2, int val3) +{ + /* This function turns three input integers into a python tuple object. + * Currently, 5th November 2022, this is faster than using Py_BuildValue + * to do the same thing. + */ + PyObject *tup = PyTuple_New(3); + if (!tup) { + return NULL; + } + + PyObject *tmp = PyLong_FromLong(val1); + if (!tmp) { + Py_DECREF(tup); + return NULL; + } + PyTuple_SET_ITEM(tup, 0, tmp); + + tmp = PyLong_FromLong(val2); + if (!tmp) { + Py_DECREF(tup); + return NULL; + } + PyTuple_SET_ITEM(tup, 1, tmp); + + tmp = PyLong_FromLong(val3); + if (!tmp) { + Py_DECREF(tup); + return NULL; + } + PyTuple_SET_ITEM(tup, 2, tmp); + + return tup; +} diff --git a/.venv/include/site/python3.7/pygame/include/bitmask.h b/.venv/include/site/python3.7/pygame/include/bitmask.h new file mode 100644 index 0000000..eee09b7 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/bitmask.h @@ -0,0 +1,171 @@ +/* + Bitmask 1.7 - A pixel-perfect collision detection library. + + Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount + function which is copyright (C) Donald W. Gillies, 1992. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef BITMASK_H +#define BITMASK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* Define INLINE for different compilers. If your compiler does not + support inlining then there might be a performance hit in + bitmask_overlap_area(). +*/ +#ifndef INLINE +#ifdef __GNUC__ +#define INLINE inline +#else +#ifdef _MSC_VER +#define INLINE __inline +#else +#define INLINE +#endif +#endif +#endif + +#define BITMASK_W unsigned long int +#define BITMASK_W_LEN (sizeof(BITMASK_W) * CHAR_BIT) +#define BITMASK_W_MASK (BITMASK_W_LEN - 1) +#define BITMASK_N(n) ((BITMASK_W)1 << (n)) + +typedef struct bitmask { + int w, h; + BITMASK_W bits[1]; +} bitmask_t; + +/* Creates a bitmask of width w and height h, where + w and h must both be greater than or equal to 0. + The mask is automatically cleared when created. + */ +bitmask_t * +bitmask_create(int w, int h); + +/* Frees all the memory allocated by bitmask_create for m. */ +void +bitmask_free(bitmask_t *m); + +/* Create a copy of the given bitmask. */ +bitmask_t * +bitmask_copy(bitmask_t *m); + +/* Clears all bits in the mask */ +void +bitmask_clear(bitmask_t *m); + +/* Sets all bits in the mask */ +void +bitmask_fill(bitmask_t *m); + +/* Flips all bits in the mask */ +void +bitmask_invert(bitmask_t *m); + +/* Counts the bits in the mask */ +unsigned int +bitmask_count(bitmask_t *m); + +/* Returns nonzero if the bit at (x,y) is set. Coordinates start at + (0,0) */ +static INLINE int +bitmask_getbit(const bitmask_t *m, int x, int y) +{ + return (m->bits[x / BITMASK_W_LEN * m->h + y] & + BITMASK_N(x & BITMASK_W_MASK)) != 0; +} + +/* Sets the bit at (x,y) */ +static INLINE void +bitmask_setbit(bitmask_t *m, int x, int y) +{ + m->bits[x / BITMASK_W_LEN * m->h + y] |= BITMASK_N(x & BITMASK_W_MASK); +} + +/* Clears the bit at (x,y) */ +static INLINE void +bitmask_clearbit(bitmask_t *m, int x, int y) +{ + m->bits[x / BITMASK_W_LEN * m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK); +} + +/* Returns nonzero if the masks overlap with the given offset. + The overlap tests uses the following offsets (which may be negative): + + +----+----------.. + |A | yoffset + | +-+----------.. + +--|B + |xoffset + | | + : : +*/ +int +bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, + int yoffset); + +/* Like bitmask_overlap(), but will also give a point of intersection. + x and y are given in the coordinates of mask a, and are untouched + if there is no overlap. */ +int +bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b, int xoffset, + int yoffset, int *x, int *y); + +/* Returns the number of overlapping 'pixels' */ +int +bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, + int yoffset); + +/* Fills a mask with the overlap of two other masks. A bitwise AND. */ +void +bitmask_overlap_mask(const bitmask_t *a, const bitmask_t *b, bitmask_t *c, + int xoffset, int yoffset); + +/* Draws mask b onto mask a (bitwise OR). Can be used to compose large + (game background?) mask from several submasks, which may speed up + the testing. */ + +void +bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +void +bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Return a new scaled bitmask, with dimensions w*h. The quality of the + scaling may not be perfect for all circumstances, but it should + be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */ +bitmask_t * +bitmask_scale(const bitmask_t *m, int w, int h); + +/* Convolve b into a, drawing the output into o, shifted by offset. If offset + * is 0, then the (x,y) bit will be set if and only if + * bitmask_overlap(a, b, x - b->w - 1, y - b->h - 1) returns true. + * + * Modifies bits o[xoffset ... xoffset + a->w + b->w - 1) + * [yoffset ... yoffset + a->h + b->h - 1). */ +void +bitmask_convolve(const bitmask_t *a, const bitmask_t *b, bitmask_t *o, + int xoffset, int yoffset); + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif + +#endif diff --git a/.venv/include/site/python3.7/pygame/include/pgcompat.h b/.venv/include/site/python3.7/pygame/include/pgcompat.h new file mode 100644 index 0000000..3c09099 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pgcompat.h @@ -0,0 +1,102 @@ +#if !defined(PGCOMPAT_H) +#define PGCOMPAT_H + +#include + +/* In CPython, Py_Exit finalises the python interpreter before calling C exit() + * This does not exist on PyPy, so use exit() directly here */ +#ifdef PYPY_VERSION +#define PG_EXIT(n) exit(n) +#else +#define PG_EXIT(n) Py_Exit(n) +#endif + +/* define common types where SDL is not included */ +#ifndef SDL_VERSION_ATLEAST +#ifdef _MSC_VER +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif +typedef uint32_t Uint32; +typedef uint8_t Uint8; +#endif /* no SDL */ + +#if defined(SDL_VERSION_ATLEAST) + +#ifndef SDL_WINDOW_VULKAN +#define SDL_WINDOW_VULKAN 0 +#endif + +#ifndef SDL_WINDOW_ALWAYS_ON_TOP +#define SDL_WINDOW_ALWAYS_ON_TOP 0 +#endif + +#ifndef SDL_WINDOW_SKIP_TASKBAR +#define SDL_WINDOW_SKIP_TASKBAR 0 +#endif + +#ifndef SDL_WINDOW_UTILITY +#define SDL_WINDOW_UTILITY 0 +#endif + +#ifndef SDL_WINDOW_TOOLTIP +#define SDL_WINDOW_TOOLTIP 0 +#endif + +#ifndef SDL_WINDOW_POPUP_MENU +#define SDL_WINDOW_POPUP_MENU 0 +#endif + +#ifndef SDL_WINDOW_INPUT_GRABBED +#define SDL_WINDOW_INPUT_GRABBED 0 +#endif + +#ifndef SDL_WINDOW_INPUT_FOCUS +#define SDL_WINDOW_INPUT_FOCUS 0 +#endif + +#ifndef SDL_WINDOW_MOUSE_FOCUS +#define SDL_WINDOW_MOUSE_FOCUS 0 +#endif + +#ifndef SDL_WINDOW_FOREIGN +#define SDL_WINDOW_FOREIGN 0 +#endif + +#ifndef SDL_WINDOW_ALLOW_HIGHDPI +#define SDL_WINDOW_ALLOW_HIGHDPI 0 +#endif + +#ifndef SDL_WINDOW_MOUSE_CAPTURE +#define SDL_WINDOW_MOUSE_CAPTURE 0 +#endif + +#ifndef SDL_WINDOW_ALWAYS_ON_TOP +#define SDL_WINDOW_ALWAYS_ON_TOP 0 +#endif + +#ifndef SDL_WINDOW_SKIP_TASKBAR +#define SDL_WINDOW_SKIP_TASKBAR 0 +#endif + +#ifndef SDL_WINDOW_UTILITY +#define SDL_WINDOW_UTILITY 0 +#endif + +#ifndef SDL_WINDOW_TOOLTIP +#define SDL_WINDOW_TOOLTIP 0 +#endif + +#ifndef SDL_WINDOW_POPUP_MENU +#define SDL_WINDOW_POPUP_MENU 0 +#endif + +#ifndef SDL_MOUSEWHEEL_FLIPPED +#define NO_SDL_MOUSEWHEEL_FLIPPED +#endif + +#endif /* defined(SDL_VERSION_ATLEAST) */ + +#endif /* ~defined(PGCOMPAT_H) */ diff --git a/.venv/include/site/python3.7/pygame/include/pgimport.h b/.venv/include/site/python3.7/pygame/include/pgimport.h new file mode 100644 index 0000000..2c2e8cf --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pgimport.h @@ -0,0 +1,67 @@ +#ifndef PGIMPORT_H +#define PGIMPORT_H + +/* Prefix when importing module */ +#define IMPPREFIX "pygame." + +#include "pgcompat.h" + +#define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API" +#define PG_CAPSULE_NAME(m) (IMPPREFIX m "." PYGAMEAPI_LOCAL_ENTRY) + +/* + * fill API slots defined by PYGAMEAPI_DEFINE_SLOTS/PYGAMEAPI_EXTERN_SLOTS + */ +#define _IMPORT_PYGAME_MODULE(module) \ + { \ + PyObject *_mod_##module = PyImport_ImportModule(IMPPREFIX #module); \ + \ + if (_mod_##module != NULL) { \ + PyObject *_c_api = \ + PyObject_GetAttrString(_mod_##module, PYGAMEAPI_LOCAL_ENTRY); \ + \ + Py_DECREF(_mod_##module); \ + if (_c_api != NULL && PyCapsule_CheckExact(_c_api)) { \ + void **localptr = (void **)PyCapsule_GetPointer( \ + _c_api, PG_CAPSULE_NAME(#module)); \ + _PGSLOTS_##module = localptr; \ + } \ + Py_XDECREF(_c_api); \ + } \ + } + +#define PYGAMEAPI_IS_IMPORTED(module) (_PGSLOTS_##module != NULL) + +/* + * source file must include one of these in order to use _IMPORT_PYGAME_MODULE. + * this is set by import_pygame_*() functions. + * disable with NO_PYGAME_C_API + */ +#define PYGAMEAPI_DEFINE_SLOTS(module) void **_PGSLOTS_##module = NULL +#define PYGAMEAPI_EXTERN_SLOTS(module) extern void **_PGSLOTS_##module +#define PYGAMEAPI_GET_SLOT(module, index) _PGSLOTS_##module[(index)] + +/* + * disabled API with NO_PYGAME_C_API; do nothing instead + */ +#ifdef NO_PYGAME_C_API + +#undef PYGAMEAPI_DEFINE_SLOTS +#undef PYGAMEAPI_EXTERN_SLOTS + +#define PYGAMEAPI_DEFINE_SLOTS(module) +#define PYGAMEAPI_EXTERN_SLOTS(module) + +/* intentionally leave this defined to cause a compiler error * +#define PYGAMEAPI_GET_SLOT(api_root, index) +#undef PYGAMEAPI_GET_SLOT*/ + +#undef _IMPORT_PYGAME_MODULE +#define _IMPORT_PYGAME_MODULE(module) + +#endif /* NO_PYGAME_C_API */ + +#define encapsulate_api(ptr, module) \ + PyCapsule_New(ptr, PG_CAPSULE_NAME(module), NULL) + +#endif /* ~PGIMPORT_H */ diff --git a/.venv/include/site/python3.7/pygame/include/pgplatform.h b/.venv/include/site/python3.7/pygame/include/pgplatform.h new file mode 100644 index 0000000..4c299da --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pgplatform.h @@ -0,0 +1,87 @@ +/* platform/compiler adjustments */ +#ifndef PG_PLATFORM_H +#define PG_PLATFORM_H + +#if defined(HAVE_SNPRINTF) /* defined in python.h (pyerrors.h) and SDL.h \ + (SDL_config.h) */ +#undef HAVE_SNPRINTF /* remove GCC redefine warning */ +#endif /* HAVE_SNPRINTF */ + +#ifndef PG_INLINE +#if defined(__clang__) +#define PG_INLINE __inline__ __attribute__((__unused__)) +#elif defined(__GNUC__) +#define PG_INLINE __inline__ +#elif defined(_MSC_VER) +#define PG_INLINE __inline +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define PG_INLINE inline +#else +#define PG_INLINE +#endif +#endif /* ~PG_INLINE */ + +// Worth trying this on MSVC/win32 builds to see if provides any speed up +#ifndef PG_FORCEINLINE +#if defined(__clang__) +#define PG_FORCEINLINE __inline__ __attribute__((__unused__)) +#elif defined(__GNUC__) +#define PG_FORCEINLINE __inline__ +#elif defined(_MSC_VER) +#define PG_FORCEINLINE __forceinline +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define PG_FORCEINLINE inline +#else +#define PG_FORCEINLINE +#endif +#endif /* ~PG_FORCEINLINE */ + +/* This is unconditionally defined in Python.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +#if defined(HAVE_SNPRINTF) +#undef HAVE_SNPRINTF +#endif + +/* SDL needs WIN32 */ +#if !defined(WIN32) && \ + (defined(MS_WIN32) || defined(_WIN32) || defined(__WIN32) || \ + defined(__WIN32__) || defined(_WINDOWS)) +#define WIN32 +#endif + +/* Commenting out SSE4_2 stuff because it does not do runtime detection. +#ifndef PG_TARGET_SSE4_2 +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ == 4 && +__GNUC_MINOR__ >= 9) || __GNUC__ >= 5 )) +//The old gcc 4.8 on centos used by manylinux1 does not seem to get sse4.2 +intrinsics #define PG_FUNCTION_TARGET_SSE4_2 __attribute__((target("sse4.2"))) +// No else; we define the fallback later +#endif +#endif +*/ +/* ~PG_TARGET_SSE4_2 */ + +/* +#ifdef PG_FUNCTION_TARGET_SSE4_2 +#if !defined(__SSE4_2__) && !defined(PG_COMPILE_SSE4_2) +#if defined(__x86_64__) || defined(__i386__) +#define PG_COMPILE_SSE4_2 1 +#endif +#endif +#endif +*/ +/* ~PG_TARGET_SSE4_2 */ + +/* Fallback definition of target attribute */ +#ifndef PG_FUNCTION_TARGET_SSE4_2 +#define PG_FUNCTION_TARGET_SSE4_2 +#endif + +#ifndef PG_COMPILE_SSE4_2 +#define PG_COMPILE_SSE4_2 0 +#endif + +#endif /* ~PG_PLATFORM_H */ diff --git a/.venv/include/site/python3.7/pygame/include/pygame.h b/.venv/include/site/python3.7/pygame/include/pygame.h new file mode 100644 index 0000000..3772ae6 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame.h @@ -0,0 +1,34 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* To allow the Pygame C api to be globally shared by all code within an + * extension module built from multiple C files, only include the pygame.h + * header within the top level C file, the one which calls the + * 'import_pygame_*' macros. All other C source files of the module should + * include _pygame.h instead. + */ +#ifndef PYGAME_H +#define PYGAME_H + +#include "_pygame.h" + +#endif diff --git a/.venv/include/site/python3.7/pygame/include/pygame_bufferproxy.h b/.venv/include/site/python3.7/pygame/include/pygame_bufferproxy.h new file mode 100644 index 0000000..9284ff2 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame_bufferproxy.h @@ -0,0 +1,56 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Rene Dudfield, Richard Goedeken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* Bufferproxy module C api. */ +#if !defined(PG_BUFPROXY_HEADER) +#define PG_BUFPROXY_HEADER + +#include + +typedef PyObject *(*_pgbufproxy_new_t)(PyObject *, getbufferproc); +typedef PyObject *(*_pgbufproxy_get_obj_t)(PyObject *); +typedef int (*_pgbufproxy_trip_t)(PyObject *); + +#ifndef PYGAMEAPI_BUFPROXY_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(bufferproxy); + +#define pgBufproxy_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(bufferproxy, 0)) + +#define pgBufproxy_Check(x) ((x)->ob_type == &pgBufproxy_Type) + +#define pgBufproxy_New (*(_pgbufproxy_new_t)PYGAMEAPI_GET_SLOT(bufferproxy, 1)) + +#define pgBufproxy_GetParent \ + (*(_pgbufproxy_get_obj_t)PYGAMEAPI_GET_SLOT(bufferproxy, 2)) + +#define pgBufproxy_Trip \ + (*(_pgbufproxy_trip_t)PYGAMEAPI_GET_SLOT(bufferproxy, 3)) + +#define import_pygame_bufferproxy() _IMPORT_PYGAME_MODULE(bufferproxy) + +#endif /* ~PYGAMEAPI_BUFPROXY_INTERNAL */ + +#endif /* ~defined(PG_BUFPROXY_HEADER) */ diff --git a/.venv/include/site/python3.7/pygame/include/pygame_font.h b/.venv/include/site/python3.7/pygame/include/pygame_font.h new file mode 100644 index 0000000..aae41bf --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame_font.h @@ -0,0 +1,50 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#include +#include "pgplatform.h" + +struct TTF_Font; + +typedef struct { + PyObject_HEAD TTF_Font *font; + PyObject *weakreflist; + unsigned int ttf_init_generation; +} PyFontObject; +#define PyFont_AsFont(x) (((PyFontObject *)x)->font) + +#ifndef PYGAMEAPI_FONT_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(font); + +#define PyFont_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(font, 0)) +#define PyFont_Check(x) ((x)->ob_type == &PyFont_Type) + +#define PyFont_New (*(PyObject * (*)(TTF_Font *)) PYGAMEAPI_GET_SLOT(font, 1)) + +/*slot 2 taken by FONT_INIT_CHECK*/ + +#define import_pygame_font() _IMPORT_PYGAME_MODULE(font) + +#endif diff --git a/.venv/include/site/python3.7/pygame/include/pygame_freetype.h b/.venv/include/site/python3.7/pygame/include/pygame_freetype.h new file mode 100644 index 0000000..90172cc --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame_freetype.h @@ -0,0 +1,42 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef PYGAME_FREETYPE_H_ +#define PYGAME_FREETYPE_H_ + +#include "pgplatform.h" +#include "pgimport.h" +#include "pgcompat.h" + +#ifndef PYGAME_FREETYPE_INTERNAL + +PYGAMEAPI_DEFINE_SLOTS(_freetype); + +#define pgFont_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(_freetype, 0)) + +#define pgFont_Check(x) ((x)->ob_type == &pgFont_Type) + +#define pgFont_New \ + (*(PyObject * (*)(const char *, long)) PYGAMEAPI_GET_SLOT(_freetype, 1)) + +#define import_pygame_freetype() _IMPORT_PYGAME_MODULE(_freetype) + +#endif /* PYGAME_FREETYPE_INTERNAL */ + +#endif /* PYGAME_FREETYPE_H_ */ diff --git a/.venv/include/site/python3.7/pygame/include/pygame_mask.h b/.venv/include/site/python3.7/pygame/include/pygame_mask.h new file mode 100644 index 0000000..8dd8f17 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame_mask.h @@ -0,0 +1,45 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef PGMASK_H +#define PGMASK_H + +#include +#include "bitmask.h" + +typedef struct { + PyObject_HEAD bitmask_t *mask; + void *bufdata; +} pgMaskObject; + +#define pgMask_AsBitmap(x) (((pgMaskObject *)x)->mask) + +#ifndef PYGAMEAPI_MASK_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(mask); + +#define pgMask_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(mask, 0)) +#define pgMask_Check(x) ((x)->ob_type == &pgMask_Type) + +#define import_pygame_mask() _IMPORT_PYGAME_MODULE(mask) + +#endif /* ~PYGAMEAPI_MASK_INTERNAL */ + +#endif /* ~PGMASK_H */ diff --git a/.venv/include/site/python3.7/pygame/include/pygame_mixer.h b/.venv/include/site/python3.7/pygame/include/pygame_mixer.h new file mode 100644 index 0000000..e19d273 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/pygame_mixer.h @@ -0,0 +1,71 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef PGMIXER_H +#define PGMIXER_H + +#include +#include + +#include "pgcompat.h" + +struct Mix_Chunk; + +typedef struct { + PyObject_HEAD Mix_Chunk *chunk; + Uint8 *mem; + PyObject *weakreflist; +} pgSoundObject; + +typedef struct { + PyObject_HEAD int chan; +} pgChannelObject; + +#define pgSound_AsChunk(x) (((pgSoundObject *)x)->chunk) +#define pgChannel_AsInt(x) (((pgChannelObject *)x)->chan) + +#include "pgimport.h" + +#ifndef PYGAMEAPI_MIXER_INTERNAL + +PYGAMEAPI_DEFINE_SLOTS(mixer); + +#define pgSound_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(mixer, 0)) + +#define pgSound_Check(x) ((x)->ob_type == &pgSound_Type) + +#define pgSound_New \ + (*(PyObject * (*)(Mix_Chunk *)) PYGAMEAPI_GET_SLOT(mixer, 1)) + +#define pgSound_Play \ + (*(PyObject * (*)(PyObject *, PyObject *)) PYGAMEAPI_GET_SLOT(mixer, 2)) + +#define pgChannel_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(mixer, 3)) +#define pgChannel_Check(x) ((x)->ob_type == &pgChannel_Type) + +#define pgChannel_New (*(PyObject * (*)(int)) PYGAMEAPI_GET_SLOT(mixer, 4)) + +#define import_pygame_mixer() _IMPORT_PYGAME_MODULE(mixer) + +#endif /* PYGAMEAPI_MIXER_INTERNAL */ + +#endif /* ~PGMIXER_H */ diff --git a/.venv/include/site/python3.7/pygame/include/sse2neon.h b/.venv/include/site/python3.7/pygame/include/sse2neon.h new file mode 100644 index 0000000..a3e3ac0 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/include/sse2neon.h @@ -0,0 +1,6203 @@ +#ifndef SSE2NEON_H +#define SSE2NEON_H + +// This header file provides a simple API translation layer +// between SSE intrinsics to their corresponding Arm/Aarch64 NEON versions +// +// This header file does not yet translate all of the SSE intrinsics. +// +// Contributors to this work are: +// John W. Ratcliff +// Brandon Rowlett +// Ken Fast +// Eric van Beurden +// Alexander Potylitsin +// Hasindu Gamaarachchi +// Jim Huang +// Mark Cheng +// Malcolm James MacLeod +// Devin Hussey (easyaspi314) +// Sebastian Pop +// Developer Ecosystem Engineering +// Danila Kutenin +// François Turban (JishinMaster) +// Pei-Hsuan Hung +// Yang-Hao Yuan + +/* + * sse2neon is freely redistributable under the MIT License. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Tunable configurations */ + +/* Enable precise implementation of _mm_min_ps and _mm_max_ps + * This would slow down the computation a bit, but gives consistent result with + * x86 SSE2. (e.g. would solve a hole or NaN pixel in the rendering result) + */ +#ifndef SSE2NEON_PRECISE_MINMAX +#define SSE2NEON_PRECISE_MINMAX (0) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#pragma push_macro("FORCE_INLINE") +#pragma push_macro("ALIGN_STRUCT") +#define FORCE_INLINE static inline __attribute__((always_inline)) +#define ALIGN_STRUCT(x) __attribute__((aligned(x))) +#else +#error "Macro name collisions may happen with unsupported compiler." +#ifdef FORCE_INLINE +#undef FORCE_INLINE +#endif +#define FORCE_INLINE static inline +#ifndef ALIGN_STRUCT +#define ALIGN_STRUCT(x) __declspec(align(x)) +#endif +#endif + +#include +#include + +// These cause the build to fail on raspberry pi with 'unsupported target' +// and don't seem to do anything particularly useful +///* Architecture-specific build options */ +///* FIXME: #pragma GCC push_options is only available on GCC */ +//#if defined(__GNUC__) +//#if defined(__arm__) && __ARM_ARCH == 7 +///* According to ARM C Language Extensions Architecture specification, +// * __ARM_NEON is defined to a value indicating the Advanced SIMD (NEON) +// * architecture supported. +// */ +//#if !defined(__ARM_NEON) || !defined(__ARM_NEON__) +//#error "You must enable NEON instructions (e.g. -mfpu=neon) to use SSE2NEON." +//#endif +//#pragma GCC push_options +//#pragma GCC target("fpu=neon") +//#elif defined(__aarch64__) +//#pragma GCC push_options +//#pragma GCC target("+simd") +//#else +//#error "Unsupported target. Must be either ARMv7-A+NEON or ARMv8-A." +//#endif +//#endif + +#include + +/* Rounding functions require either Aarch64 instructions or libm failback */ +#if !defined(__aarch64__) +#include +#endif + +/* "__has_builtin" can be used to query support for built-in functions + * provided by gcc/clang and other compilers that support it. + */ +#ifndef __has_builtin /* GCC prior to 10 or non-clang compilers */ +/* Compatibility with gcc <= 9 */ +#if __GNUC__ <= 9 +#define __has_builtin(x) HAS##x +#define HAS__builtin_popcount 1 +#define HAS__builtin_popcountll 1 +#else +#define __has_builtin(x) 0 +#endif +#endif + +/** + * MACRO for shuffle parameter for _mm_shuffle_ps(). + * Argument fp3 is a digit[0123] that represents the fp from argument "b" + * of mm_shuffle_ps that will be placed in fp3 of result. fp2 is the same + * for fp2 in result. fp1 is a digit[0123] that represents the fp from + * argument "a" of mm_shuffle_ps that will be places in fp1 of result. + * fp0 is the same for fp0 of result. + */ +#define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \ + (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0))) + +/* Rounding mode macros. */ +#define _MM_FROUND_TO_NEAREST_INT 0x00 +#define _MM_FROUND_TO_NEG_INF 0x01 +#define _MM_FROUND_TO_POS_INF 0x02 +#define _MM_FROUND_TO_ZERO 0x03 +#define _MM_FROUND_CUR_DIRECTION 0x04 +#define _MM_FROUND_NO_EXC 0x08 + +/* indicate immediate constant argument in a given range */ +#define __constrange(a, b) const + +/* A few intrinsics accept traditional data types like ints or floats, but + * most operate on data types that are specific to SSE. + * If a vector type ends in d, it contains doubles, and if it does not have + * a suffix, it contains floats. An integer vector type can contain any type + * of integer, from chars to shorts to unsigned long longs. + */ +typedef int64x1_t __m64; +typedef float32x4_t __m128; /* 128-bit vector containing 4 floats */ +// On ARM 32-bit architecture, the float64x2_t is not supported. +// The data type __m128d should be represented in a different way for related +// intrinsic conversion. +#if defined(__aarch64__) +typedef float64x2_t __m128d; /* 128-bit vector containing 2 doubles */ +#else +typedef float32x4_t __m128d; +#endif +typedef int64x2_t __m128i; /* 128-bit vector containing integers */ + +/* type-safe casting between types */ + +#define vreinterpretq_m128_f16(x) vreinterpretq_f32_f16(x) +#define vreinterpretq_m128_f32(x) (x) +#define vreinterpretq_m128_f64(x) vreinterpretq_f32_f64(x) + +#define vreinterpretq_m128_u8(x) vreinterpretq_f32_u8(x) +#define vreinterpretq_m128_u16(x) vreinterpretq_f32_u16(x) +#define vreinterpretq_m128_u32(x) vreinterpretq_f32_u32(x) +#define vreinterpretq_m128_u64(x) vreinterpretq_f32_u64(x) + +#define vreinterpretq_m128_s8(x) vreinterpretq_f32_s8(x) +#define vreinterpretq_m128_s16(x) vreinterpretq_f32_s16(x) +#define vreinterpretq_m128_s32(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_m128_s64(x) vreinterpretq_f32_s64(x) + +#define vreinterpretq_f16_m128(x) vreinterpretq_f16_f32(x) +#define vreinterpretq_f32_m128(x) (x) +#define vreinterpretq_f64_m128(x) vreinterpretq_f64_f32(x) + +#define vreinterpretq_u8_m128(x) vreinterpretq_u8_f32(x) +#define vreinterpretq_u16_m128(x) vreinterpretq_u16_f32(x) +#define vreinterpretq_u32_m128(x) vreinterpretq_u32_f32(x) +#define vreinterpretq_u64_m128(x) vreinterpretq_u64_f32(x) + +#define vreinterpretq_s8_m128(x) vreinterpretq_s8_f32(x) +#define vreinterpretq_s16_m128(x) vreinterpretq_s16_f32(x) +#define vreinterpretq_s32_m128(x) vreinterpretq_s32_f32(x) +#define vreinterpretq_s64_m128(x) vreinterpretq_s64_f32(x) + +#define vreinterpretq_m128i_s8(x) vreinterpretq_s64_s8(x) +#define vreinterpretq_m128i_s16(x) vreinterpretq_s64_s16(x) +#define vreinterpretq_m128i_s32(x) vreinterpretq_s64_s32(x) +#define vreinterpretq_m128i_s64(x) (x) + +#define vreinterpretq_m128i_u8(x) vreinterpretq_s64_u8(x) +#define vreinterpretq_m128i_u16(x) vreinterpretq_s64_u16(x) +#define vreinterpretq_m128i_u32(x) vreinterpretq_s64_u32(x) +#define vreinterpretq_m128i_u64(x) vreinterpretq_s64_u64(x) + +#define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s64(x) +#define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s64(x) +#define vreinterpretq_s32_m128i(x) vreinterpretq_s32_s64(x) +#define vreinterpretq_s64_m128i(x) (x) + +#define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s64(x) +#define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s64(x) +#define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s64(x) +#define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s64(x) + +#define vreinterpret_m64_s8(x) vreinterpret_s64_s8(x) +#define vreinterpret_m64_s16(x) vreinterpret_s64_s16(x) +#define vreinterpret_m64_s32(x) vreinterpret_s64_s32(x) +#define vreinterpret_m64_s64(x) (x) + +#define vreinterpret_m64_u8(x) vreinterpret_s64_u8(x) +#define vreinterpret_m64_u16(x) vreinterpret_s64_u16(x) +#define vreinterpret_m64_u32(x) vreinterpret_s64_u32(x) +#define vreinterpret_m64_u64(x) vreinterpret_s64_u64(x) + +#define vreinterpret_m64_f16(x) vreinterpret_s64_f16(x) +#define vreinterpret_m64_f32(x) vreinterpret_s64_f32(x) +#define vreinterpret_m64_f64(x) vreinterpret_s64_f64(x) + +#define vreinterpret_u8_m64(x) vreinterpret_u8_s64(x) +#define vreinterpret_u16_m64(x) vreinterpret_u16_s64(x) +#define vreinterpret_u32_m64(x) vreinterpret_u32_s64(x) +#define vreinterpret_u64_m64(x) vreinterpret_u64_s64(x) + +#define vreinterpret_s8_m64(x) vreinterpret_s8_s64(x) +#define vreinterpret_s16_m64(x) vreinterpret_s16_s64(x) +#define vreinterpret_s32_m64(x) vreinterpret_s32_s64(x) +#define vreinterpret_s64_m64(x) (x) + +#define vreinterpret_f32_m64(x) vreinterpret_f32_s64(x) + +#if defined(__aarch64__) +#define vreinterpretq_m128d_s32(x) vreinterpretq_f64_s32(x) +#define vreinterpretq_m128d_s64(x) vreinterpretq_f64_s64(x) + +#define vreinterpretq_m128d_f64(x) (x) + +#define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f64(x) + +#define vreinterpretq_f64_m128d(x) (x) +#else +#define vreinterpretq_m128d_s32(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_m128d_s64(x) vreinterpretq_f32_s64(x) + +#define vreinterpretq_m128d_f32(x) (x) + +#define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f32(x) + +#define vreinterpretq_f32_m128d(x) (x) +#endif + +// A struct is defined in this header file called 'SIMDVec' which can be used +// by applications which attempt to access the contents of an _m128 struct +// directly. It is important to note that accessing the __m128 struct directly +// is bad coding practice by Microsoft: @see: +// https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx +// +// However, some legacy source code may try to access the contents of an __m128 +// struct directly so the developer can use the SIMDVec as an alias for it. Any +// casting must be done manually by the developer, as you cannot cast or +// otherwise alias the base NEON data type for intrinsic operations. +// +// union intended to allow direct access to an __m128 variable using the names +// that the MSVC compiler provides. This union should really only be used when +// trying to access the members of the vector as integer values. GCC/clang +// allow native access to the float members through a simple array access +// operator (in C since 4.6, in C++ since 4.8). +// +// Ideally direct accesses to SIMD vectors should not be used since it can cause +// a performance hit. If it really is needed however, the original __m128 +// variable can be aliased with a pointer to this union and used to access +// individual components. The use of this union should be hidden behind a macro +// that is used throughout the codebase to access the members instead of always +// declaring this type of variable. +typedef union ALIGN_STRUCT(16) SIMDVec { + float m128_f32[4]; // as floats - DON'T USE. Added for convenience. + int8_t m128_i8[16]; // as signed 8-bit integers. + int16_t m128_i16[8]; // as signed 16-bit integers. + int32_t m128_i32[4]; // as signed 32-bit integers. + int64_t m128_i64[2]; // as signed 64-bit integers. + uint8_t m128_u8[16]; // as unsigned 8-bit integers. + uint16_t m128_u16[8]; // as unsigned 16-bit integers. + uint32_t m128_u32[4]; // as unsigned 32-bit integers. + uint64_t m128_u64[2]; // as unsigned 64-bit integers. +} SIMDVec; + +// casting using SIMDVec +#define vreinterpretq_nth_u64_m128i(x, n) (((SIMDVec *) &x)->m128_u64[n]) +#define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n]) +#define vreinterpretq_nth_u8_m128i(x, n) (((SIMDVec *) &x)->m128_u8[n]) + +/* Backwards compatibility for compilers with lack of specific type support */ + +// Older gcc does not define vld1q_u8_x4 type +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ <= 9 +FORCE_INLINE uint8x16x4_t vld1q_u8_x4(const uint8_t *p) +{ + uint8x16x4_t ret; + ret.val[0] = vld1q_u8(p + 0); + ret.val[1] = vld1q_u8(p + 16); + ret.val[2] = vld1q_u8(p + 32); + ret.val[3] = vld1q_u8(p + 48); + return ret; +} +#endif +#endif + +/* Function Naming Conventions + * The naming convention of SSE intrinsics is straightforward. A generic SSE + * intrinsic function is given as follows: + * _mm__ + * + * The parts of this format are given as follows: + * 1. describes the operation performed by the intrinsic + * 2. identifies the data type of the function's primary arguments + * + * This last part, , is a little complicated. It identifies the + * content of the input values, and can be set to any of the following values: + * + ps - vectors contain floats (ps stands for packed single-precision) + * + pd - vectors cantain doubles (pd stands for packed double-precision) + * + epi8/epi16/epi32/epi64 - vectors contain 8-bit/16-bit/32-bit/64-bit + * signed integers + * + epu8/epu16/epu32/epu64 - vectors contain 8-bit/16-bit/32-bit/64-bit + * unsigned integers + * + si128 - unspecified 128-bit vector or 256-bit vector + * + m128/m128i/m128d - identifies input vector types when they are different + * than the type of the returned vector + * + * For example, _mm_setzero_ps. The _mm implies that the function returns + * a 128-bit vector. The _ps at the end implies that the argument vectors + * contain floats. + * + * A complete example: Byte Shuffle - pshufb (_mm_shuffle_epi8) + * // Set packed 16-bit integers. 128 bits, 8 short, per 16 bits + * __m128i v_in = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + * // Set packed 8-bit integers + * // 128 bits, 16 chars, per 8 bits + * __m128i v_perm = _mm_setr_epi8(1, 0, 2, 3, 8, 9, 10, 11, + * 4, 5, 12, 13, 6, 7, 14, 15); + * // Shuffle packed 8-bit integers + * __m128i v_out = _mm_shuffle_epi8(v_in, v_perm); // pshufb + * + * Data (Number, Binary, Byte Index): + +------+------+-------------+------+------+-------------+ + | 1 | 2 | 3 | 4 | Number + +------+------+------+------+------+------+------+------+ + | 0000 | 0001 | 0000 | 0010 | 0000 | 0011 | 0000 | 0100 | Binary + +------+------+------+------+------+------+------+------+ + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Index + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 5 | 6 | 7 | 8 | Number + +------+------+------+------+------+------+------+------+ + | 0000 | 0101 | 0000 | 0110 | 0000 | 0111 | 0000 | 1000 | Binary + +------+------+------+------+------+------+------+------+ + | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Index + +------+------+------+------+------+------+------+------+ + * Index (Byte Index): + +------+------+------+------+------+------+------+------+ + | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 | + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 | + +------+------+------+------+------+------+------+------+ + * Result: + +------+------+------+------+------+------+------+------+ + | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 | Index + +------+------+------+------+------+------+------+------+ + | 0001 | 0000 | 0000 | 0010 | 0000 | 0101 | 0000 | 0110 | Binary + +------+------+------+------+------+------+------+------+ + | 256 | 2 | 5 | 6 | Number + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 | Index + +------+------+------+------+------+------+------+------+ + | 0000 | 0011 | 0000 | 0111 | 0000 | 0100 | 0000 | 1000 | Binary + +------+------+------+------+------+------+------+------+ + | 3 | 7 | 4 | 8 | Number + +------+------+------+------+------+------+-------------+ + */ + +/* Set/get methods */ + +/* Constants for use with _mm_prefetch. */ +enum _mm_hint { + _MM_HINT_NTA = 0, /* load data to L1 and L2 cache, mark it as NTA */ + _MM_HINT_T0 = 1, /* load data to L1 and L2 cache */ + _MM_HINT_T1 = 2, /* load data to L2 cache only */ + _MM_HINT_T2 = 3, /* load data to L2 cache only, mark it as NTA */ + _MM_HINT_ENTA = 4, /* exclusive version of _MM_HINT_NTA */ + _MM_HINT_ET0 = 5, /* exclusive version of _MM_HINT_T0 */ + _MM_HINT_ET1 = 6, /* exclusive version of _MM_HINT_T1 */ + _MM_HINT_ET2 = 7 /* exclusive version of _MM_HINT_T2 */ +}; + +// Loads one cache line of data from address p to a location closer to the +// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx +FORCE_INLINE void _mm_prefetch(const void *p, int i) +{ + (void) i; + __builtin_prefetch(p); +} + +// Copy the lower single-precision (32-bit) floating-point element of a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 +FORCE_INLINE float _mm_cvtss_f32(__m128 a) +{ + return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 +#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 +FORCE_INLINE int _mm_cvtss_si64(__m128 a) +{ +#if defined(__aarch64__) + return vgetq_lane_s64( + vreinterpretq_s64_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a))), 0); +#else + float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t diff = data - floor(data); + if (diff > 0.5) + return (int64_t) ceil(data); + if (diff == 0.5) { + int64_t f = (int64_t) floor(data); + int64_t c = (int64_t) ceil(data); + return c & 1 ? f : c; + } + return (int64_t) floor(data); +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi +FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) +{ + return vreinterpret_m64_s32( + vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si +FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) +{ + return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 +#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 +#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 +FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) +{ + return vgetq_lane_s64( + vmovl_s32(vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))), 0); +} + +// Sets the 128-bit value to zero +// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx +FORCE_INLINE __m128i _mm_setzero_si128(void) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(0)); +} + +// Clears the four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setzero_ps(void) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(0)); +} + +// Return vector of type __m128d with all elements set to zero. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd +FORCE_INLINE __m128d _mm_setzero_pd(void) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(0)); +#else + return vreinterpretq_m128d_f32(vdupq_n_f32(0)); +#endif +} + +// Sets the four single-precision, floating-point values to w. +// +// r0 := r1 := r2 := r3 := w +// +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set1_ps(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to w. +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps1(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to the four inputs. +// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Copy single-precision (32-bit) floating-point element a to the lower element +// of dst, and zero the upper 3 elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss +FORCE_INLINE __m128 _mm_set_ss(float a) +{ + float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the four single-precision, floating-point values to the four inputs in +// reverse order. +// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the 8 signed 16-bit integer values in reverse order. +// +// Return Value +// r0 := w0 +// r1 := w1 +// ... +// r7 := w7 +FORCE_INLINE __m128i _mm_setr_epi16(short w0, + short w1, + short w2, + short w3, + short w4, + short w5, + short w6, + short w7) +{ + int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; + return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); +} + +// Sets the 4 signed 32-bit integer values in reverse order +// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Set packed 64-bit integers in dst with the supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 +FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) +{ + return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); +} + +// Sets the 16 signed 8-bit integer values to b. +// +// r0 := b +// r1 := b +// ... +// r15 := b +// +// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi8(signed char w) +{ + return vreinterpretq_m128i_s8(vdupq_n_s8(w)); +} + +// Sets the 8 signed 16-bit integer values to w. +// +// r0 := w +// r1 := w +// ... +// r7 := w +// +// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set1_epi16(short w) +{ + return vreinterpretq_m128i_s16(vdupq_n_s16(w)); +} + +// Sets the 16 signed 8-bit integer values. +// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi8(signed char b15, + signed char b14, + signed char b13, + signed char b12, + signed char b11, + signed char b10, + signed char b9, + signed char b8, + signed char b7, + signed char b6, + signed char b5, + signed char b4, + signed char b3, + signed char b2, + signed char b1, + signed char b0) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 8 signed 16-bit integer values. +// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi16(short i7, + short i6, + short i5, + short i4, + short i3, + short i2, + short i1, + short i0) +{ + int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; + return vreinterpretq_m128i_s16(vld1q_s16(data)); +} + +// Sets the 16 signed 8-bit integer values in reverse order. +// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, + signed char b1, + signed char b2, + signed char b3, + signed char b4, + signed char b5, + signed char b6, + signed char b7, + signed char b8, + signed char b9, + signed char b10, + signed char b11, + signed char b12, + signed char b13, + signed char b14, + signed char b15) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 4 signed 32-bit integer values to i. +// +// r0 := i +// r1 := i +// r2 := i +// r3 := I +// +// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi32(int _i) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) +FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x +FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); +} + +// Sets the 4 signed 32-bit integer values. +// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) +{ + int64_t ALIGN_STRUCT(16) data[2] = {i2, i1}; + return vreinterpretq_m128i_s64(vld1q_s64(data)); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) +{ + return _mm_set_epi64x((int64_t) i1, (int64_t) i2); +} + +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd +FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) +{ + double ALIGN_STRUCT(16) data[2] = {e0, e1}; +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); +#else + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); +#endif +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx +FORCE_INLINE void _mm_store_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores the lower single - precision, floating - point value. +// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx +FORCE_INLINE void _mm_store_ss(float *p, __m128 a) +{ + vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary +// or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd +FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); +#else + vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); +#endif +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr does not need to be aligned on any +// particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd +FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) +{ + _mm_store_pd(mem_addr, a); +} + +// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. +// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx +FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) +{ + uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); + uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); + *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); +} + +// Stores the lower two single-precision floating point values of a to the +// address p. +// +// *p0 := a0 +// *p1 := a1 +// +// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx +FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_low_f32(a)); +} + +// Stores the upper two single-precision, floating-point values of a to the +// address p. +// +// *p0 := a2 +// *p1 := a3 +// +// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx +FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_high_f32(a)); +} + +// Loads a single single-precision, floating-point value, copying it into all +// four words +// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load1_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_dup_f32(p)); +} + +// Load a single-precision (32-bit) floating-point element from memory into all +// elements of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[63:32] := MEM[mem_addr+31:mem_addr] +// dst[95:64] := MEM[mem_addr+31:mem_addr] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 +#define _mm_load_ps1 _mm_load1_ps + +// Sets the lower two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the upper two values are passed +// through from a. +// +// Return Value +// r0 := *p0 +// r1 := *p1 +// r2 := a2 +// r3 := a3 +// +// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx +FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); +} + +// Load 4 single-precision (32-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[31:0] := MEM[mem_addr+127:mem_addr+96] +// dst[63:32] := MEM[mem_addr+95:mem_addr+64] +// dst[95:64] := MEM[mem_addr+63:mem_addr+32] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps +FORCE_INLINE __m128 _mm_loadr_ps(const float *p) +{ + float32x4_t v = vrev64q_f32(vld1q_f32(p)); + return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); +} + +// Sets the upper two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the lower two values are passed +// through from a. +// +// r0 := a0 +// r1 := a1 +// r2 := *p0 +// r3 := *p1 +// +// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx +FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_loadu_ps(const float *p) +{ + // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are + // equivalent for neon + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Load unaligned 16-bit integer from memory into the first element of dst. +// +// dst[15:0] := MEM[mem_addr+15:mem_addr] +// dst[MAX:16] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 +FORCE_INLINE __m128i _mm_loadu_si16(const void *p) +{ + return vreinterpretq_m128i_s16( + vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); +} + +// Load unaligned 64-bit integer from memory into the first element of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[MAX:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 +FORCE_INLINE __m128i _mm_loadu_si64(const void *p) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower of dst, and zero the upper element. mem_addr does not need to be +// aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd +FORCE_INLINE __m128d _mm_load_sd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Loads two double-precision from 16-byte aligned memory, floating-point +// values. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd +FORCE_INLINE __m128d _mm_load_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64(p)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Loads two double-precision from unaligned memory, floating-point values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd +FORCE_INLINE __m128d _mm_loadu_pd(const double *p) +{ + return _mm_load_pd(p); +} + +// Loads an single - precision, floating - point value into the low word and +// clears the upper three words. +// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_load_ss(const float *p) +{ + return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); +} + +FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) +{ + /* Load the lower 64 bits of the value pointed to by p into the + * lower 64 bits of the result, zeroing the upper 64 bits of the result. + */ + return vreinterpretq_m128i_s32( + vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower element of dst, and copy the upper element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd +FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); +#else + return vreinterpretq_m128d_f32( + vcombine_f32(vld1_f32((const float *) p), + vget_high_f32(vreinterpretq_f32_m128d(a)))); +#endif +} + +// Load 2 double-precision (64-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[63:0] := MEM[mem_addr+127:mem_addr+64] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd +FORCE_INLINE __m128d _mm_loadr_pd(const double *p) +{ +#if defined(__aarch64__) + float64x2_t v = vld1q_f64(p); + return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); +#else + int64x2_t v = vld1q_s64((const int64_t *) p); + return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); +#endif +} + +// Sets the low word to the single-precision, floating-point value of b +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) +FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), + vreinterpretq_f32_m128(a), 0)); +} + +// Copy the lower 64-bit integer in a to the lower element of dst, and zero the +// upper element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 +FORCE_INLINE __m128i _mm_move_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); +} + +// Return vector of type __m128 with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps +FORCE_INLINE __m128 _mm_undefined_ps(void) +{ + __m128 a; + return a; +} + +/* Logic/Binary operations */ + +// Computes the bitwise AND-NOT of the four single-precision, floating-point +// values of a and b. +// +// r0 := ~a0 & b0 +// r1 := ~a1 & b1 +// r2 := ~a2 & b2 +// r3 := ~a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx +FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vbicq_s32(vreinterpretq_s32_m128(b), + vreinterpretq_s32_m128(a))); // *NOTE* argument swap +} + +// Compute the bitwise NOT of packed double-precision (64-bit) floating-point +// elements in a and then AND with b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd +FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) +{ + // *NOTE* argument swap + return vreinterpretq_m128d_s64( + vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); +} + +// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the +// 128-bit value in a. +// +// r := (~a) & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vbicq_s32(vreinterpretq_s32_m128i(b), + vreinterpretq_s32_m128i(a))); // *NOTE* argument swap +} + +// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in +// b. +// +// r := a & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise AND of the four single-precision, floating-point values +// of a and b. +// +// r0 := a0 & b0 +// r1 := a1 & b1 +// r2 := a2 & b2 +// r3 := a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Compute the bitwise AND of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] AND b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd +FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise OR of the four single-precision, floating-point values +// of a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx +FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes bitwise EXOR (exclusive-or) of the four single-precision, +// floating-point values of a and b. +// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Compute the bitwise XOR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd +FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// +// r := a | b +// +// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx +FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in +// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx +FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Duplicate odd-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps +FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); +#else + float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); + float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +// Duplicate even-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps +FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); +#else + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); + float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +// Moves the upper two values of B into the lower two values of A. +// +// r3 := a3 +// r2 := a2 +// r1 := b3 +// r0 := b2 +FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(b32, a32)); +} + +// Moves the lower two values of B into the upper two values of A. +// +// r3 := b1 +// r2 := b0 +// r1 := a1 +// r0 := a0 +FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 +FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); +} + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 +FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) +{ + return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 +FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) +{ + return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 1 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 +FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) +{ + return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); +} + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 +FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) +{ + return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 +FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) +{ + return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); +} + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of b and places it into the high end of the result. +FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a32, b10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in high +// end of result takes the higher two 32 bit values from b and swaps them and +// places in low end of result. +FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b23)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) +{ + float32x2_t a21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a21, b03)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) +{ + float32x2_t a03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a03, b21)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a01, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b01)); +} + +// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the +// high +FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) +{ + float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a11, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) +{ + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a22, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) +{ + float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a00, b22)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/ + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a02, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) +{ + float32x2_t a33 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1); + return vreinterpretq_m128_f32(vcombine_f32(a33, b11)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a10, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a01, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); +} + +// NEON does not support a general purpose permute intrinsic +// Selects four specific single-precision, floating-point values from a and b, +// based on the mask i. +// +// C equivalent: +// __m128 _mm_shuffle_ps_default(__m128 a, __m128 b, +// __constrange(0, 255) int imm) { +// __m128 ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = b[(imm >> 4) & 0x03]; ret[3] = b[(imm >> 6) & 0x03]; +// return ret; +// } +// +// https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx +#define _mm_shuffle_ps_default(a, b, imm) \ + __extension__({ \ + float32x4_t ret; \ + ret = vmovq_n_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128_f32(ret); \ + }) + +// FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255) +// int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + float32x4_t _input1 = vreinterpretq_f32_m128(a); \ + float32x4_t _input2 = vreinterpretq_f32_m128(b); \ + float32x4_t _shuf = __builtin_shufflevector( \ + _input1, _input2, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + (((imm) >> 4) & 0x3) + 4, (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128_f32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + __m128 ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_ps_1032((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_ps_2301((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_ps_0321((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_ps_2103((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_movelh_ps((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_ps_1001((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_ps_0101((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 1, 0): \ + ret = _mm_shuffle_ps_3210((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 1, 1): \ + ret = _mm_shuffle_ps_0011((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 2, 2): \ + ret = _mm_shuffle_ps_0022((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 2, 0, 0): \ + ret = _mm_shuffle_ps_2200((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 0, 2): \ + ret = _mm_shuffle_ps_3202((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 3, 2): \ + ret = _mm_movehl_ps((b), (a)); \ + break; \ + case _MM_SHUFFLE(1, 1, 3, 3): \ + ret = _mm_shuffle_ps_1133((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 1, 0): \ + ret = _mm_shuffle_ps_2010((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 0, 1): \ + ret = _mm_shuffle_ps_2001((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 3, 2): \ + ret = _mm_shuffle_ps_2032((a), (b)); \ + break; \ + default: \ + ret = _mm_shuffle_ps_default((a), (b), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of a and places it into the high end of the result. +FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in low end +// of result takes the higher two 32 bit values from a and swaps them and places +// in high end of result. +FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); +} + +// rotates the least significant 32 bits into the most signficant 32 bits, and +// shifts the rest down +FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); +} + +// rotates the most significant 32 bits into the least signficant 32 bits, and +// shifts the rest up +FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); +} + +// gets the lower 64 bits of a, and places it in the upper 64 bits +// gets the lower 64 bits of a and places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) +{ + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the +// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the +// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and +// places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) +{ + int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +{ + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 +FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +{ + int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a + uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b + uint8x16_t idx_masked = + vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); +#elif defined(__GNUC__) + int8x16_t ret; + // %e and %f represent the even and odd D registers + // respectively. + __asm__ __volatile__( + "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" + "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" + : [ret] "=&w"(ret) + : [tbl] "w"(tbl), [idx] "w"(idx_masked)); + return vreinterpretq_m128i_s8(ret); +#else + // use this line if testing on aarch64 + int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; + return vreinterpretq_m128i_s8( + vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), + vtbl2_s8(a_split, vget_high_u8(idx_masked)))); +#endif +} + +// C equivalent: +// __m128i _mm_shuffle_epi32_default(__m128i a, +// __constrange(0, 255) int imm) { +// __m128i ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; +// return ret; +// } +#define _mm_shuffle_epi32_default(a, imm) \ + __extension__({ \ + int32x4_t ret; \ + ret = vmovq_n_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128i_s32(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) +// int imm) +#if defined(__aarch64__) +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ + }) +#else +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ + }) +#endif + +// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. +// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + int32x4_t _input = vreinterpretq_s32_m128i(a); \ + int32x4_t _shuf = __builtin_shufflevector( \ + _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ + vreinterpretq_m128i_s32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032((a)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301((a)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321((a)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101((a)); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122((a)); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332((a)); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat((a), 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat((a), 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat((a), 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat((a), 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default((a), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) +// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflelo_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t lowBits = vget_low_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflelo_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ + (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) +#endif + +// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflehi_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t highBits = vget_high_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ + 5); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ + 6); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ + 7); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflehi_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ + (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +#endif + +// Blend packed 16-bit integers from a and b using control mask imm8, and store +// the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[j] +// dst[i+15:i] := b[i+15:i] +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, +// __constrange(0,255) int imm) +#define _mm_blend_epi16(a, b, imm) \ + __extension__({ \ + const uint16_t _mask[8] = {((imm) & (1 << 0)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 1)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 2)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 3)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 4)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 5)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 6)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 7)) ? 0xFFFF : 0x0000}; \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t _a = vreinterpretq_u16_m128i(a); \ + uint16x8_t _b = vreinterpretq_u16_m128i(b); \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ + }) + +// Blend packed 8-bit integers from a and b using mask, and store the results in +// dst. +// +// FOR j := 0 to 15 +// i := j*8 +// IF mask[i+7] +// dst[i+7:i] := b[i+7:i] +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint8x16_t mask = + vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); + uint8x16_t a = vreinterpretq_u8_m128i(_a); + uint8x16_t b = vreinterpretq_u8_m128i(_b); + return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +} + +/* Shifts */ + + +// Shift packed 16-bit integers in a right by imm while shifting in sign +// bits, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 +FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) +{ + const int count = (imm & ~15) ? 15 : imm; + return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); +} + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx +#define _mm_slli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 15) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s16( \ + vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while +// shifting in zeros. : +// https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm) +FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) +{ + if (imm <= 0) /* TODO: add constant range macro: [0, 255] */ + return a; + if (imm > 31) /* TODO: add unlikely macro */ + return _mm_setzero_si128(); + return vreinterpretq_m128i_s32( + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); +} + +// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) +{ + if (imm <= 0) /* TODO: add constant range macro: [0, 255] */ + return a; + if (imm > 63) /* TODO: add unlikely macro */ + return _mm_setzero_si128(); + return vreinterpretq_m128i_s64( + vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); +} + +// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 +#define _mm_srli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) == 0) { \ + ret = a; \ + } else if (0 < (imm) && (imm) < 16) { \ + ret = vreinterpretq_m128i_u16( \ + vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 +// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) == 0) { \ + ret = a; \ + } else if (0 < (imm) && (imm) < 32) { \ + ret = vreinterpretq_m128i_u32( \ + vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 +#define _mm_srli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) == 0) { \ + ret = a; \ + } else if (0 < (imm) && (imm) < 64) { \ + ret = vreinterpretq_m128i_u64( \ + vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 +// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srai_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) == 0) { \ + ret = a; \ + } else if (0 < (imm) && (imm) < 32) { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ + } \ + ret; \ + }) + +// Shifts the 128 - bit value in a right by imm bytes while shifting in +// zeros.imm must be an immediate. +// +// r := srl(a, imm*8) +// +// https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx +// FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 15) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8( \ + vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm +// must be an immediate. +// +// r := a << (imm * 8) +// +// https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_slli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 15) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8(vextq_s8( \ + vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \ + } \ + ret; \ + }) + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 15) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16((int16_t) c); + return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); +} + +// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// r2 := a2 << count +// r3 := a3 << count +// +// https://msdn.microsoft.com/en-us/library/6fe5a6s9(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 31) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32((int32_t) c); + return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); +} + +// Shifts the 2 signed or unsigned 64-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// +// https://msdn.microsoft.com/en-us/library/6ta9dffd(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 63) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64((int64_t) c); + return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); +} + +// Shifts the 8 signed or unsigned 16-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// ... +// r7 := srl(a7, count) +// +// https://msdn.microsoft.com/en-us/library/wd5ax830(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 15) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16(-(int16_t) c); + return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); +} + +// Shifts the 4 signed or unsigned 32-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// r2 := srl(a2, count) +// r3 := srl(a3, count) +// +// https://msdn.microsoft.com/en-us/library/a9cbttf4(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 31) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32(-(int32_t) c); + return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); +} + +// Shifts the 2 signed or unsigned 64-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// +// https://msdn.microsoft.com/en-us/library/yf6cf9k8(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (c > 63) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64(-(int64_t) c); + return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); +} + +// NEON does not provide a version of this function. +// Creates a 16-bit mask from the most significant bits of the 16 signed or +// unsigned 8-bit integers in a and zero extends the upper bits. +// https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_epi8(__m128i a) +{ +#if defined(__aarch64__) + uint8x16_t input = vreinterpretq_u8_m128i(a); + const int8_t ALIGN_STRUCT(16) + xr[16] = {-7, -6, -5, -4, -3, -2, -1, 0, -7, -6, -5, -4, -3, -2, -1, 0}; + const uint8x16_t mask_and = vdupq_n_u8(0x80); + const int8x16_t mask_shift = vld1q_s8(xr); + const uint8x16_t mask_result = + vshlq_u8(vandq_u8(input, mask_and), mask_shift); + uint8x8_t lo = vget_low_u8(mask_result); + uint8x8_t hi = vget_high_u8(mask_result); + + return vaddv_u8(lo) + (vaddv_u8(hi) << 8); +#else + // Use increasingly wide shifts+adds to collect the sign bits + // together. + // Since the widening shifts would be rather confusing to follow in little + // endian, everything will be illustrated in big endian order instead. This + // has a different result - the bits would actually be reversed on a big + // endian machine. + + // Starting input (only half the elements are shown): + // 89 ff 1d c0 00 10 99 33 + uint8x16_t input = vreinterpretq_u8_m128i(a); + + // Shift out everything but the sign bits with an unsigned shift right. + // + // Bytes of the vector:: + // 89 ff 1d c0 00 10 99 33 + // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7) + // | | | | | | | | + // 01 01 00 01 00 00 01 00 + // + // Bits of first important lane(s): + // 10001001 (89) + // \______ + // | + // 00000001 (01) + uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7)); + + // Merge the even lanes together with a 16-bit unsigned shift right + add. + // 'xx' represents garbage data which will be ignored in the final result. + // In the important bytes, the add functions like a binary OR. + // + // 01 01 00 01 00 00 01 00 + // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7)) + // \| \| \| \| + // xx 03 xx 01 xx 00 xx 02 + // + // 00000001 00000001 (01 01) + // \_______ | + // \| + // xxxxxxxx xxxxxx11 (xx 03) + uint32x4_t paired16 = + vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); + + // Repeat with a wider 32-bit shift + add. + // xx 03 xx 01 xx 00 xx 02 + // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >> + // 14)) + // \| \| + // xx xx xx 0d xx xx xx 02 + // + // 00000011 00000001 (03 01) + // \\_____ || + // '----.\|| + // xxxxxxxx xxxx1101 (xx 0d) + uint64x2_t paired32 = + vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); + + // Last, an even wider 64-bit shift + add to get our result in the low 8 bit + // lanes. xx xx xx 0d xx xx xx 02 + // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >> + // 28)) + // \| + // xx xx xx xx xx xx xx d2 + // + // 00001101 00000010 (0d 02) + // \ \___ | | + // '---. \| | + // xxxxxxxx 11010010 (xx d2) + uint8x16_t paired64 = + vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); + + // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts. + // xx xx xx xx xx xx xx d2 + // || return paired64[0] + // d2 + // Note: Little endian would return the correct value 4b (01001011) instead. + return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); +#endif +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movepi64_pi64 +FORCE_INLINE __m64 _mm_movepi64_pi64(__m128i a) +{ + return vreinterpret_m64_s64(vget_low_s64(vreinterpretq_s64_m128i(a))); +} + +// Copy the 64-bit integer a to the lower element of dst, and zero the upper +// element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movpi64_epi64 +FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0))); +} + +// NEON does not provide this method +// Creates a 4-bit mask from the most significant bits of the four +// single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_ps(__m128 a) +{ + uint32x4_t input = vreinterpretq_u32_m128(a); +#if defined(__aarch64__) + static const int32x4_t shift = {0, 1, 2, 3}; + uint32x4_t tmp = vshrq_n_u32(input, 31); + return vaddvq_u32(vshlq_u32(tmp, shift)); +#else + // Uses the exact same method as _mm_movemask_epi8, see that for details. + // Shift out everything but the sign bits with a 32-bit unsigned shift + // right. + uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); + // Merge the two pairs together with a 64-bit unsigned shift right + add. + uint8x16_t paired = + vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); + // Extract the result. + return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); +#endif +} + +// Compute the bitwise NOT of a and then AND with a 128-bit vector containing +// all 1's, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones +FORCE_INLINE int _mm_test_all_ones(__m128i a) +{ + return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == + ~(uint64_t) 0; +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros +FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +{ + int64x2_t a_and_mask = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); + return (vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)) ? 0 + : 1; +} + +/* Math operations */ + +// Subtracts the four single-precision, floating-point values of a and b. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Subtract the lower single-precision (32-bit) floating-point element in b from +// the lower single-precision (32-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper 3 packed elements from +// a to the upper elements of dst. +// +// dst[31:0] := a[31:0] - b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss +FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_sub_ps(a, b)); +} + +// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, +// and store the results in dst. +// r0 := a0 - b0 +// r1 := a1 - b1 +FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or +// unsigned 32-bit integers of a. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx +FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. +// +// dst[63:0] := a[63:0] - b[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 +FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} + +// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit +// integers of a and saturates.. +// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx +FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit +// integers of a and saturates. +// +// r0 := UnsignedSaturate(a0 - b0) +// r1 := UnsignedSaturate(a1 - b1) +// ... +// r15 := UnsignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r15 := SignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r7 := SignedSaturate(a7 - b7) +// +// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Negate packed 8-bit integers in a when the corresponding signed +// 8-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..15 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) +{ + int8x16_t a = vreinterpretq_s8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); +#else + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); +#endif + + // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a') + // based on ltMask + int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); + // res = masked & (~zeroMask) + int8x16_t res = vbicq_s8(masked, zeroMask); + + return vreinterpretq_m128i_s8(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed +// 16-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..7 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); + // (b == 0) ? 0xFFFF : 0 +#if defined(__aarch64__) + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b)); +#else + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s16(a) equals to negative + // 'a') based on ltMask + int16x8_t masked = vbslq_s16(ltMask, vnegq_s16(a), a); + // res = masked & (~zeroMask) + int16x8_t res = vbicq_s16(masked, zeroMask); + return vreinterpretq_m128i_s16(res); +} + +// Negate packed 32-bit integers in a when the corresponding signed +// 32-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..3 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b)); +#else + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s32(a) equals to negative + // 'a') based on ltMask + int32x4_t masked = vbslq_s32(ltMask, vnegq_s32(a), a); + // res = masked & (~zeroMask) + int32x4_t res = vbicq_s32(masked, zeroMask); + return vreinterpretq_m128i_s32(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed 16-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. +// +// FOR j := 0 to 3 +// i := j*16 +// IF b[i+15:i] < 0 +// dst[i+15:i] := -(a[i+15:i]) +// ELSE IF b[i+15:i] == 0 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi16 +FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) +{ + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15)); + + // (b == 0) ? 0xFFFF : 0 +#if defined(__aarch64__) + int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b)); +#else + int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a') + // based on ltMask + int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a); + // res = masked & (~zeroMask) + int16x4_t res = vbic_s16(masked, zeroMask); + + return vreinterpret_m64_s16(res); +} + +// Negate packed 32-bit integers in a when the corresponding signed 32-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. +// +// FOR j := 0 to 1 +// i := j*32 +// IF b[i+31:i] < 0 +// dst[i+31:i] := -(a[i+31:i]) +// ELSE IF b[i+31:i] == 0 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := a[i+31:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi32 +FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) +{ + int32x2_t a = vreinterpret_s32_m64(_a); + int32x2_t b = vreinterpret_s32_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b)); +#else + int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a') + // based on ltMask + int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a); + // res = masked & (~zeroMask) + int32x2_t res = vbic_s32(masked, zeroMask); + + return vreinterpret_m64_s32(res); +} + +// Negate packed 8-bit integers in a when the corresponding signed 8-bit integer +// in b is negative, and store the results in dst. Element in dst are zeroed out +// when the corresponding element in b is zero. +// +// FOR j := 0 to 7 +// i := j*8 +// IF b[i+7:i] < 0 +// dst[i+7:i] := -(a[i+7:i]) +// ELSE IF b[i+7:i] == 0 +// dst[i+7:i] := 0 +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi8 +FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) +{ + int8x8_t a = vreinterpret_s8_m64(_a); + int8x8_t b = vreinterpret_s8_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b)); +#else + int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a') + // based on ltMask + int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a); + // res = masked & (~zeroMask) + int8x8_t res = vbic_s8(masked, zeroMask); + + return vreinterpret_m64_s8(res); +} + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 +FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16( + vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 +FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb +#define _m_pavgb(a, b) _mm_avg_pu8(a, b) + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw +#define _m_pavgw(a, b) _mm_avg_pu16(a, b) + +// Computes the average of the 16 unsigned 8-bit integers in a and the 16 +// unsigned 8-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r15 := (a15 + b15) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the average of the 8 unsigned 16-bit integers in a and the 8 +// unsigned 16-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r7 := (a7 + b7) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) +{ + return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), + vreinterpretq_u16_m128i(b)); +} + +// Adds the four single-precision, floating-point values of a and b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Add packed double-precision (64-bit) floating-point elements in a and b, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd +FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1] + db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Add 64-bit integers a and b, and store the result in dst. +// +// dst[63:0] := a[63:0] + b[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 +FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} + +// adds the scalar single-precision floating point values of a and b. +// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) +{ + float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); + // the upper values in the result must be the remnants of . + return vreinterpretq_m128_f32(vaddq_f32(a, value)); +} + +// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or +// unsigned 16-bit integers in b. +// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or +// unsigned 8-bit integers in b. +// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) +FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b +// and saturates. +// +// r0 := SignedSaturate(a0 + b0) +// r1 := SignedSaturate(a1 + b1) +// ... +// r7 := SignedSaturate(a7 + b7) +// +// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Add packed signed 8-bit integers in a and b using saturation, and store the +// results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 +FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in +// b and saturates.. +// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or +// unsigned 16-bit integers from b. +// +// r0 := (a0 * b0)[15:0] +// r1 := (a1 * b1)[15:0] +// ... +// r7 := (a7 * b7)[15:0] +// +// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or +// unsigned 32-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// tmp[31:0] := a[i+15:i] * b[i+15:i] +// dst[i+15:i] := tmp[31:16] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw +#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) + +// Multiplies the four single-precision, floating-point values of a and b. +// +// r0 := a0 * b0 +// r1 := a1 * b1 +// r2 := a2 * b2 +// r3 := a3 * b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx +FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Multiply packed double-precision (64-bit) floating-point elements in a and b, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd +FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] * db[0]; + c[1] = da[1] * db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Multiply the lower single-precision (32-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper 3 packed +// elements from a to the upper elements of dst. +// +// dst[31:0] := a[31:0] * b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss +FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_mul_ps(a, b)); +} + +// Multiply the low unsigned 32-bit integers from each packed 64-bit element in +// a and b, and store the unsigned 64-bit results in dst. +// +// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) +// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) +FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +{ + // vmull_u32 upcasts instead of masking, so we downcast. + uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); + uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); + return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); +} + +// Multiply the low unsigned 32-bit integers from a and b, and store the +// unsigned 64-bit result in dst. +// +// dst[63:0] := a[31:0] * b[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 +FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) +{ + return vreinterpret_m64_u64(vget_low_u64( + vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); +} + +// Multiply the low signed 32-bit integers from each packed 64-bit element in +// a and b, and store the signed 64-bit results in dst. +// +// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 +// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 +FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +{ + // vmull_s32 upcasts instead of masking, so we downcast. + int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); + int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0) + (a1 * b1) +// r1 := (a2 * b2) + (a3 * b3) +// r2 := (a4 * b4) + (a5 * b5) +// r3 := (a6 * b6) + (a7 * b7) +// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx +FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); + int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); + + return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); +} + +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Shift right by 15 bits while rounding up, and store +// the packed 16-bit integers in dst. +// +// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) +// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) +// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) +// ... +// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) +FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) +{ + // Has issues due to saturation + // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); + + // Multiply + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + // Rounding narrowing shift right + // narrow = (int16_t)((mul + 16384) >> 15); + int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); + int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); + + // Join together + return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, +// and pack the saturated results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + +// a[i+7:i]*b[i+7:i] ) +// ENDFOR +FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + uint8x16_t a = vreinterpretq_u8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), + vmovl_s8(vget_low_s8(b))); + int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), + vmovl_s8(vget_high_s8(b))); + return vreinterpretq_m128i_s16( + vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); +#else + // This would be much simpler if x86 would choose to zero extend OR sign + // extend, not both. This could probably be optimized better. + uint16x8_t a = vreinterpretq_u16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // Zero extend a + int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); + int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); + + // Sign extend by shifting left then shifting right. + int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); + int16x8_t b_odd = vshrq_n_s16(b, 8); + + // multiply + int16x8_t prod1 = vmulq_s16(a_even, b_even); + int16x8_t prod2 = vmulq_s16(a_odd, b_odd); + + // saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); +#endif +} + +// Computes the fused multiple add product of 32-bit floating point numbers. +// +// Return Value +// Multiplies A and B, and adds C to the temporary result before returning it. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_fmadd +FORCE_INLINE __m128 _mm_fmadd_ps(__m128 a, __m128 b, __m128 c) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(c), + vreinterpretq_f32_m128(b), + vreinterpretq_f32_m128(a))); +#else + return _mm_add_ps(_mm_mul_ps(a, b), c); +#endif +} + +// Alternatively add and subtract packed single-precision (32-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps +FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) +{ + __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f}; + return _mm_fmadd_ps(b, mask, a); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce two +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of 64-bit elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 +FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +{ + uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); + uint16_t r0 = t[0] + t[1] + t[2] + t[3]; + uint16_t r4 = t[4] + t[5] + t[6] + t[7]; + uint16x8_t r = vsetq_lane_u16(r0, vdupq_n_u16(0), 0); + return (__m128i) vsetq_lane_u16(r4, r, 4); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 +FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) +{ + uint16x4_t t = + vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); + uint16_t r0 = t[0] + t[1] + t[2] + t[3]; + return vreinterpret_m64_u16(vset_lane_u16(r0, vdup_n_u16(0), 0)); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// +// FOR j := 0 to 7 +// i := j*8 +// tmp[i+7:i] := ABS(a[i+7:i] - b[i+7:i]) +// ENDFOR +// dst[15:0] := tmp[7:0] + tmp[15:8] + tmp[23:16] + tmp[31:24] + tmp[39:32] + +// tmp[47:40] + tmp[55:48] + tmp[63:56] dst[63:16] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_psadbw +#define _m_psadbw(a, b) _mm_sad_pu8(a, b) + +// Divides the four single-precision, floating-point values of a and b. +// +// r0 := a0 / b0 +// r1 := a1 / b1 +// r2 := a2 / b2 +// r3 := a3 / b3 +// +// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x4_t recip0 = vrecpeq_f32(vreinterpretq_f32_m128(b)); + float32x4_t recip1 = + vmulq_f32(recip0, vrecpsq_f32(recip0, vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip1)); +#endif +} + +// Divides the scalar single-precision floating point value of a by b. +// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Compute the approximate reciprocal of packed single-precision (32-bit) +// floating-point elements in a, and store the results in dst. The maximum +// relative error for this approximation is less than 1.5*2^-12. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps +FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vdivq_f32(vdupq_n_f32(1.0f), vreinterpretq_f32_m128(in))); +#else + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); + return vreinterpretq_m128_f32(recip); +#endif +} + +// Compute the approximate reciprocal of the lower single-precision (32-bit) +// floating-point element in a, store the result in the lower element of dst, +// and copy the upper 3 packed elements from a to the upper elements of dst. The +// maximum relative error for this approximation is less than 1.5*2^-12. +// +// dst[31:0] := (1.0 / a[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss +FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) +{ + return _mm_move_ss(a, _mm_rcp_ps(a)); +} + +// Computes the approximations of square roots of the four single-precision, +// floating-point values of a. First computes reciprocal square roots and then +// reciprocals of the four values. +// +// r0 := sqrt(a0) +// r1 := sqrt(a1) +// r2 := sqrt(a2) +// r3 := sqrt(a3) +// +// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); +#else + float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + float32x4_t sq = vrecpeq_f32(recipsq); + // ??? use step versions of both sqrt and recip for better accuracy? + return vreinterpretq_m128_f32(sq); +#endif +} + +// Computes the approximation of the square root of the scalar single-precision +// floating point value of in. +// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); +} + +// Computes the approximations of the reciprocal square roots of the four +// single-precision floating point values of in. +// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) +{ + return vreinterpretq_m128_f32(vrsqrteq_f32(vreinterpretq_f32_m128(in))); +} + +// Compute the approximate reciprocal square root of the lower single-precision +// (32-bit) floating-point element in a, store the result in the lower element +// of dst, and copy the upper 3 packed elements from a to the upper elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss +FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) +{ + return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); +} + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) + +// Computes the maximums of the four single-precision, floating-point values of +// a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_b, _a), _a, _b); +#else + return vreinterpretq_m128_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +#define _m_pmaxub(a, b) _mm_max_pu8(a, b) + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +#define _m_pminsw(a, b) _mm_min_pi16(a, b) + +// Computes the minima of the four single-precision, floating-point values of a +// and b. +// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_a, _b), _a, _b); +#else + return vreinterpretq_m128_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +#define _m_pminub(a, b) _mm_min_pu8(a, b) + +// Computes the maximum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the minimum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx +FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed signed 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 +FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed unsigned 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 +FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Compare packed signed 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 +FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed unsigned 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 +FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// epi versions of min/max +// Computes the pariwise maximums of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 > b0) ? a0 : b0 +// r1 := (a1 > b1) ? a1 : b1 +// r2 := (a2 > b2) ? a2 : b2 +// r3 := (a3 > b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the pariwise minima of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 < b0) ? a0 : b0 +// r1 := (a1 < b1) ? a1 : b1 +// r2 := (a2 < b2) ? a2 : b2 +// r3 := (a3 < b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 +FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16(vshrn_n_u32( + vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0)[31:16] +// r1 := (a1 * b1)[31:16] +// ... +// r7 := (a7 * b7)[31:16] +// +// https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) +{ + /* FIXME: issue with large values because of result saturation */ + // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a), + // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return + // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1)); + int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */ + int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */ + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_epu16 +FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) +{ + uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab3210 = vmull_u16(a3210, b3210); +#if defined(__aarch64__) + uint32x4_t ab7654 = + vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)); + uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210), + vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r); +#else + uint16x4_t a7654 = vget_high_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b7654 = vget_high_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab7654 = vmull_u16(a7654, b7654); + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_u32(ab3210), vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +#endif +} + +// Computes pairwise add of each argument as single-precision, floating-point +// values a and b. +// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx +FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32( + vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); +#endif +} + +// Computes pairwise add of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); +#else + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), + vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); +#endif +} + +// Horizontally substract adjacent pairs of single-precision (32-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps +FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsubq_f32( + vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)), + vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)))); +#else + float32x4x2_t c = + vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)); + return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); +#endif +} + +// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the +// signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 +FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the +// signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 +FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) +{ + return vreinterpret_m64_s32( + vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); +} + +// Computes pairwise difference of each argument as a 16-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Subtract + return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); +} + +// Computes saturated pairwise sub of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); +#endif +} + +// Computes saturated pairwise difference of each argument as a 16-bit signed +// integer values a and b. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 +FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated subtract + return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); +#endif +} + +// Computes pairwise add of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + return vreinterpretq_m128i_s32( + vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), + vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); +} + +// Computes pairwise difference of each argument as a 32-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +{ + int64x2_t a = vreinterpretq_s64_m128i(_a); + int64x2_t b = vreinterpretq_s64_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|b0|b2] + // [a1|a2|b1|b3] + int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); + int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); + // Subtract + return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); +} + +// Kahan summation for accurate summation of floating-point numbers. +// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html +FORCE_INLINE void sse2neon_kadd_f32(float *sum, float *c, float y) +{ + y -= *c; + float t = *sum + y; + *c = (t - *sum) - y; + *sum = t; +} + +// Conditionally multiply the packed single-precision (32-bit) floating-point +// elements in a and b using the high 4 bits in imm8, sum the four products, +// and conditionally store the sum in dst using the low 4 bits of imm. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_ps +FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) +{ +#if defined(__aarch64__) + /* shortcuts */ + if (imm == 0xFF) { + return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b))); + } + if (imm == 0x7F) { + float32x4_t m = _mm_mul_ps(a, b); + m[3] = 0; + return _mm_set1_ps(vaddvq_f32(m)); + } +#endif + + float s = 0, c = 0; + float32x4_t f32a = vreinterpretq_f32_m128(a); + float32x4_t f32b = vreinterpretq_f32_m128(b); + + /* To improve the accuracy of floating-point summation, Kahan algorithm + * is used for each operation. + */ + if (imm & (1 << 4)) + sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]); + if (imm & (1 << 5)) + sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]); + if (imm & (1 << 6)) + sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]); + if (imm & (1 << 7)) + sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]); + s += c; + + float32x4_t res = { + (imm & 0x1) ? s : 0, + (imm & 0x2) ? s : 0, + (imm & 0x4) ? s : 0, + (imm & 0x8) ? s : 0, + }; + return vreinterpretq_m128_f32(res); +} + +/* Compare operations */ + +// Compares for less than +// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) +FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmplt_ps(a, b)); +} + +// Compares for greater than. +// +// r0 := (a0 > b0) ? 0xffffffff : 0x0 +// r1 := (a1 > b1) ? 0xffffffff : 0x0 +// r2 := (a2 > b2) ? 0xffffffff : 0x0 +// r3 := (a3 > b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); +} + +// Compares for greater than or equal. +// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) +FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpge_ps(a, b)); +} + +// Compares for less than or equal. +// +// r0 := (a0 <= b0) ? 0xffffffff : 0x0 +// r1 := (a1 <= b1) ? 0xffffffff : 0x0 +// r2 := (a2 <= b2) ? 0xffffffff : 0x0 +// r3 := (a3 <= b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) +FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmple_ps(a, b)); +} + +// Compares for equality. +// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for equality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); +} + +// Compares for inequality. +// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for inequality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) +FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) +{ + return _mm_cmplt_ps(a, b); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) +{ + return _mm_cmplt_ss(a, b); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) +{ + return _mm_cmple_ps(a, b); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) +{ + return _mm_cmple_ss(a, b); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) +{ + return _mm_cmpgt_ps(a, b); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) +{ + return _mm_cmpgt_ss(a, b); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) +{ + return _mm_cmpge_ps(a, b); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) +{ + return _mm_cmpge_ss(a, b); +} + +// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or +// unsigned 8-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or +// unsigned 16-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed 32-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed 64-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); +#else + // ARMv7 lacks vceqq_u64 + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); +#endif +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for lesser than. +// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xff : 0x0 +// r1 := (a1 > b1) ? 0xff : 0x0 +// ... +// r15 := (a15 > b15) ? 0xff : 0x0 +// +// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for less than. +// +// r0 := (a0 < b0) ? 0xffff : 0x0 +// r1 := (a1 < b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 < b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xffff : 0x0 +// r1 := (a1 > b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 > b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for less than. +// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for greater than. +// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers +// in b for greater than. +FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +#else + // ARMv7 lacks vcgtq_s64. + // This is based off of Clang's SSE2 polyfill: + // (a > b) -> ((a_hi > b_hi) || (a_lo > b_lo && a_hi == b_hi)) + + // Mask the sign bit out since we need a signed AND an unsigned comparison + // and it is ugly to try and split them. + int32x4_t mask = vreinterpretq_s32_s64(vdupq_n_s64(0x80000000ull)); + int32x4_t a_mask = veorq_s32(vreinterpretq_s32_m128i(a), mask); + int32x4_t b_mask = veorq_s32(vreinterpretq_s32_m128i(b), mask); + // Check if a > b + int64x2_t greater = vreinterpretq_s64_u32(vcgtq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi > b_hi + int64x2_t gt_hi = vshrq_n_s64(greater, 63); + // Copy lower mask to upper mask + // a_lo > b_lo + int64x2_t gt_lo = vsliq_n_s64(greater, greater, 32); + // Compare for equality + int64x2_t equal = vreinterpretq_s64_u32(vceqq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi == b_hi + int64x2_t eq_hi = vshrq_n_s64(equal, 63); + // a_hi > b_hi || (a_lo > b_lo && a_hi == b_hi) + int64x2_t ret = vorrq_s64(gt_hi, vandq_s64(gt_lo, eq_hi)); + return vreinterpretq_m128i_s64(ret); +#endif +} + +// Compares the four 32-bit floats in a and b to check if any values are NaN. +// Ordered compare between each value returns true for "orderable" and false for +// "not orderable" (NaN). +// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see +// also: +// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean +// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics +FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) +{ + // Note: NEON does not have ordered compare builtin + // Need to compare a eq a and b eq b to check for NaN + // Do AND of results to get final + uint32x4_t ceqaa = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t ceqbb = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); +} + +// Compares for ordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) +FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpord_ps(a, b)); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) +{ + uint32x4_t f32a = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t f32b = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than operation. : +// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important +// note!! The documentation on MSDN is incorrect! If either of the values is a +// NAN the docs say you will get a one, but in fact, it will return a zero!! +FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) +{ + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_lt_b = + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than operation. : +// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx +FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_gt_b = + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than or equal operation. : +// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx +FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_le_b = + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than or equal operation. : +// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx +FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_ge_b = + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an equality operation. : +// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx +FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_eq_b = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an inequality operation. : +// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx +FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +{ + // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan)); + uint32x4_t a_neq_b = vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return (vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) != 0) ? 1 : 0; +} + +// according to the documentation, these intrinsics behave the same as the +// non-'u' versions. We'll just alias them here. +#define _mm_ucomilt_ss _mm_comilt_ss +#define _mm_ucomile_ss _mm_comile_ss +#define _mm_ucomigt_ss _mm_comigt_ss +#define _mm_ucomige_ss _mm_comige_ss +#define _mm_ucomieq_ss _mm_comieq_ss +#define _mm_ucomineq_ss _mm_comineq_ss + +/* Conversions */ + +// Convert packed signed 32-bit integers in b to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, and copy the upper 2 packed elements from a to the upper elements of +// dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps +FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss +FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss +#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) + +// Convert the signed 64-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss +FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si +FORCE_INLINE int _mm_cvt_ss2si(__m128 a) +{ +#if defined(__aarch64__) + return vgetq_lane_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)), 0); +#else + float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t diff = data - floor(data); + if (diff > 0.5) + return (int32_t) ceil(data); + if (diff == 0.5) { + int32_t f = (int32_t) floor(data); + int32_t c = (int32_t) ceil(data); + return c & 1 ? f : c; + } + return (int32_t) floor(data); +#endif +} + +// Convert packed 16-bit integers in a to packed single-precision (32-bit) +// floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps +FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); +} + +// Convert packed 32-bit integers in b to packed single-precision (32-bit) +// floating-point elements, store the results in the lower 2 elements of dst, +// and copy the upper 2 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps +FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert packed signed 32-bit integers in a to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, then covert the packed signed 32-bit integers in b to +// single-precision (32-bit) floating-point element, and store the results in +// the upper 2 elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) +// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps +FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); +} + +// Convert the lower packed 8-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps +FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); +} + +// Convert packed unsigned 16-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps +FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); +} + +// Convert the lower packed unsigned 8-bit integers in a to packed +// single-precision (32-bit) floating-point elements, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps +FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_u32( + vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values using truncate. +// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +{ + return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 +FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) +{ +#if defined(__aarch64__) + return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); +#else + double ret = *((double *) &a); + return (int64_t) ret; +#endif +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x +#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) + +// Converts the four signed 32-bit integer values of a to single-precision, +// floating-point values +// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_u16(u16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx +FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_u32(u32x4); +} + +// Converts the two unsigned 8-bit integers in the lower 16 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_s16(s16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_s32(s32x4); +} + +// Converts the two signed 8-bit integers in the lower 32 bits to four +// signed 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four signed 16-bit integers in the lower 64 bits to four signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32( + vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); +} + +// Converts the two signed 16-bit integers in the lower 32 bits two signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) +{ + int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four unsigned 16-bit integers in the lower 64 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) +{ + return vreinterpretq_m128i_u32( + vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); +} + +// Converts the two unsigned 16-bit integers in the lower 32 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) +{ + uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the two unsigned 32-bit integers in the lower 64 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) +{ + return vreinterpretq_m128i_u64( + vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); +} + +// Converts the two signed 32-bit integers in the lower 64 bits to two signed +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values. +// +// r0 := (int) a0 +// r1 := (int) a1 +// r2 := (int) a2 +// r3 := (int) a3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx +// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A +// does not support! It is supported on ARMv8-A however. +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); +#else + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = + vcvtq_s32_f32(vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128i_s32(vbslq_s32(is_delta_half, r_even, r_normal)); +#endif +} + +// Copy the lower 32-bit integer in a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 +FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) +{ + return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 +FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) +{ + return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// +// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +{ + return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); +} + +// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) +{ + return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); +} + +// Cast vector of type __m128 to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd +FORCE_INLINE __m128d _mm_castps_pd(__m128 a) +{ + return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); +} + +// Applies a type cast to reinterpret four 32-bit floating point values passed +// in as a 128-bit parameter as packed 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb514099.aspx +FORCE_INLINE __m128i _mm_castps_si128(__m128 a) +{ + return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); +} + +// Applies a type cast to reinterpret four 32-bit integers passed in as a +// 128-bit parameter as packed 32-bit floating point values. +// https://msdn.microsoft.com/en-us/library/bb514029.aspx +FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) +{ + return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx +FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd +FORCE_INLINE __m128d _mm_load1_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// upper element of dst, and copy the lower element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := a[63:0] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd +FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); +#else + return vreinterpretq_m128d_f32(vcombine_f32( + vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 +#define _mm_load_pd1 _mm_load1_pd + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd +#define _mm_loaddup_pd _mm_load1_pd + +// Loads 128-bit value. : +// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load unaligned 32-bit integer from memory into the first element of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[MAX:32] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 +FORCE_INLINE __m128i _mm_loadu_si32(const void *p) +{ + return vreinterpretq_m128i_s32( + vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed single-precision (32-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) +// ENDFOR +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps +FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) +{ +#if defined(__aarch64__) + float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); + return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); +#else + float a0 = (float) ((double *) &a)[0]; + float a1 = (float) ((double *) &a)[1]; + return _mm_set_ps(0, 0, a1, a0); +#endif +} + +// Copy the lower double-precision (64-bit) floating-point element of a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 +FORCE_INLINE double _mm_cvtsd_f64(__m128d a) +{ +#if defined(__aarch64__) + return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); +#else + return ((double *) &a)[0]; +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed double-precision (64-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 64*j +// k := 32*j +// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd +FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); +#else + double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + return _mm_set_pd(a1, a0); +#endif +} + +// Cast vector of type __m128d to type __m128i. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 +FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) +{ + return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); +} + +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps +FORCE_INLINE __m128 _mm_blendv_ps(__m128 a, __m128 b, __m128 mask) +{ + return vreinterpretq_m128_f32(vbslq_f32(vreinterpretq_u32_m128(mask), + vreinterpretq_f32_m128(b), + vreinterpretq_f32_m128(a))); +} + +// Round the packed single-precision (32-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed single-precision +// floating-point elements in dst. +// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps +FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +{ +#if defined(__aarch64__) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); + } +#else + float *v_float = (float *) &a; + __m128 zero, neg_inf, pos_inf; + + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return _mm_cvtepi32_ps(_mm_cvtps_epi32(a)); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return (__m128){floorf(v_float[0]), floorf(v_float[1]), + floorf(v_float[2]), floorf(v_float[3])}; + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return (__m128){ceilf(v_float[0]), ceilf(v_float[1]), ceilf(v_float[2]), + ceilf(v_float[3])}; + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + zero = _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); + neg_inf = _mm_set_ps(floorf(v_float[0]), floorf(v_float[1]), + floorf(v_float[2]), floorf(v_float[3])); + pos_inf = _mm_set_ps(ceilf(v_float[0]), ceilf(v_float[1]), + ceilf(v_float[2]), ceilf(v_float[3])); + return _mm_blendv_ps(pos_inf, neg_inf, _mm_cmple_ps(a, zero)); + default: //_MM_FROUND_CUR_DIRECTION + return (__m128){roundf(v_float[0]), roundf(v_float[1]), + roundf(v_float[2]), roundf(v_float[3])}; + } +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi +FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpret_m64_s32( + vget_low_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)))); +#else + return vreinterpret_m64_s32( + vcvt_s32_f32(vget_low_f32(vreinterpretq_f32_m128( + _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC))))); +#endif +} + +// Round the packed single-precision (32-bit) floating-point elements in a up to +// an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps +FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) +{ + return _mm_round_ps(a, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +} + +// Round the packed single-precision (32-bit) floating-point elements in a down +// to an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps +FORCE_INLINE __m128 _mm_floor_ps(__m128 a) +{ + return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +} + + +// Load 128-bits of integer data from unaligned memory into dst. This intrinsic +// may perform better than _mm_loadu_si128 when the data crosses a cache line +// boundary. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 +#define _mm_lddqu_si128 _mm_loadu_si128 + +/* Miscellaneous Operations */ + +// Shifts the 8 signed 16-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// ... +// r7 := a7 >> count +// +// https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (c > 15) + return _mm_cmplt_epi16(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); +} + +// Shifts the 4 signed 32-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// r2 := a2 >> count +// r3 := a3 >> count +// +// https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx +FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (c > 31) + return _mm_cmplt_epi32(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); +} + +// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and +// saturates. +// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), + vqmovn_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// ... +// r7 := UnsignedSaturate(a7) +// r8 := UnsignedSaturate(b0) +// r9 := UnsignedSaturate(b1) +// ... +// r15 := UnsignedSaturate(b7) +// +// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) +{ + return vreinterpretq_m128i_u8( + vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), + vqmovun_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers +// and saturates. +// +// r0 := SignedSaturate(a0) +// r1 := SignedSaturate(a1) +// r2 := SignedSaturate(a2) +// r3 := SignedSaturate(a3) +// r4 := SignedSaturate(b0) +// r5 := SignedSaturate(b1) +// r6 := SignedSaturate(b2) +// r7 := SignedSaturate(b3) +// +// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), + vqmovn_s32(vreinterpretq_s32_m128i(b)))); +} + +// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// r2 := UnsignedSaturate(a2) +// r3 := UnsignedSaturate(a3) +// r4 := UnsignedSaturate(b0) +// r5 := UnsignedSaturate(b1) +// r6 := UnsignedSaturate(b2) +// r7 := UnsignedSaturate(b3) +FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), + vqmovun_s32(vreinterpretq_s32_m128i(b)))); +} + +// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// ... +// r14 := a7 +// r15 := b7 +// +// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the +// lower 4 signed or unsigned 16-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// r4 := a2 +// r5 := b2 +// r6 := a3 +// r7 := b3 +// +// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the +// lower 2 signed or unsigned 32 - bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +{ + int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); +} + +// Selects and interleaves the lower two single-precision, floating-point values +// from a and b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Selects and interleaves the upper two single-precision, floating-point values +// from a and b. +// +// r0 := a2 +// r1 := b2 +// r2 := a3 +// r3 := b3 +// +// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a8 +// r1 := b8 +// r2 := a9 +// r3 := b9 +// ... +// r14 := a15 +// r15 := b15 +// +// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the +// upper 4 signed or unsigned 16-bit integers in b. +// +// r0 := a4 +// r1 := b4 +// r2 := a5 +// r3 := b5 +// r4 := a6 +// r5 := b6 +// r6 := a7 +// r7 := b7 +// +// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the +// upper 2 signed or unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper signed or unsigned 64-bit integer in a with the +// upper signed or unsigned 64-bit integer in b. +// +// r0 := a1 +// r1 := b1 +FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +{ + int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); +} + +// Horizontally compute the minimum amongst the packed unsigned 16-bit integers +// in a, store the minimum and index in dst, and zero the remaining bits in dst. +// +// index[2:0] := 0 +// min[15:0] := a[15:0] +// FOR j := 0 to 7 +// i := j*16 +// IF a[i+15:i] < min[15:0] +// index[2:0] := j +// min[15:0] := a[i+15:i] +// FI +// ENDFOR +// dst[15:0] := min[15:0] +// dst[18:16] := index[2:0] +// dst[127:19] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_minpos_epu16 +FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a) +{ + __m128i dst; + uint16_t min, idx = 0; + // Find the minimum value +#if defined(__aarch64__) + min = vminvq_u16(vreinterpretq_u16_m128i(a)); +#else + __m64 tmp; + tmp = vreinterpret_m64_u16( + vmin_u16(vget_low_u16(vreinterpretq_u16_m128i(a)), + vget_high_u16(vreinterpretq_u16_m128i(a)))); + tmp = vreinterpret_m64_u16( + vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp))); + tmp = vreinterpret_m64_u16( + vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp))); + min = vget_lane_u16(vreinterpret_u16_m64(tmp), 0); +#endif + // Get the index of the minimum value + int i; + for (i = 0; i < 8; i++) { + if (min == vgetq_lane_u16(vreinterpretq_u16_m128i(a), 0)) { + idx = (uint16_t) i; + break; + } + a = _mm_srli_si128(a, 2); + } + // Generate result + dst = _mm_setzero_si128(); + dst = vreinterpretq_m128i_u16( + vsetq_lane_u16(min, vreinterpretq_u16_m128i(dst), 0)); + dst = vreinterpretq_m128i_u16( + vsetq_lane_u16(idx, vreinterpretq_u16_m128i(dst), 1)); + return dst; +} + +// shift to right +// https://msdn.microsoft.com/en-us/library/bb514041(v=vs.120).aspx +// http://blog.csdn.net/hemmingway/article/details/44828303 +// Clang requires a macro here, as it is extremely picky about c being a +// literal. +#define _mm_alignr_epi8(a, b, c) \ + ((__m128i) vextq_s8((int8x16_t)(b), (int8x16_t)(a), (c))) + +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return the CF value. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testc_si128 +FORCE_INLINE int _mm_testc_si128(__m128i a, __m128i b) +{ + int64x2_t s64 = + vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(vreinterpretq_s32_m128i(a))), + vreinterpretq_s64_m128i(b)); + return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return the ZF value. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testz_si128 +FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) +{ + int64x2_t s64 = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)); + return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); +} + +// Extracts the selected signed or unsigned 8-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) +#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) + +// Inserts the least significant 8 bits of b into the selected 8-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, +// __constrange(0,16) int imm) +#define _mm_insert_epi8(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s8( \ + vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 16-bit integer from a and zero +// extends. +// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx +// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) +#define _mm_extract_epi16(a, imm) \ + vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) + +// Inserts the least significant 16 bits of b into the selected 16-bit integer +// of a. +// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx +// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, +// __constrange(0,8) int imm) +#define _mm_insert_epi16(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 32-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) +#define _mm_extract_epi32(a, imm) \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) + +// Extracts the selected single-precision (32-bit) floating-point from a. +// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) +#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) + +// Inserts the least significant 32 bits of b into the selected 32-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, +// __constrange(0,4) int imm) +#define _mm_insert_epi32(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 64-bit integer from a and zero +// extends. +// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) +#define _mm_extract_epi64(a, imm) \ + vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) + +// Inserts the least significant 64 bits of b into the selected 64-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, +// __constrange(0,2) int imm) +#define _mm_insert_epi64(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ + }) + +// Count the number of bits set to 1 in unsigned 32-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 +FORCE_INLINE int _mm_popcnt_u32(unsigned int a) +{ +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(a); +#else + return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); +#endif +#else + uint32_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + + vst1_u32(&count, count32x2_val); + return count; +#endif +} + +// Count the number of bits set to 1 in unsigned 64-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 +FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) +{ +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcountll) + return __builtin_popcountll(a); +#else + return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); +#endif +#else + uint64_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + uint64x1_t count64x1_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + count64x1_val = vpaddl_u32(count32x2_val); + vst1_u64(&count, count64x1_val); + return count; +#endif +} + +// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision +// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the +// transposed matrix in these vectors (row0 now contains column 0, etc.). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ + float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ + row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ + vget_low_f32(ROW23.val[0])); \ + row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ + vget_low_f32(ROW23.val[1])); \ + row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ + vget_high_f32(ROW23.val[0])); \ + row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ + vget_high_f32(ROW23.val[1])); \ + } while (0) + +/* Crypto Extensions */ + +#if defined(__ARM_FEATURE_CRYPTO) +// Wraps vmull_p64 +FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); + poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); + return vreinterpretq_u64_p128(vmull_p64(a, b)); +} +#else // ARMv7 polyfill +// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. +// +// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a +// 64-bit->128-bit polynomial multiply. +// +// It needs some work and is somewhat slow, but it is still faster than all +// known scalar methods. +// +// Algorithm adapted to C from +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted +// from "Fast Software Polynomial Multiplication on ARM Processors Using the +// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab +// (https://hal.inria.fr/hal-01506572) +static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly8x8_t a = vreinterpret_p8_u64(_a); + poly8x8_t b = vreinterpret_p8_u64(_b); + + // Masks + uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), + vcreate_u8(0x00000000ffffffff)); + uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), + vcreate_u8(0x0000000000000000)); + + // Do the multiplies, rotating with vext to get all combinations + uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 + uint8x16_t e = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 + uint8x16_t f = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 + uint8x16_t g = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 + uint8x16_t h = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 + uint8x16_t i = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 + uint8x16_t j = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 + uint8x16_t k = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 + + // Add cross products + uint8x16_t l = veorq_u8(e, f); // L = E + F + uint8x16_t m = veorq_u8(g, h); // M = G + H + uint8x16_t n = veorq_u8(i, j); // N = I + J + + // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL + // instructions. +#if defined(__aarch64__) + uint8x16_t lm_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t lm_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t nk_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); + uint8x16_t nk_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#else + uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); + uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); + uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); + uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); +#endif + // t0 = (L) (P0 + P1) << 8 + // t1 = (M) (P2 + P3) << 16 + uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); + uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); + uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); + + // t2 = (N) (P4 + P5) << 24 + // t3 = (K) (P6 + P7) << 32 + uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); + uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); + uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); + + // De-interleave +#if defined(__aarch64__) + uint8x16_t t0 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t1 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t2 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); + uint8x16_t t3 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); +#else + uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); + uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); + uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); + uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); +#endif + // Shift the cross products + uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 + uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 + uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 + uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 + + // Accumulate the products + uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); + uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); + uint8x16_t mix = veorq_u8(d, cross1); + uint8x16_t r = veorq_u8(mix, cross2); + return vreinterpretq_u64_u8(r); +} +#endif // ARMv7 polyfill + +FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) +{ + uint64x2_t a = vreinterpretq_u64_m128i(_a); + uint64x2_t b = vreinterpretq_u64_m128i(_b); + switch (imm & 0x11) { + case 0x00: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); + case 0x01: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); + case 0x10: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); + case 0x11: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); + default: + abort(); + } +} + +#if !defined(__ARM_FEATURE_CRYPTO) +/* clang-format off */ +#define SSE2NEON_AES_DATA(w) \ + { \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), \ + w(0xc5), w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), \ + w(0xab), w(0x76), w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), \ + w(0x59), w(0x47), w(0xf0), w(0xad), w(0xd4), w(0xa2), w(0xaf), \ + w(0x9c), w(0xa4), w(0x72), w(0xc0), w(0xb7), w(0xfd), w(0x93), \ + w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc), w(0x34), w(0xa5), \ + w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15), w(0x04), \ + w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a), \ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), \ + w(0x75), w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), \ + w(0x5a), w(0xa0), w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), \ + w(0xe3), w(0x2f), w(0x84), w(0x53), w(0xd1), w(0x00), w(0xed), \ + w(0x20), w(0xfc), w(0xb1), w(0x5b), w(0x6a), w(0xcb), w(0xbe), \ + w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf), w(0xd0), w(0xef), \ + w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85), w(0x45), \ + w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8), \ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), \ + w(0xf5), w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), \ + w(0xf3), w(0xd2), w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), \ + w(0x97), w(0x44), w(0x17), w(0xc4), w(0xa7), w(0x7e), w(0x3d), \ + w(0x64), w(0x5d), w(0x19), w(0x73), w(0x60), w(0x81), w(0x4f), \ + w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88), w(0x46), w(0xee), \ + w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb), w(0xe0), \ + w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c), \ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), \ + w(0x79), w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), \ + w(0x4e), w(0xa9), w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), \ + w(0x7a), w(0xae), w(0x08), w(0xba), w(0x78), w(0x25), w(0x2e), \ + w(0x1c), w(0xa6), w(0xb4), w(0xc6), w(0xe8), w(0xdd), w(0x74), \ + w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a), w(0x70), w(0x3e), \ + w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e), w(0x61), \ + w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e), \ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), \ + w(0x94), w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), \ + w(0x28), w(0xdf), w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), \ + w(0xe6), w(0x42), w(0x68), w(0x41), w(0x99), w(0x2d), w(0x0f), \ + w(0xb0), w(0x54), w(0xbb), w(0x16) \ + } +/* clang-format on */ + +/* X Macro trick. See https://en.wikipedia.org/wiki/X_Macro */ +#define SSE2NEON_AES_H0(x) (x) +static const uint8_t SSE2NEON_sbox[256] = SSE2NEON_AES_DATA(SSE2NEON_AES_H0); +#undef SSE2NEON_AES_H0 + +// In the absence of crypto extensions, implement aesenc using regular neon +// intrinsics instead. See: +// https://www.workofard.com/2017/01/accelerated-aes-for-the-arm64-linux-kernel/ +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/ and +// https://github.com/ColinIanKing/linux-next-mirror/blob/b5f466091e130caaf0735976648f72bd5e09aa84/crypto/aegis128-neon-inner.c#L52 +// for more information Reproduced with permission of the author. +FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey) +{ +#if defined(__aarch64__) + static const uint8_t shift_rows[] = {0x0, 0x5, 0xa, 0xf, 0x4, 0x9, + 0xe, 0x3, 0x8, 0xd, 0x2, 0x7, + 0xc, 0x1, 0x6, 0xb}; + static const uint8_t ror32by8[] = {0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x4, + 0x9, 0xa, 0xb, 0x8, 0xd, 0xe, 0xf, 0xc}; + + uint8x16_t v; + uint8x16_t w = vreinterpretq_u8_m128i(EncBlock); + + // shift rows + w = vqtbl1q_u8(w, vld1q_u8(shift_rows)); + + // sub bytes + v = vqtbl4q_u8(vld1q_u8_x4(SSE2NEON_sbox), w); + v = vqtbx4q_u8(v, vld1q_u8_x4(SSE2NEON_sbox + 0x40), w - 0x40); + v = vqtbx4q_u8(v, vld1q_u8_x4(SSE2NEON_sbox + 0x80), w - 0x80); + v = vqtbx4q_u8(v, vld1q_u8_x4(SSE2NEON_sbox + 0xc0), w - 0xc0); + + // mix columns + w = (v << 1) ^ (uint8x16_t)(((int8x16_t) v >> 7) & 0x1b); + w ^= (uint8x16_t) vrev32q_u16((uint16x8_t) v); + w ^= vqtbl1q_u8(v ^ w, vld1q_u8(ror32by8)); + + // add round key + return vreinterpretq_m128i_u8(w) ^ RoundKey; + +#else /* ARMv7-A NEON implementation */ +#define SSE2NEON_AES_B2W(b0, b1, b2, b3) \ + (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | \ + (b0)) +#define SSE2NEON_AES_F2(x) ((x << 1) ^ (((x >> 7) & 1) * 0x011b /* WPOLY */)) +#define SSE2NEON_AES_F3(x) (SSE2NEON_AES_F2(x) ^ x) +#define SSE2NEON_AES_U0(p) \ + SSE2NEON_AES_B2W(SSE2NEON_AES_F2(p), p, p, SSE2NEON_AES_F3(p)) +#define SSE2NEON_AES_U1(p) \ + SSE2NEON_AES_B2W(SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p, p) +#define SSE2NEON_AES_U2(p) \ + SSE2NEON_AES_B2W(p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p) +#define SSE2NEON_AES_U3(p) \ + SSE2NEON_AES_B2W(p, p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p)) + static const uint32_t ALIGN_STRUCT(16) aes_table[4][256] = { + SSE2NEON_AES_DATA(SSE2NEON_AES_U0), + SSE2NEON_AES_DATA(SSE2NEON_AES_U1), + SSE2NEON_AES_DATA(SSE2NEON_AES_U2), + SSE2NEON_AES_DATA(SSE2NEON_AES_U3), + }; +#undef SSE2NEON_AES_B2W +#undef SSE2NEON_AES_F2 +#undef SSE2NEON_AES_F3 +#undef SSE2NEON_AES_U0 +#undef SSE2NEON_AES_U1 +#undef SSE2NEON_AES_U2 +#undef SSE2NEON_AES_U3 + + uint32_t x0 = _mm_cvtsi128_si32(EncBlock); + uint32_t x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0x55)); + uint32_t x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xAA)); + uint32_t x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xFF)); + + __m128i out = _mm_set_epi32( + (aes_table[0][x3 & 0xff] ^ aes_table[1][(x0 >> 8) & 0xff] ^ + aes_table[2][(x1 >> 16) & 0xff] ^ aes_table[3][x2 >> 24]), + (aes_table[0][x2 & 0xff] ^ aes_table[1][(x3 >> 8) & 0xff] ^ + aes_table[2][(x0 >> 16) & 0xff] ^ aes_table[3][x1 >> 24]), + (aes_table[0][x1 & 0xff] ^ aes_table[1][(x2 >> 8) & 0xff] ^ + aes_table[2][(x3 >> 16) & 0xff] ^ aes_table[3][x0 >> 24]), + (aes_table[0][x0 & 0xff] ^ aes_table[1][(x1 >> 8) & 0xff] ^ + aes_table[2][(x2 >> 16) & 0xff] ^ aes_table[3][x3 >> 24])); + + return _mm_xor_si128(out, RoundKey); +#endif +} + +FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) +{ + /* FIXME: optimized for NEON */ + uint8_t v[4][4] = { + [0] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, + [1] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, + [2] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, + [3] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, + }; + for (int i = 0; i < 16; i++) + vreinterpretq_nth_u8_m128i(a, i) = + v[i / 4][i % 4] ^ vreinterpretq_nth_u8_m128i(RoundKey, i); + return a; +} + +// Emits the Advanced Encryption Standard (AES) instruction aeskeygenassist. +// This instruction generates a round key for AES encryption. See +// https://kazakov.life/2017/11/01/cryptocurrency-mining-on-ios-devices/ +// for details. +// +// https://msdn.microsoft.com/en-us/library/cc714138(v=vs.120).aspx +FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i key, const int rcon) +{ + uint32_t X1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55)); + uint32_t X3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF)); + for (int i = 0; i < 4; ++i) { + ((uint8_t *) &X1)[i] = SSE2NEON_sbox[((uint8_t *) &X1)[i]]; + ((uint8_t *) &X3)[i] = SSE2NEON_sbox[((uint8_t *) &X3)[i]]; + } + return _mm_set_epi32(((X3 >> 8) | (X3 << 24)) ^ rcon, X3, + ((X1 >> 8) | (X1 << 24)) ^ rcon, X1); +} +#undef SSE2NEON_AES_DATA + +#else /* __ARM_FEATURE_CRYPTO */ +// Implements equivalent of 'aesenc' by combining AESE (with an empty key) and +// AESMC and then manually applying the real key as an xor operation. This +// unfortunately means an additional xor op; the compiler should be able to +// optimize this away for repeated calls however. See +// https://blog.michaelbrase.com/2018/05/08/emulating-x86-aes-intrinsics-on-armv8-a +// for more details. +FORCE_INLINE __m128i _mm_aesenc_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))) ^ + vreinterpretq_u8_m128i(b)); +} + +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128 +FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) +{ + return _mm_xor_si128(vreinterpretq_m128i_u8(vaeseq_u8( + vreinterpretq_u8_m128i(a), vdupq_n_u8(0))), + RoundKey); +} + +FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) +{ + // AESE does ShiftRows and SubBytes on A + uint8x16_t u8 = vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0)); + + uint8x16_t dest = { + // Undo ShiftRows step from AESE and extract X1 and X3 + u8[0x4], u8[0x1], u8[0xE], u8[0xB], // SubBytes(X1) + u8[0x1], u8[0xE], u8[0xB], u8[0x4], // ROT(SubBytes(X1)) + u8[0xC], u8[0x9], u8[0x6], u8[0x3], // SubBytes(X3) + u8[0x9], u8[0x6], u8[0x3], u8[0xC], // ROT(SubBytes(X3)) + }; + uint32x4_t r = {0, (unsigned) rcon, 0, (unsigned) rcon}; + return vreinterpretq_m128i_u8(dest) ^ vreinterpretq_m128i_u32(r); +} +#endif + +/* Streaming Extensions */ + +// Guarantees that every preceding store is globally visible before any +// subsequent store. +// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx +FORCE_INLINE void _mm_sfence(void) +{ + __sync_synchronize(); +} + +// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- +// point elements) from a into memory using a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps +FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); +#else + vst1q_f32(p, vreinterpretq_f32_m128(a)); +#endif +} + +// Stores the data in a to the address p without polluting the caches. If the +// cache line containing address p is already in the cache, the cache will be +// updated. +// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx +FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, p); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); +#endif +} + +// Load 128-bits of integer data from memory into dst using a non-temporal +// memory hint. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 +FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) +{ +#if __has_builtin(__builtin_nontemporal_store) + return __builtin_nontemporal_load(p); +#else + return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); +#endif +} + +// Cache line containing p is flushed and invalidated from all caches in the +// coherency domain. : +// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx +FORCE_INLINE void _mm_clflush(void const *p) +{ + (void) p; + // no corollary for Neon? +} + +// Allocate aligned blocks of memory. +// https://software.intel.com/en-us/ +// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks +FORCE_INLINE void *_mm_malloc(size_t size, size_t align) +{ + void *ptr; + if (align == 1) + return malloc(size); + if (align == 2 || (sizeof(void *) == 8 && align == 4)) + align = sizeof(void *); + if (!posix_memalign(&ptr, align, size)) + return ptr; + return NULL; +} + +FORCE_INLINE void _mm_free(void *addr) +{ + free(addr); +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 8-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc ^= v; + for (int bit = 0; bit < 8; bit++) { + if (crc & 1) + crc = (crc >> 1) ^ UINT32_C(0x82f63b78); + else + crc = (crc >> 1); + } +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 16-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u8(crc, v & 0xff); + crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 32-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u16(crc, v & 0xffff); + crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 64-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) +FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff); + crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff); +#endif + return crc; +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma pop_macro("ALIGN_STRUCT") +#pragma pop_macro("FORCE_INLINE") +#endif + +#if defined(__GNUC__) +#pragma GCC pop_options +#endif + +#endif diff --git a/.venv/include/site/python3.7/pygame/mask.h b/.venv/include/site/python3.7/pygame/mask.h new file mode 100644 index 0000000..45ad8c5 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/mask.h @@ -0,0 +1,7 @@ +#ifndef PGMASK_INTERNAL_H +#define PGMASK_INTERNAL_H + +#include "include/pygame_mask.h" +#define PYGAMEAPI_MASK_NUMSLOTS 1 + +#endif /* ~PGMASK_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/mixer.h b/.venv/include/site/python3.7/pygame/mixer.h new file mode 100644 index 0000000..97f5a0f --- /dev/null +++ b/.venv/include/site/python3.7/pygame/mixer.h @@ -0,0 +1,14 @@ +#ifndef MIXER_INTERNAL_H +#define MIXER_INTERNAL_H + +#include + +/* test mixer initializations */ +#define MIXER_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_AUDIO)) \ + return RAISE(pgExc_SDLError, "mixer not initialized") + +#define PYGAMEAPI_MIXER_NUMSLOTS 5 +#include "include/pygame_mixer.h" + +#endif /* ~MIXER_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/palette.h b/.venv/include/site/python3.7/pygame/palette.h new file mode 100644 index 0000000..1ae4cf6 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/palette.h @@ -0,0 +1,123 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef PALETTE_H +#define PALETTE_H + +#include + +/* SDL 2 does not assign a default palette color scheme to a new 8 bit + * surface. Instead, the palette is set all white. This defines the SDL 1.2 + * default palette. + */ +static const SDL_Color default_palette_colors[] = { + {0, 0, 0, 255}, {0, 0, 85, 255}, {0, 0, 170, 255}, + {0, 0, 255, 255}, {0, 36, 0, 255}, {0, 36, 85, 255}, + {0, 36, 170, 255}, {0, 36, 255, 255}, {0, 73, 0, 255}, + {0, 73, 85, 255}, {0, 73, 170, 255}, {0, 73, 255, 255}, + {0, 109, 0, 255}, {0, 109, 85, 255}, {0, 109, 170, 255}, + {0, 109, 255, 255}, {0, 146, 0, 255}, {0, 146, 85, 255}, + {0, 146, 170, 255}, {0, 146, 255, 255}, {0, 182, 0, 255}, + {0, 182, 85, 255}, {0, 182, 170, 255}, {0, 182, 255, 255}, + {0, 219, 0, 255}, {0, 219, 85, 255}, {0, 219, 170, 255}, + {0, 219, 255, 255}, {0, 255, 0, 255}, {0, 255, 85, 255}, + {0, 255, 170, 255}, {0, 255, 255, 255}, {85, 0, 0, 255}, + {85, 0, 85, 255}, {85, 0, 170, 255}, {85, 0, 255, 255}, + {85, 36, 0, 255}, {85, 36, 85, 255}, {85, 36, 170, 255}, + {85, 36, 255, 255}, {85, 73, 0, 255}, {85, 73, 85, 255}, + {85, 73, 170, 255}, {85, 73, 255, 255}, {85, 109, 0, 255}, + {85, 109, 85, 255}, {85, 109, 170, 255}, {85, 109, 255, 255}, + {85, 146, 0, 255}, {85, 146, 85, 255}, {85, 146, 170, 255}, + {85, 146, 255, 255}, {85, 182, 0, 255}, {85, 182, 85, 255}, + {85, 182, 170, 255}, {85, 182, 255, 255}, {85, 219, 0, 255}, + {85, 219, 85, 255}, {85, 219, 170, 255}, {85, 219, 255, 255}, + {85, 255, 0, 255}, {85, 255, 85, 255}, {85, 255, 170, 255}, + {85, 255, 255, 255}, {170, 0, 0, 255}, {170, 0, 85, 255}, + {170, 0, 170, 255}, {170, 0, 255, 255}, {170, 36, 0, 255}, + {170, 36, 85, 255}, {170, 36, 170, 255}, {170, 36, 255, 255}, + {170, 73, 0, 255}, {170, 73, 85, 255}, {170, 73, 170, 255}, + {170, 73, 255, 255}, {170, 109, 0, 255}, {170, 109, 85, 255}, + {170, 109, 170, 255}, {170, 109, 255, 255}, {170, 146, 0, 255}, + {170, 146, 85, 255}, {170, 146, 170, 255}, {170, 146, 255, 255}, + {170, 182, 0, 255}, {170, 182, 85, 255}, {170, 182, 170, 255}, + {170, 182, 255, 255}, {170, 219, 0, 255}, {170, 219, 85, 255}, + {170, 219, 170, 255}, {170, 219, 255, 255}, {170, 255, 0, 255}, + {170, 255, 85, 255}, {170, 255, 170, 255}, {170, 255, 255, 255}, + {255, 0, 0, 255}, {255, 0, 85, 255}, {255, 0, 170, 255}, + {255, 0, 255, 255}, {255, 36, 0, 255}, {255, 36, 85, 255}, + {255, 36, 170, 255}, {255, 36, 255, 255}, {255, 73, 0, 255}, + {255, 73, 85, 255}, {255, 73, 170, 255}, {255, 73, 255, 255}, + {255, 109, 0, 255}, {255, 109, 85, 255}, {255, 109, 170, 255}, + {255, 109, 255, 255}, {255, 146, 0, 255}, {255, 146, 85, 255}, + {255, 146, 170, 255}, {255, 146, 255, 255}, {255, 182, 0, 255}, + {255, 182, 85, 255}, {255, 182, 170, 255}, {255, 182, 255, 255}, + {255, 219, 0, 255}, {255, 219, 85, 255}, {255, 219, 170, 255}, + {255, 219, 255, 255}, {255, 255, 0, 255}, {255, 255, 85, 255}, + {255, 255, 170, 255}, {255, 255, 255, 255}, {0, 0, 0, 255}, + {0, 0, 85, 255}, {0, 0, 170, 255}, {0, 0, 255, 255}, + {0, 36, 0, 255}, {0, 36, 85, 255}, {0, 36, 170, 255}, + {0, 36, 255, 255}, {0, 73, 0, 255}, {0, 73, 85, 255}, + {0, 73, 170, 255}, {0, 73, 255, 255}, {0, 109, 0, 255}, + {0, 109, 85, 255}, {0, 109, 170, 255}, {0, 109, 255, 255}, + {0, 146, 0, 255}, {0, 146, 85, 255}, {0, 146, 170, 255}, + {0, 146, 255, 255}, {0, 182, 0, 255}, {0, 182, 85, 255}, + {0, 182, 170, 255}, {0, 182, 255, 255}, {0, 219, 0, 255}, + {0, 219, 85, 255}, {0, 219, 170, 255}, {0, 219, 255, 255}, + {0, 255, 0, 255}, {0, 255, 85, 255}, {0, 255, 170, 255}, + {0, 255, 255, 255}, {85, 0, 0, 255}, {85, 0, 85, 255}, + {85, 0, 170, 255}, {85, 0, 255, 255}, {85, 36, 0, 255}, + {85, 36, 85, 255}, {85, 36, 170, 255}, {85, 36, 255, 255}, + {85, 73, 0, 255}, {85, 73, 85, 255}, {85, 73, 170, 255}, + {85, 73, 255, 255}, {85, 109, 0, 255}, {85, 109, 85, 255}, + {85, 109, 170, 255}, {85, 109, 255, 255}, {85, 146, 0, 255}, + {85, 146, 85, 255}, {85, 146, 170, 255}, {85, 146, 255, 255}, + {85, 182, 0, 255}, {85, 182, 85, 255}, {85, 182, 170, 255}, + {85, 182, 255, 255}, {85, 219, 0, 255}, {85, 219, 85, 255}, + {85, 219, 170, 255}, {85, 219, 255, 255}, {85, 255, 0, 255}, + {85, 255, 85, 255}, {85, 255, 170, 255}, {85, 255, 255, 255}, + {170, 0, 0, 255}, {170, 0, 85, 255}, {170, 0, 170, 255}, + {170, 0, 255, 255}, {170, 36, 0, 255}, {170, 36, 85, 255}, + {170, 36, 170, 255}, {170, 36, 255, 255}, {170, 73, 0, 255}, + {170, 73, 85, 255}, {170, 73, 170, 255}, {170, 73, 255, 255}, + {170, 109, 0, 255}, {170, 109, 85, 255}, {170, 109, 170, 255}, + {170, 109, 255, 255}, {170, 146, 0, 255}, {170, 146, 85, 255}, + {170, 146, 170, 255}, {170, 146, 255, 255}, {170, 182, 0, 255}, + {170, 182, 85, 255}, {170, 182, 170, 255}, {170, 182, 255, 255}, + {170, 219, 0, 255}, {170, 219, 85, 255}, {170, 219, 170, 255}, + {170, 219, 255, 255}, {170, 255, 0, 255}, {170, 255, 85, 255}, + {170, 255, 170, 255}, {170, 255, 255, 255}, {255, 0, 0, 255}, + {255, 0, 85, 255}, {255, 0, 170, 255}, {255, 0, 255, 255}, + {255, 36, 0, 255}, {255, 36, 85, 255}, {255, 36, 170, 255}, + {255, 36, 255, 255}, {255, 73, 0, 255}, {255, 73, 85, 255}, + {255, 73, 170, 255}, {255, 73, 255, 255}, {255, 109, 0, 255}, + {255, 109, 85, 255}, {255, 109, 170, 255}, {255, 109, 255, 255}, + {255, 146, 0, 255}, {255, 146, 85, 255}, {255, 146, 170, 255}, + {255, 146, 255, 255}, {255, 182, 0, 255}, {255, 182, 85, 255}, + {255, 182, 170, 255}, {255, 182, 255, 255}, {255, 219, 0, 255}, + {255, 219, 85, 255}, {255, 219, 170, 255}, {255, 219, 255, 255}, + {255, 255, 0, 255}, {255, 255, 85, 255}, {255, 255, 170, 255}, + {255, 255, 255, 255}}; + +static const int default_palette_size = + (int)(sizeof(default_palette_colors) / sizeof(SDL_Color)); + +#endif diff --git a/.venv/include/site/python3.7/pygame/pgarrinter.h b/.venv/include/site/python3.7/pygame/pgarrinter.h new file mode 100644 index 0000000..5ba096b --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pgarrinter.h @@ -0,0 +1,26 @@ +/* array structure interface version 3 declarations */ + +#if !defined(PG_ARRAYINTER_HEADER) +#define PG_ARRAYINTER_HEADER + +static const int PAI_CONTIGUOUS = 0x01; +static const int PAI_FORTRAN = 0x02; +static const int PAI_ALIGNED = 0x100; +static const int PAI_NOTSWAPPED = 0x200; +static const int PAI_WRITEABLE = 0x400; +static const int PAI_ARR_HAS_DESCR = 0x800; + +typedef struct { + int two; /* contains the integer 2 -- simple sanity check */ + int nd; /* number of dimensions */ + char typekind; /* kind in array -- character code of typestr */ + int itemsize; /* size of each element */ + int flags; /* flags indicating how the data should be */ + /* interpreted */ + Py_intptr_t *shape; /* A length-nd array of shape information */ + Py_intptr_t *strides; /* A length-nd array of stride information */ + void *data; /* A pointer to the first element of the array */ + PyObject *descr; /* NULL or a data-description */ +} PyArrayInterface; + +#endif diff --git a/.venv/include/site/python3.7/pygame/pgbufferproxy.h b/.venv/include/site/python3.7/pygame/pgbufferproxy.h new file mode 100644 index 0000000..1507608 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pgbufferproxy.h @@ -0,0 +1,7 @@ +#ifndef PG_BUFPROXY_INTERNAL_H +#define PG_BUFPROXY_INTERNAL_H + +#include "include/pygame_bufferproxy.h" +#define PYGAMEAPI_BUFPROXY_NUMSLOTS 4 + +#endif /* ~PG_BUFPROXY_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/pgcompat.h b/.venv/include/site/python3.7/pygame/pgcompat.h new file mode 100644 index 0000000..1bc0d24 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pgcompat.h @@ -0,0 +1,27 @@ +/* Python 2.x/3.x compatibility tools (internal) + */ +#ifndef PGCOMPAT_INTERNAL_H +#define PGCOMPAT_INTERNAL_H + +#include "include/pgcompat.h" + +/* Module init function returns new module instance. */ +#define MODINIT_DEFINE(mod_name) PyMODINIT_FUNC PyInit_##mod_name(void) + +/* Defaults for unicode file path encoding */ +#if defined(MS_WIN32) +#define UNICODE_DEF_FS_ERROR "replace" +#else +#define UNICODE_DEF_FS_ERROR "surrogateescape" +#endif + +#define RELATIVE_MODULE(m) ("." m) + +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER +#define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif + +#define Slice_GET_INDICES_EX(slice, length, start, stop, step, slicelength) \ + PySlice_GetIndicesEx(slice, length, start, stop, step, slicelength) + +#endif /* ~PGCOMPAT_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/pgopengl.h b/.venv/include/site/python3.7/pygame/pgopengl.h new file mode 100644 index 0000000..a845cbf --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pgopengl.h @@ -0,0 +1,20 @@ +#if !defined(PGOPENGL_H) +#define PGOPENGL_H + +/** This header includes definitions of Opengl functions as pointer types for + ** use with the SDL function SDL_GL_GetProcAddress. + **/ + +#if defined(_WIN32) +#define GL_APIENTRY __stdcall +#else +#define GL_APIENTRY +#endif + +typedef void(GL_APIENTRY *GL_glReadPixels_Func)(int, int, int, int, + unsigned int, unsigned int, + void *); + +typedef void(GL_APIENTRY *GL_glViewport_Func)(int, int, unsigned int, + unsigned int); +#endif diff --git a/.venv/include/site/python3.7/pygame/pgplatform.h b/.venv/include/site/python3.7/pygame/pgplatform.h new file mode 100644 index 0000000..54310eb --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pgplatform.h @@ -0,0 +1,23 @@ +/* platform/compiler adjustments (internal) */ +#ifndef PG_PLATFORM_INTERNAL_H +#define PG_PLATFORM_INTERNAL_H + +#include "include/pgplatform.h" + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#endif + +/* warnings */ +#define PG_STRINGIZE_HELPER(x) #x +#define PG_STRINGIZE(x) PG_STRINGIZE_HELPER(x) +#define PG_WARN(desc) \ + message(__FILE__ "(" PG_STRINGIZE(__LINE__) "): WARNING: " #desc) + +#endif /* ~PG_PLATFORM_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/pygame.h b/.venv/include/site/python3.7/pygame/pygame.h new file mode 100644 index 0000000..d7eaf73 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/pygame.h @@ -0,0 +1,32 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* This will use PYGAMEAPI_DEFINE_SLOTS instead + * of PYGAMEAPI_EXTERN_SLOTS for base modules. + */ +#ifndef PYGAME_INTERNAL_H +#define PYGAME_INTERNAL_H + +#define PYGAME_H +#include "_pygame.h" + +#endif /* ~PYGAME_INTERNAL_H */ diff --git a/.venv/include/site/python3.7/pygame/scrap.h b/.venv/include/site/python3.7/pygame/scrap.h new file mode 100644 index 0000000..5866b56 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/scrap.h @@ -0,0 +1,147 @@ +/* + pygame - Python Game Library + Copyright (C) 2006, 2007 Rene Dudfield, Marcus von Appen + + Originally put in the public domain by Sam Lantinga. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SCRAP_H +#define SCRAP_H + +/* This is unconditionally defined in Python.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +#include + +/* Handle clipboard text and data in arbitrary formats */ + +/** + * Predefined supported pygame scrap types. + */ +#define PYGAME_SCRAP_TEXT "text/plain" +#define PYGAME_SCRAP_BMP "image/bmp" +#define PYGAME_SCRAP_PPM "image/ppm" +#define PYGAME_SCRAP_PBM "image/pbm" + +/** + * The supported scrap clipboard types. + * + * This is only relevant in a X11 environment, which supports mouse + * selections as well. For Win32 and MacOS environments the default + * clipboard is used, no matter what value is passed. + */ +typedef enum { + SCRAP_CLIPBOARD, + SCRAP_SELECTION /* only supported in X11 environments. */ +} ScrapClipType; + +/** + * Macro for initialization checks. + */ +#define PYGAME_SCRAP_INIT_CHECK() \ + if (!pygame_scrap_initialized()) \ + return (PyErr_SetString(pgExc_SDLError, "scrap system not initialized."), \ + NULL) + +/** + * \brief Checks, whether the pygame scrap module was initialized. + * + * \return 1 if the modules was initialized, 0 otherwise. + */ +extern int +pygame_scrap_initialized(void); + +/** + * \brief Initializes the pygame scrap module internals. Call this before any + * other method. + * + * \return 1 on successful initialization, 0 otherwise. + */ +extern int +pygame_scrap_init(void); + +/** + * \brief Checks, whether the pygame window lost the clipboard focus or not. + * + * \return 1 if the window lost the focus, 0 otherwise. + */ +extern int +pygame_scrap_lost(void); + +/** + * \brief Places content of a specific type into the clipboard. + * + * \note For X11 the following notes are important: The following types + * are reserved for internal usage and thus will throw an error on + * setting them: "TIMESTAMP", "TARGETS", "SDL_SELECTION". + * Setting PYGAME_SCRAP_TEXT ("text/plain") will also automatically + * set the X11 types "STRING" (XA_STRING), "TEXT" and "UTF8_STRING". + * + * For Win32 the following notes are important: Setting + * PYGAME_SCRAP_TEXT ("text/plain") will also automatically set + * the Win32 type "TEXT" (CF_TEXT). + * + * For QNX the following notes are important: Setting + * PYGAME_SCRAP_TEXT ("text/plain") will also automatically set + * the QNX type "TEXT" (Ph_CL_TEXT). + * + * \param type The type of the content. + * \param srclen The length of the content. + * \param src The NULL terminated content. + * \return 1, if the content could be successfully pasted into the clipboard, + * 0 otherwise. + */ +extern int +pygame_scrap_put(char *type, Py_ssize_t srclen, char *src); + +/** + * \brief Gets the current content from the clipboard. + * + * \note The received content does not need to be the content previously + * placed in the clipboard using pygame_put_scrap(). See the + * pygame_put_scrap() notes for more details. + * + * \param type The type of the content to receive. + * \param count The size of the returned content. + * \return The content or NULL in case of an error or if no content of the + * specified type was available. + */ +extern char * +pygame_scrap_get(char *type, size_t *count); + +/** + * \brief Gets the currently available content types from the clipboard. + * + * \return The different available content types or NULL in case of an + * error or if no content type is available. + */ +extern char ** +pygame_scrap_get_types(void); + +/** + * \brief Checks whether content for the specified scrap type is currently + * available in the clipboard. + * + * \param type The type to check for. + * \return 1, if there is content and 0 otherwise. + */ +extern int +pygame_scrap_contains(char *type); + +#endif /* SCRAP_H */ diff --git a/.venv/include/site/python3.7/pygame/simd_blitters.h b/.venv/include/site/python3.7/pygame/simd_blitters.h new file mode 100644 index 0000000..da0ecbb --- /dev/null +++ b/.venv/include/site/python3.7/pygame/simd_blitters.h @@ -0,0 +1,84 @@ +#define NO_PYGAME_C_API +#include "_surface.h" +#include "_blit_info.h" + +#if !defined(PG_ENABLE_ARM_NEON) && defined(__aarch64__) +// arm64 has neon optimisations enabled by default, even when fpu=neon is not +// passed +#define PG_ENABLE_ARM_NEON 1 +#endif + +int +pg_sse2_at_runtime_but_uncompiled(); +int +pg_neon_at_runtime_but_uncompiled(); +int +pg_avx2_at_runtime_but_uncompiled(); + +#if (defined(__SSE2__) || defined(PG_ENABLE_ARM_NEON)) +void +alphablit_alpha_sse2_argb_surf_alpha(SDL_BlitInfo *info); +void +alphablit_alpha_sse2_argb_no_surf_alpha(SDL_BlitInfo *info); +void +alphablit_alpha_sse2_argb_no_surf_alpha_opaque_dst(SDL_BlitInfo *info); +void +blit_blend_rgba_mul_sse2(SDL_BlitInfo *info); +void +blit_blend_rgb_mul_sse2(SDL_BlitInfo *info); +void +blit_blend_rgba_add_sse2(SDL_BlitInfo *info); +void +blit_blend_rgb_add_sse2(SDL_BlitInfo *info); +void +blit_blend_rgba_sub_sse2(SDL_BlitInfo *info); +void +blit_blend_rgb_sub_sse2(SDL_BlitInfo *info); +void +blit_blend_rgba_max_sse2(SDL_BlitInfo *info); +void +blit_blend_rgb_max_sse2(SDL_BlitInfo *info); +void +blit_blend_rgba_min_sse2(SDL_BlitInfo *info); +void +blit_blend_rgb_min_sse2(SDL_BlitInfo *info); +void +blit_blend_premultiplied_sse2(SDL_BlitInfo *info); +#endif /* (defined(__SSE2__) || defined(PG_ENABLE_ARM_NEON)) */ + +/* Deliberately putting these outside of the preprocessor guards as I want to + move to a system of trusting the runtime checks to head to the right + function and having a fallback function there if pygame is not compiled + with the right stuff (this is the strategy used for AVX2 right now. + Potentially I might want to shift both these into a slightly different + file as they are not exactly blits (though v. similar) - or I could rename + the SIMD trilogy of files to replace the word blit with something more + generic like surface_ops*/ + +void +premul_surf_color_by_alpha_non_simd(SDL_Surface *src, SDL_Surface *dst); +void +premul_surf_color_by_alpha_sse2(SDL_Surface *src, SDL_Surface *dst); + +int +pg_has_avx2(); +void +blit_blend_rgba_mul_avx2(SDL_BlitInfo *info); +void +blit_blend_rgb_mul_avx2(SDL_BlitInfo *info); +void +blit_blend_rgba_add_avx2(SDL_BlitInfo *info); +void +blit_blend_rgb_add_avx2(SDL_BlitInfo *info); +void +blit_blend_rgba_sub_avx2(SDL_BlitInfo *info); +void +blit_blend_rgb_sub_avx2(SDL_BlitInfo *info); +void +blit_blend_rgba_max_avx2(SDL_BlitInfo *info); +void +blit_blend_rgb_max_avx2(SDL_BlitInfo *info); +void +blit_blend_rgba_min_avx2(SDL_BlitInfo *info); +void +blit_blend_rgb_min_avx2(SDL_BlitInfo *info); diff --git a/.venv/include/site/python3.7/pygame/surface.h b/.venv/include/site/python3.7/pygame/surface.h new file mode 100644 index 0000000..21508c6 --- /dev/null +++ b/.venv/include/site/python3.7/pygame/surface.h @@ -0,0 +1,361 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef SURFACE_H +#define SURFACE_H + +/* This is defined in SDL.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +#include +#include "pygame.h" + +/* Blend modes */ +#define PYGAME_BLEND_ADD 0x1 +#define PYGAME_BLEND_SUB 0x2 +#define PYGAME_BLEND_MULT 0x3 +#define PYGAME_BLEND_MIN 0x4 +#define PYGAME_BLEND_MAX 0x5 + +#define PYGAME_BLEND_RGB_ADD 0x1 +#define PYGAME_BLEND_RGB_SUB 0x2 +#define PYGAME_BLEND_RGB_MULT 0x3 +#define PYGAME_BLEND_RGB_MIN 0x4 +#define PYGAME_BLEND_RGB_MAX 0x5 + +#define PYGAME_BLEND_RGBA_ADD 0x6 +#define PYGAME_BLEND_RGBA_SUB 0x7 +#define PYGAME_BLEND_RGBA_MULT 0x8 +#define PYGAME_BLEND_RGBA_MIN 0x9 +#define PYGAME_BLEND_RGBA_MAX 0x10 +#define PYGAME_BLEND_PREMULTIPLIED 0x11 +#define PYGAME_BLEND_ALPHA_SDL2 0x12 + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define GET_PIXEL_24(b) (b[0] + (b[1] << 8) + (b[2] << 16)) +#else +#define GET_PIXEL_24(b) (b[2] + (b[1] << 8) + (b[0] << 16)) +#endif + +#define GET_PIXEL(pxl, bpp, source) \ + switch (bpp) { \ + case 2: \ + pxl = *((Uint16 *)(source)); \ + break; \ + case 4: \ + pxl = *((Uint32 *)(source)); \ + break; \ + default: { \ + Uint8 *b = (Uint8 *)source; \ + pxl = GET_PIXEL_24(b); \ + } break; \ + } + +#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \ + SDL_GetRGBA(px, fmt, &(_sR), &(_sG), &(_sB), &(_sA)); \ + if (!ppa) { \ + _sA = 255; \ + } + +#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \ + sr = _fmt->palette->colors[*((Uint8 *)(_src))].r; \ + sg = _fmt->palette->colors[*((Uint8 *)(_src))].g; \ + sb = _fmt->palette->colors[*((Uint8 *)(_src))].b; \ + sa = 255; + +/* For 1 byte palette pixels */ +#define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \ + *(px) = (Uint8)SDL_MapRGBA(fmt, _dR, _dG, _dB, _dA) + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SET_OFFSETS_24(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 0 : fmt->Rshift == 8 ? 1 : 2); \ + og = (fmt->Gshift == 0 ? 0 : fmt->Gshift == 8 ? 1 : 2); \ + ob = (fmt->Bshift == 0 ? 0 : fmt->Bshift == 8 ? 1 : 2); \ + } + +#define SET_OFFSETS_32(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 0 \ + : fmt->Rshift == 8 ? 1 \ + : fmt->Rshift == 16 ? 2 \ + : 3); \ + og = (fmt->Gshift == 0 ? 0 \ + : fmt->Gshift == 8 ? 1 \ + : fmt->Gshift == 16 ? 2 \ + : 3); \ + ob = (fmt->Bshift == 0 ? 0 \ + : fmt->Bshift == 8 ? 1 \ + : fmt->Bshift == 16 ? 2 \ + : 3); \ + } +#else +#define SET_OFFSETS_24(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 2 : fmt->Rshift == 8 ? 1 : 0); \ + og = (fmt->Gshift == 0 ? 2 : fmt->Gshift == 8 ? 1 : 0); \ + ob = (fmt->Bshift == 0 ? 2 : fmt->Bshift == 8 ? 1 : 0); \ + } + +#define SET_OFFSETS_32(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 3 \ + : fmt->Rshift == 8 ? 2 \ + : fmt->Rshift == 16 ? 1 \ + : 0); \ + og = (fmt->Gshift == 0 ? 3 \ + : fmt->Gshift == 8 ? 2 \ + : fmt->Gshift == 16 ? 1 \ + : 0); \ + ob = (fmt->Bshift == 0 ? 3 \ + : fmt->Bshift == 8 ? 2 \ + : fmt->Bshift == 16 ? 1 \ + : 0); \ + } +#endif + +#define CREATE_PIXEL(buf, r, g, b, a, bp, ft) \ + switch (bp) { \ + case 2: \ + *((Uint16 *)(buf)) = ((r >> ft->Rloss) << ft->Rshift) | \ + ((g >> ft->Gloss) << ft->Gshift) | \ + ((b >> ft->Bloss) << ft->Bshift) | \ + ((a >> ft->Aloss) << ft->Ashift); \ + break; \ + case 4: \ + *((Uint32 *)(buf)) = ((r >> ft->Rloss) << ft->Rshift) | \ + ((g >> ft->Gloss) << ft->Gshift) | \ + ((b >> ft->Bloss) << ft->Bshift) | \ + ((a >> ft->Aloss) << ft->Ashift); \ + break; \ + } + +/* Pretty good idea from Tom Duff :-). */ +#define LOOP_UNROLLED4(code, n, width) \ + n = (width + 3) / 4; \ + switch (width & 3) { \ + case 0: \ + do { \ + code; \ + case 3: \ + code; \ + case 2: \ + code; \ + case 1: \ + code; \ + } while (--n > 0); \ + } + +/* Used in the srcbpp == dstbpp == 1 blend functions */ +#define REPEAT_3(code) \ + code; \ + code; \ + code; + +#define REPEAT_4(code) \ + code; \ + code; \ + code; \ + code; + +#define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR + sR; \ + dR = (tmp <= 255 ? tmp : 255); \ + tmp = dG + sG; \ + dG = (tmp <= 255 ? tmp : 255); \ + tmp = dB + sB; \ + dB = (tmp <= 255 ? tmp : 255); + +#define BLEND_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR - sR; \ + dR = (tmp >= 0 ? tmp : 0); \ + tmp = dG - sG; \ + dG = (tmp >= 0 ? tmp : 0); \ + tmp = dB - sB; \ + dB = (tmp >= 0 ? tmp : 0); + +#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \ + dR = (dR && sR) ? ((dR * sR) + 255) >> 8 : 0; \ + dG = (dG && sG) ? ((dG * sG) + 255) >> 8 : 0; \ + dB = (dB && sB) ? ((dB * sB) + 255) >> 8 : 0; + +#define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \ + if (sR < dR) { \ + dR = sR; \ + } \ + if (sG < dG) { \ + dG = sG; \ + } \ + if (sB < dB) { \ + dB = sB; \ + } + +#define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \ + if (sR > dR) { \ + dR = sR; \ + } \ + if (sG > dG) { \ + dG = sG; \ + } \ + if (sB > dB) { \ + dB = sB; \ + } + +#define BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR + sR; \ + dR = (tmp <= 255 ? tmp : 255); \ + tmp = dG + sG; \ + dG = (tmp <= 255 ? tmp : 255); \ + tmp = dB + sB; \ + dB = (tmp <= 255 ? tmp : 255); \ + tmp = dA + sA; \ + dA = (tmp <= 255 ? tmp : 255); + +#define BLEND_RGBA_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR - sR; \ + dR = (tmp >= 0 ? tmp : 0); \ + tmp = dG - sG; \ + dG = (tmp >= 0 ? tmp : 0); \ + tmp = dB - sB; \ + dB = (tmp >= 0 ? tmp : 0); \ + tmp = dA - sA; \ + dA = (tmp >= 0 ? tmp : 0); + +#define BLEND_RGBA_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \ + dR = (dR && sR) ? ((dR * sR) + 255) >> 8 : 0; \ + dG = (dG && sG) ? ((dG * sG) + 255) >> 8 : 0; \ + dB = (dB && sB) ? ((dB * sB) + 255) >> 8 : 0; \ + dA = (dA && sA) ? ((dA * sA) + 255) >> 8 : 0; + +#define BLEND_RGBA_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \ + if (sR < dR) { \ + dR = sR; \ + } \ + if (sG < dG) { \ + dG = sG; \ + } \ + if (sB < dB) { \ + dB = sB; \ + } \ + if (sA < dA) { \ + dA = sA; \ + } + +#define BLEND_RGBA_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \ + if (sR > dR) { \ + dR = sR; \ + } \ + if (sG > dG) { \ + dG = sG; \ + } \ + if (sB > dB) { \ + dB = sB; \ + } \ + if (sA > dA) { \ + dA = sA; \ + } + +#if 1 +/* Choose an alpha blend equation. If the sign is preserved on a right shift + * then use a specialized, faster, equation. Otherwise a more general form, + * where all additions are done before the shift, is needed. + */ +#if (-1 >> 1) < 0 +#define ALPHA_BLEND_COMP(sC, dC, sA) ((((sC - dC) * sA + sC) >> 8) + dC) +#else +#define ALPHA_BLEND_COMP(sC, dC, sA) (((dC << 8) + (sC - dC) * sA + sC) >> 8) +#endif + +#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + if (dA) { \ + dR = ALPHA_BLEND_COMP(sR, dR, sA); \ + dG = ALPHA_BLEND_COMP(sG, dG, sA); \ + dB = ALPHA_BLEND_COMP(sB, dB, sA); \ + dA = sA + dA - ((sA * dA) / 255); \ + } \ + else { \ + dR = sR; \ + dG = sG; \ + dB = sB; \ + dA = sA; \ + } \ + } while (0) + +#define ALPHA_BLEND_PREMULTIPLIED_COMP(sC, dC, sA) \ + (sC + dC - ((dC + 1) * sA >> 8)) + +#define ALPHA_BLEND_PREMULTIPLIED(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + dR = ALPHA_BLEND_PREMULTIPLIED_COMP(sR, dR, sA); \ + dG = ALPHA_BLEND_PREMULTIPLIED_COMP(sG, dG, sA); \ + dB = ALPHA_BLEND_PREMULTIPLIED_COMP(sB, dB, sA); \ + dA = ALPHA_BLEND_PREMULTIPLIED_COMP(sA, dA, sA); \ + } while (0) +#elif 0 + +#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + if (sA) { \ + if (dA && sA < 255) { \ + int dContrib = dA * (255 - sA) / 255; \ + dA = sA + dA - ((sA * dA) / 255); \ + dR = (dR * dContrib + sR * sA) / dA; \ + dG = (dG * dContrib + sG * sA) / dA; \ + dB = (dB * dContrib + sB * sA) / dA; \ + } \ + else { \ + dR = sR; \ + dG = sG; \ + dB = sB; \ + dA = sA; \ + } \ + } \ + } while (0) +#endif + +int +surface_fill_blend(SDL_Surface *surface, SDL_Rect *rect, Uint32 color, + int blendargs); + +void +surface_respect_clip_rect(SDL_Surface *surface, SDL_Rect *rect); + +int +pygame_AlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, + SDL_Rect *dstrect, int the_args); + +int +pygame_Blit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, + SDL_Rect *dstrect, int the_args); + +int +premul_surf_color_by_alpha(SDL_Surface *src, SDL_Surface *dst); + +int +pg_warn_simd_at_runtime_but_uncompiled(); + +#endif /* SURFACE_H */ diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/LICENCE.txt b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/LICENCE.txt new file mode 100644 index 0000000..0c62fb1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/LICENCE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2012-2021 Ben Croston + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/METADATA b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/METADATA new file mode 100644 index 0000000..9473cd9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/METADATA @@ -0,0 +1,263 @@ +Metadata-Version: 2.1 +Name: RPi.GPIO +Version: 0.7.1 +Summary: A module to control Raspberry Pi GPIO channels +Home-page: http://sourceforge.net/projects/raspberry-gpio-python/ +Author: Ben Croston +Author-email: ben@croston.org +License: MIT +Keywords: Raspberry Pi GPIO +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: POSIX :: Linux +Classifier: License :: OSI Approved :: MIT License +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development +Classifier: Topic :: Home Automation +Classifier: Topic :: System :: Hardware +License-File: LICENCE.txt + +This package provides a Python module to control the GPIO on a Raspberry Pi. + +Note that this module is unsuitable for real-time or timing critical applications. This is because you +can not predict when Python will be busy garbage collecting. It also runs under the Linux kernel which +is not suitable for real time applications - it is multitasking O/S and another process may be given +priority over the CPU, causing jitter in your program. If you are after true real-time performance and +predictability, buy yourself an Arduino http://www.arduino.cc ! + +Note that the current release does not support SPI, I2C, hardware PWM or serial functionality on the RPi yet. +This is planned for the near future - watch this space! One-wire functionality is also planned. + +Although hardware PWM is not available yet, software PWM is available to use on all channels. + +For examples and documentation, visit http://sourceforge.net/p/raspberry-gpio-python/wiki/Home/ + +Change Log +========== + +0.7.1 +------- +- Better RPi board + peri_addr detection (issue 190 / 191) +- Fix PyEval_InitThreads deprecation warning for Python 3.9 (issue 188) +- Fix build using GCC 10 (issue 187) +- Fix docstrings to not include licence +- Remove Debian/Raspbian stretch packaging support +- Use setuptools instead of distutils +- Added detection of Zero 2 W +- Tested and working with Python 2.7, 3.7, 3.8, 3.9, 3.10 + +0.7.0 +----- +- Updated RPI_INFO to include RPi 4B +- Fixed pull up/down for Pi4 (issue 168) +- Fix spelling mistake in docstrings +- Tested and working on Raspbian Buster + Python 3.8.0b2 +- Fix board detection for aarch64 (Issues 161 / 165) +- Fix checking mmap return value in c_gpio.c (issue 166) + +0.6.5 +----- +- Fix exception on re-export of /sys/class/gpio/gpioNN + +0.6.4 +----- +- Event cleanup bug (issue 145) +- Raise exception for duplicate PWM objects (issue 54 - Thijs Schreijer ) +- Fix build warnings (Issue 146 - Dominik George) +- test.py runs unchanged for both python 2+3 +- Soft PWM stops running fix (Issues 94, 111, 154) +- Soft PWM segfault fix (Luke Allen pull request) + +0.6.3 +----- +- Fix code so it builds under PyPy (Gasper Zejn) +- os.system breaks event detection - Matt Kimball (issue 127) + +0.6.2 +----- +- Rewrote Debian packaging mechanism +- RPI_INFO reports Pi 3 +- Changed module layout - moved C components to RPi._GPIO + +0.6.1 +----- +- Update RPI_INFO to detect more board types +- Issue 118 - add_event_detect sometimes gives runtime error with unpriv user +- Issue 120 - setmode() remembers invalid mode + +0.6.0a3 +------- +- Now uses /dev/gpiomem if available to avoid being run as root +- Fix warnings with pull up/down on pins 3/5 +- Correct base address on Pi 2 when devicetree is disabled +- caddr_t error on compile (Issue 109) +- Error on invalid parameters to setup() (issue 93) +- Add timeout parameter to wait_for_edge() (issue 91) + +0.5.11 +------ +- Fix - pins > 26 missing when using BOARD mode +- Add getmode() +- Raise exception when a mix of modes is used +- GPIO.cleanaup() unsets the current pin mode + +0.5.10 +------ +- Issue 95 - support RPi 2 boards +- Introduce RPI_INFO +- Deprecate RPI_REVISION +- Issue 97 - fixed docstring for setup() + +0.5.9 +----- +- Issue 87 - warn about pull up/down on i2c pins +- Issue 86/75 - wait_for_edge() bugfix +- Issue 84 - recognise RPi properly when using a custom kernel +- Issue 90 - cleanup() on a list/tuple of channels + +0.5.8 +----- +- Allow lists/tuples of channels in GPIO.setup() +- GPIO.output() now allows lists/tuples of values +- GPIO.wait_for_edge() bug fixes (issue 78) + +0.5.7 +----- +- Issue 67 - speed up repeated calls to GPIO.wait_for_event() +- Added bouncetime keyword to GPIO.wait_for_event() +- Added extra edge/interrupt unit tests +- GPIO.wait_for_event() can now be mixed with GPIO.add_event_detect() +- Improved cleanups of events +- Issue 69 resolved + +0.5.6 +----- +- Issue 68 - support for RPi Model B+ +- Fix gpio_function() + +0.5.5 +----- +- Issue 52 - 'unallocate' a channel +- Issue 35 - use switchbounce with GPIO.event_detected() +- Refactored events code +- Rewrote tests to use unittest mechanism and new test board with loopbacks +- Fixed adding events after a GPIO.cleanup() +- Issue 64 - misleading /dev/mem permissions error +- Issue 59 - name collision with PWM constant and class + +0.5.4 +----- +- Changed release status (from alpha to full release) +- Warn when GPIO.cleanup() used with nothing to clean up (issue 44) +- Avoid collisions in constants (e.g. HIGH / RISING / PUD_DOWN) +- Accept BOARD numbers in gpio_function (issue 34) +- More return values for gpio_function (INPUT, OUTPUT, SPI, I2C, PWM, SERIAL, UNKNOWN) +- Tidy up docstrings +- Fix /dev/mem access error with gpio_function + +0.5.3a +------ +- Allow pydoc for non-root users (issue 27) +- Fix add_event_detect error when run as daemon (issue 32) +- Simplified exception types +- Changed from distribute to pip + +0.5.2a +------ +- Added software PWM (experimental) +- Added switch bounce handling to event callbacks +- Added channel number parameter to event callbacks (issue 31) +- Internal refactoring and code tidy up + +0.5.1a +------ +- Fixed callbacks for multiple GPIOs (issue 28) + +0.5.0a +------ +- Added new edge detection events (interrupt handling) + - Added add_event_detect() + - Added remove_event_detect() + - Added add_event_callback() + - Added wait_for_edge() +- Removed old experimental event functions + - Removed set_rising_event() + - Removed set_falling_event() + - Removed set_high_event() + - Removed set_low_event() +- Changed event_detected() for new edge detection functionality +- input() now returns 0/LOW == False or 1/HIGH == True (integers) instead of False or True (booleans). +- Fix error on repeated import (issue 3) +- Change SetupException to a RuntimeError so it can be caught on import (issue 25, Chris Hager ) +- Improved docstrings of functions + +0.4.2a +------ +- Fix for installing on Arch Linux (Python 3.3) (issue 20) +- Initial value when setting a channel as an output (issue 19) + +0.4.1a +------ +- Added VERSION +- Permit input() of channels set as outputs (Eric Ptak ) + +0.4.0a +------ +- Added support for Revision 2 boards +- Added RPI_REVISION +- Added cleanup() function and removed automatic reset functionality on program exit +- Added get_function() to read existing GPIO channel functionality (suggestion from Eric Ptak ) +- Added set_rising_event() +- Added set_falling_event() +- Added set_high_event() +- Added set_low_event() +- Added event_detected() +- Added test/test.py +- Converted debian to armhf +- Fixed C function short_wait() (thanks to Thibault Porteboeuf ) + +0.3.1a +------ +- Fixed critical bug with swapped high/low state on outputs +- Added pull-up / pull-down setup functionality for inputs + +0.3.0a +------ +- Rewritten as a C extension +- Now uses /dev/mem and SoC registers instead of /sys/class/gpio +- Faster! +- Make call to GPIO.setmode() mandatory +- Added GPIO.HIGH and GPIO.LOW constants + +0.2.0 +----- +- Changed status from alpha to beta +- Added setmode() to be able to use BCM GPIO 00.nn channel numbers +- Renamed InvalidPinException to InvalidChannelException + +0.1.0 +------ +- Fixed direction bug +- Added MANIFEST.in (to include missing file) +- Changed GPIO channel number to pin number +- Tested and working! + +0.0.3a +------ +- Added GPIO table +- Refactored +- Fixed a few critical bugs +- Still completely untested! + +0.0.2a +------ +- Internal refactoring. Still completely untested! + +0.0.1a +------ +- First version. Completely untested until I can get hold of a Raspberry Pi! + + + diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/RECORD b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/RECORD new file mode 100644 index 0000000..5222715 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/RECORD @@ -0,0 +1,11 @@ +RPi.GPIO-0.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +RPi.GPIO-0.7.1.dist-info/LICENCE.txt,sha256=HM8DmgMIjaQr2yGKRGpWQzC4gexx9wIqn7GTDz-2XYo,1061 +RPi.GPIO-0.7.1.dist-info/METADATA,sha256=gfz7FOe6QRcrTaYh62yL91Po_-aFTe_id4xBy0lowjs,8250 +RPi.GPIO-0.7.1.dist-info/RECORD,, +RPi.GPIO-0.7.1.dist-info/WHEEL,sha256=GMu0CcHnECe7JSPnzBUPyOsrcZoHb7dOBGXgpe8vHSQ,104 +RPi.GPIO-0.7.1.dist-info/top_level.txt,sha256=D2ebmx5QNuKCb-J2LbVMXkkhIVNpXvmxlOVIZjPsALw,4 +RPi/GPIO/__init__.py,sha256=sdM6clNBKNh1SLlx_Ymapx8w8apBzznBSvq8Nv9WGJQ,1222 +RPi/GPIO/__pycache__/__init__.cpython-37.pyc,, +RPi/_GPIO.cpython-37m-arm-linux-gnueabihf.so,sha256=zTt72JfV-vb8B7DxcMdMv864aToVo3qPxlDG9iopXa0,134980 +RPi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +RPi/__pycache__/__init__.cpython-37.pyc,, diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/WHEEL new file mode 100644 index 0000000..a194ea7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.3) +Root-Is-Purelib: false +Tag: cp37-cp37m-linux_armv7l + diff --git a/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/top_level.txt new file mode 100644 index 0000000..196e1e3 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi.GPIO-0.7.1.dist-info/top_level.txt @@ -0,0 +1 @@ +RPi diff --git a/.venv/lib/python3.7/site-packages/RPi/GPIO/__init__.py b/.venv/lib/python3.7/site-packages/RPi/GPIO/__init__.py new file mode 100644 index 0000000..b309025 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/RPi/GPIO/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2012-2021 Ben Croston +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""This package provides a Python module to control the GPIO on a Raspberry Pi""" + +from RPi._GPIO import * + +VERSION = '0.7.1' diff --git a/.venv/lib/python3.7/site-packages/RPi/GPIO/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/RPi/GPIO/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..647949721ddf0df138a1aa6dcf3cfbcf7c079606 GIT binary patch literal 282 zcmXw#!AiqG5QaBtLaWf5z0Wm56Fv1JB7#T}+K`kUa#^<7#Vl^J>+UKfPoyv6L*(ko zSMcO+r33Tx55qSz%>8_Rj$ACt5Be1$^zDmNgwEW#G#5@Nst^rmD1sfLlPaW9iIRAD z+BMvOBJ~S-W}viu=ad;BkoUHc9ki0Z2?ka|Ejz2F0NXHl%-36RT>=F$>cF(_A?H7C z4N8JBxE$iEbd_FjlF2y5n93UC>a56liaj|__YXz6-fljTjvaE8-&JN?l_{>4yfc;v pv3zCbKwCUyp7fwM+0kIkJ8m&fRX@&d{*Sy}xLL+M0Y%{~`~%;~OgsPp literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/RPi/_GPIO.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/RPi/_GPIO.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..3d6ebddebd535e60aebb03e1cc97f3a4f416324c GIT binary patch literal 134980 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 v_2j3~m&{Lj%O5+}xn3LDrf^r=!;pwdW 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 H8HgDGYTh1> literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc b/.venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f85b64b5d798be2f8fb7a49aa7984e6583d58a2 GIT binary patch literal 281 zcmYk!y-EW?5C`!6IQ5X^2?RatuE<@Hgft=|SlC#^?wVoAEO=zUxZNvaVdKk~SGv~9 zSFmzUBRVkipMl|bJDr{~s{Q&6Unt+lQ9DV-o^{6*-{W&pCmZU}hS}j|ww*84!r4{*XVw3WD(r^* S%6jaLzUBnQQOiWmC;SVg_)XUU literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc b/.venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f05dd9ce7a630126acc3d0c8bee4fcb468b1ffa GIT binary patch literal 27407 zcmc(H3w#{MdEedM6Ndu`flpDCbdo5Eq{tH=67?b}k{~J45+RzPUMIf$lvSxxkDZ>(sra=q zm7cOny<{sobTwPRC>X3sOE6Yvi6}sE_$PU9kIra~tZ}U%zE~ zYiVmd)<~*EX{%bJ240AjZdKQ)K|F6md27`=l($aGyB*>6Y6HR>?AuZPHiS2-O$cuS z{o4_<12NaC&4}4774!ZeB_ubQ?mqsN2##NVs7gEN-iukLGD>VEZr&~gAc2L=0(dQcr!M``@84GDBi9rK~%>bMWx(^bL=q46PgLdrWS^*W_aBD4*4+P-Ar`4084JRea* zB3-AaQlROZY8W)JoNek+bw)7Wsm`hqi8-epQ;!SugnCj^Jv9}(l+ZEt1X7jc&C}`` z^{hbeQf2j=KovErssbrxt1*Gb)r6`EG^wUkU7%^zP)&haYDQ^+9ObH6fzGQ7YEGbe zHLuzNy<5H8hZfX=4=t)i^&WZqUiChy!TZ(o@?26c$g`wA;8XiS^`gXFR4=LTlQbVv zA66d`=%ecU)g^&GrarEIK%ke^52{ZH^h4?u^{POhRG(5mEYPRbXVi}fbXi?dKPu4Q zQlC|STc96PKkn!JIrVw<6B73Y^+olQ0{xWwX}^r0v3IGT-566}lK8)a(BDPq=OpxH zgnoWw%-kjBE9&p5uL|_{)i0=D6zFT}AErzsG$=;1t{kr*!3-2L|MW3gxVmiE|t?K|x~ll$yFO9}MnyX-yowk4+die0>Xx4lRG65no& zUBS3^DLM0%Ct^?UL2h@Jae@V7w?pXPgeCsl5c+o^^zTFHcMUXtZRy^*E%v?O_B!GAJsoaeO3&OT z{Jht`2mBq4cR^Fv`588JC-l)Ee z`zE$9p4WDTHg|=t3qs?`(jm}vD5U9N7fr7VO^57*K1~OOrY$~A*Q1mhLYi(ws30^I zgr*0Dikr;HHXbh>MmdMWavqG7(=#(F~^Zu2#X zBhufF_~R+Lb-RplakUNbc4#L@@!Wyy4!}cp{!&g4Ahfe|4EJ57_n+V3bm44vv`=v0qDr^@Mf8J!BL@5OZ= zN_`l5l?A=(;nF*Rf4X$K3;&}b{{6sz0QjeUeA4<=#2vtO5b?vP^P{CR2pz)pAY$HW z-&i`^VCZmwgXa-kNAZ@JL%0Ohg$v>`J_J zPN3s}9uw#UpvMJz2+$J(odooxK&Jpb1>W}RA4X2(<4KfX!t)facL07G&xdh60{9s` zPvaT}{4CPH3-F`Jq3pwF06*u$?*v?FoCC<tTiQfP-B5F39yUz|mYEkL3D9B-baI zE9y-OpOSjtYLmi}50k>DefU|x&j_5ql-J)th%xU1?W1^>aXkmPYO9hhD}u4om_2rR z9PyPa@yUr&?ddVpWm3ga=9Hb9te2+kMyV;dty0TwP0o~NaMvaMbPK6QOAa+NK-Fv6 zX4R=U%KZ``RdR8+OS8C-mCiQ?@f?@935lyAjyX)?3h0{xZ0NH~HfXFNT*oyHn)$AQ zs|k48PF%iVCnx9Z`74%B9qF2xoJqz?GbIhYR>{GA85Q6n`7q;is|r{X#*^5i$h(av zDIW*?Zahi<1mFcc&*Q2AUWD}Y>Cf8lvG-5D7jYMstkV1Nd==LmuK5?@rS~^B1NtN` z=J;;Jyw4`i0@pR7%_htW3vr86N#yst^8P)1-^e4DIlm93Js+0yewDzwV#!`oiK*lX=uv*dcVC?dI9fw8Jt_~_XGZb)L&MB;VO^#uh@yn58(RXm<6m4 z;(8HuzlfNNlQH|na;)q9MZA9r?_WafOL+fMIo3!MF1>^|--qi%po`BBYpBFXY};qzu~>WmV{WZpb8EI! z7;Ean1r4|{UZ^&eU2rEVZb8pBoIwkN&#lU3AAethy8!sReu z6$gqnTxWUwS+UQv8cD~lkLfHTGjO~o7>2mu{r#8o{ z*qZk;<#OF_l*@;Z&LL&7c)RDxq8~d9QnKZ8qcUxm%U-Tro^GnyI^le|JTqIVn>V^Q zD790*rpZKSa65oYvd&r(uBQ<3o%fo*3`rkwT6VQOrkm5{db6TzT@^}z#wRbSJab%# zFT~0|3)+Pv3hVf0br!>+TXAb>C%0Ls6vk#7RfdYg$Q(5UO1Zq<@{)YvB@kRjCn{M{ zSgJOwXHbUWgQeF3?rMgRl0m$2V+&#papRNLLhRZY8YSMo=ah(0!SHEkLEG-EZcrNC z3EPh?RK_4w5>c->E-K&_wj34c=pXllM6Yj zHEM3T{4A*;IS{qAosuAP=6y8~Y*vQyERBB@z(VYD>`H7g;l?QjU^@ohcx-;qO)SJG zlZ@dI3e{*`GUleHa{7Q#jEpk0z^)Y^M*Xs7ZKKPdx4n#GLvUOz6nhzE*BSD9%H=BB z#z9l`A3;QI6vM-Dt($s#QflZWnxm7R<+i*uvYM^C%WDg%8@Ex}=Rmg8k6SFBjrYf` z#31hJczdv`;(|K7J*D$N)P1}$jo!@LExd*O+Cb8|uEmR|aY?IZt!zRwrmNLO9*9!J zEo}Adi?K0`H!AT$4@Mlcy0m>-W$;YB7)!=VX|Srt>pk5(Z>!VN=ZC97UVO5NcsYA< zb7N?b*phYGT7ZTUkGToGZ6TpzQ(0YDh%Y7<66mwZMtTALq?}Z~#H75GGuyJY-ij=w zre5OAQ~SIG#M$SvX_Z8?uDnFUz5pS+fw;m8;Q;y5z~zu{vG_nd2`=NZ+Up{ucO)x1 zrcwfjn3g%QGf&2sII==QEa^V_cDz8DBGDcGOTpLS)deQ@<+!^zU%J9kj2z=7#oY|R z7i0^31J9N$h%|Tup%#G-1T~>qjF*9Qh>Wu52J)8_InDS3vX?qvsn4z$A$mm!iCHeU zk=S7^D2TauKHlEg%_6@P43ywNW>rZfIhvB>_4ys7YS-)Kaz{FYCK4vGVe7b@G;Ud| zzXuY^xGJvjM=9dZ*@jynp(3B05wn~T&DaD@qa&LsuU9&dkDj2(#fdG!9{UHpe8Bv5#3Z$q~~(K(HB*J*&7| z-@$ykMfmmHfqKnxtIg@wp_iB$b56(Fw|Cb<)gU{?1NCOLQg;pk2-09yx(3pR@u5rs zlM&MKS>~k}Hps`Q48q zjr_7cGIU9+Z%=n-WG{n}lp}_h!DuQ#mN9HBFUu%G0V}&j{o||`2cXUR%}}7B30!@Ydjs(zt1ktGU|1W}jOh|CO2J{Gv~UZBD~`d8lP(o4GwG(3 znRL@IxAmwT7FQXyS#jenjt#*+)eqbrf2%B~%vM>i*(k$?V7}C6Hpxo;W^=5xMrFag z>%4X4k=op8OdDq^?u1cEZQcHjTmio$g=xGfwD6{26izCmO&>0BUBGVb$RercIt6ET z)NtD=<|K!66E&wG`VkY=ZED{@FPu4kX5a3;g|S)#D!e2&+I+Ea$}Kn(&DpvtjM`Y2 zO{4JIXx*0FF4RCsure#&E$OgYDcExuYN$D%#|jL}JXUaHKHfe_*fr{N^co_^Ib@ne zLJcEh8H+0;PL@$7`lcGq3k`qT49BZAsI?y_i=E|i#fjld%w0we>TlPt#^H{L3q?3j@*=HaI6i!^^3(?q5K22TdLq_H9p?5sN%uEB8*5h#6pf}^V7Cg^x8OMC*2_L@&D>osGLSwX#lY{06} zY42ZVElF-HZlN*ylI_@d<| z7c4imWa&c-*5x$Tn--QXu?4G~LA>N~03kD~Wc7OFtvQqFlel@S%1e|&FIRKKAk(PY zdMne3l8@EDVJYfz+C8jU0zm5noB!Nj5nUn^r@P`@ss$D&jJmeR< z6GsRU4UVClm@k80Fy~=`g4$Z`&&aULIpnOEH43htwRaY3V`9soi9!V;fC++AOm(U< zZu_$a(>-Aq8ZaRP9|)L+CYpeo1++P41+DEW<_XAm0gG$EPJwenSg1co>?__?*yh+a zr<=R(-m^V?PfHcMx0re|6BUQrjD8q(2{ifDh9fiwQVF5o2C5m2GVL2z6}1j-7vm^w z!ZV{ud3||jHqU0|3jn+M)sRm zN{)j211?~6%30mGM>^ayFP2qnMDSXuqS&Sfaxr_gS<+>m{fzhas z5+XtRIB%TGrBSpn=A8_3gz<7@uG5^==-KBOOOsrLPN7&2Y{#VpR>w)jZkoW%FN>5@u08Fvucsxiz#dOk z3L2Cw*@6zXipfc;{V0l9mGCF<;xAY}n1?KRIaEHP~_@5h=@s@7=Dx~NmxPX?1*kFH#Rt&s8Q zS_2t3WE6(wsM7M1HQv)`is}XBSxu)z`w8G#F{A((^?DG~oOPK&7TV}EwgVh52R*l? zn^oI!yp*mq#%(V>XP$l9j*OY8j2LTV54AuksO8$4d`MnzqFHSdP~>;ZE1fSfj`mk%ug% zvE_l#yt2ofw!AKeuX_dC=UwjPxzmpr&b8%5(SLyeNvzk9&dV@B>Lj-4$F8xbE46xg zx`w@z(TZcY`z4}y`qb&;M;SHb&y?Mr2-$#AK>xYSpPa`f1BN(WUHJ+e^Ju9vN-7 zG&^aMfR}fg)hXNcGtZAm$dn6>+X!dIost2?%bfFpem@3QsY<;$?xl~(vmL}2{rJHE z4?~&l$K_4{_VI)F#mM`0K^p9{uJ!h$-7gXR`U=Nc_@!H(a+O(hi5y8ElOT%p*LKWa85ZcVT8U~x^tLl^;#kHdl{w63p2jxywX6%zQ?Dd{uqo0-iMK24Qq#3;4 z5ll925G`@#8OQ4hpt{!sT+D5{g6SIIWV6_-ZnHc(??RbjQFeo?4=7N~9z(F6_p$=JAfQK}S@vmzAUjoFA7UJA`B%ni zJ@k4d*sxt}H247!Seb@eCT~oxCK0qPm=Dj}?LpJ@prF%3y5dZi_7S&)Qp zMHc=5ZU3H#EHDgx@a!YU*`=jLQQy5@52r#Cw+=d<3qGD}Hb*Al!XmNDI)70JS;n+g z;tbwfV%m*Y>pQbG8t6&1~IbE!%ATe4o6<*tf`{c|EOeh3~PGm{@UBf);VU6RiJ)J zbDYE~13MPpTD~|79f62lkw$wxW7Z(ZA`ftGK0xUeUCGa64Kq0d4}}X&txk_?@5W^j zPr!2Gmwwi+)Tg~oM@Ai2SE??usa226x)VXh>zH&!?0PADMf9~nHpgmQc|`MB&wN%! zZ;*^u#`h9Epdrt|ND%7f6dVL{Cpu_rhAPzwI}*|VSVIi@0rDX85q5Xj*ozi~AC9is zaQNVWSFPKX#%#;$L7(y)zyCy~QJwFE^DVL-V_XY7_STr8RdjxCfCdp$_RRS*Biie` zCeJ{|+UvSTsGv7=#Rj-m6aAK$dCOIq*-?Gk z2j2!iJIUV)OE-aq-;S`9VQa-lCaSn~@hgF0^Dr)l z=B=o@L>rTxx|~)P{E#yOB>-gwN&@N;C1G4rYi%2v*U*NM0gE?2hN zr-sCSSg5Q}rwSa09T;f?cTU@}r?GwLh}}6b3wN-V&2iFsm&KWRud5@%x?v`(t4P{a z*&6z0prK^5Z-~sJDVQ!EbnZ~8adE60_EJKOmy+^5tWc#$FB=H1{uLxMw$9ZZkLUpL zmw|M^f$nNkZ{SBUyuEK#C6pFExVafi7N{Z3`Z{E+xA1m7Z`dD+8G=~qs`kLmK=~tF zvh7NHVA5;YoPKEj;5dL03xp^!cXqYmdOev(hNQdN|FEf{vm+ zj9n7CBZ&Rc7^mST$)X~3%5F&(gA44!=k32Ho!sY$S^6fxU9`}HRcLtL& z$FMcV{i3sGzi2-1iVx92dK%vBdm26x**1f7-G<1yPVOzz60=izO_pfapaG2nJUU)U%q-zKEuV4+tA{SXfY}p>HJp%j(Th zm~9cr)TSky5&`B?%1f?(HpVI{`IP$PMUat?=jYVbDr_xj6|R(w)129qpi3+aNN_^3 zYAZHM2P*13rgQjn!!}%jGIk4VFD)O}#pNv@N+I`bUFowg7>7nU_R=9syaE%$Az{oY zfy?0~8@;h-2NvOIKo_j3^yBc>p26-Z2(^TBaAqi%xsh`-iiX8=57K$5Df*W#YqHmS z4va$=oonesI|GuFvG#TFy{cC*;6?nf0zBCJ6P3oimvrY_aA$>wwr} z_`G^4mc9n>y+pOXoIl=rf72)^$!sCs9VzF&tJa2_`rPgI1&ABn>^b}KSXLWNV(;%{ z+C_H?*@#HenBa1YlpFmJl`Fn`al%WnEwFNh0}eJg&mkawt7v*wY}J-o>sL&e3ri9c z9_&y+N9Jz!g=BD^F=S8x10pPaKkM}XZb7m4GD0j4a+7^1a_exXm@4uLe~6A9#me+{(ca@bN*IMt#+3pUI_aiN zXu2mgAN1FXo-eldy-^ZV!pcMszEPrWC}?Lvl5U3wOHHp*>d`mP;AvC%vscR_6b~?| zGhlK=pqj&zp41v_i7`I9)Zwq$Avz(Qn1=AhL*rR!n5 zTs}s`XFnLp?hG*6)}f=`08|!i;}1ataF6r&*K5qUG-#sFR%)>6p0&rJz?9bdaS}RR zabdP`N*he%a1+*RV)^mjH7hdkdL!w*{_b?&OVxxopYBwyE3a@;H47571e~9++QlMH zT%eM}ZR?q5+R10|EA`JdYN8e6m{g@@V}OTpBr#mqwdz=|LcLgpyPEvGaupIdQbnvx|9qs7XOXDn%f~5B2qGWt{8128z_tL?gnB#AEzKYla-QVy z;*vC+OkFsgL9ent%6E*4dt{8{GhF=9=&yeiXyB_&qJerK2Bd~h4;Ad z?Ss&DmWPjM$+kz~wugmhKfMGyF`)J)6ry+Gh7)?D%i4sUQ*)&HRT4}kp6;bM#~_9a zacP=BbwcVnVul^&C<3584%&B6>82%&=i4TEjt6T##NUQcV$pg}qLKGw_T$h7oJui< z#C^j?vc2UvID|8W=8!VB5Gx(?RdJY>hFJRsa0Z9PYw%jlR0*0K@JX^8T+c`$!o!kps!x8LG_F78aPp7BgO3I z3$f=RnKC*F^Dsn-$mKfZEN5y?>MpeZX{WpBCh~=45Ds*16&cHqngHv(2A6Xe5YRO+ z7x1w073-zg#h9`nY@6xwCr6feNG`i*sT2qi)V#^*Q1}q3E8BZgirIZ$}A=t zJTaT3kF)cfn^svmc}uDuNrkgVlIjz{N=d30!c-|q^$DcHhvJw@|0v*IffLRz&23qT z@gpsZX{1d{+AlKgnb^!1pTHpp?V%&&m*R^VJn@OR#cU(1@{1YOx0n@Lv-*!0vY?w3 zWcBL{nZ?xHPB+6fB=RjhV=eY9rWbnfQMt`H8I@$0!ZXe1rT9z|WmpR->1edK^|$Xj zhb114HtllU`MO;YCWq@e`CLGF^yDr%da}28cM%80VQKHS_^>h7vN05HoR~R7IfFd6 ziE1F`BF?>n!H>&3vik9hu}L29>Oou@4F+jhO2~OXj(sN;$BfwJ46(3qw-%AZWvDw18>^)rYZ`kx#J%TtMVsQ6_oJBZj`7g*Q3>@^Z2Z&iCtucagJzlIsZ& zV7Jb-x8Powp2cx?obX|%E#ONGl|n$I4X>XqxLp;cy|var$E&FV^lxrz7BG*?xqevr zo2K2iZTI52*W-olSufFQw#@Jc)+nspg)zbcJCg@G{~CWvGRH_5&y;91|#lyhKr=YjAW-ScJNC zSA1<|J#Q!u%2fXSUFRba{G--Yy3I5+hqO!TNS1`ci? z@Eq0L)`bMpZ&^&TM>6&0gvqCde#l-na{|K!`d}H%GFoQJ^cpd=b9VvGQ7!Zto0jei zy3%Ulv}+lh%9sG0G5lCB3%#^9-mr1D(j-yl&@HEgWgPO>lnsiXr9MP%Nxw_vpo`Ev zpS1?SwJi_>{r%u^sEq(qI3-*%tCUHeoMb(qe|!YTf3a$W3iM&N%tv_pC~k;wS)B~F zpIkUFN~SBYmeZMH<(y$sC#}TqN_>pe;F4cJ4YfNt-S!YBqZi|2poC|)6^_eb#KWCh z9XG;iu`8r7)xI^{?Bh`8A10(8SE$JGL^)kptor51BM=m4CxXGYWVEiVdRTLiifgT!{@2*-?DP43SNf$9rb9%kV zjdxpdB#R*T^cbzg%wW+PJs{W9tO{N;J7V zY#lu52;X*m$A$)651!}pp$dZvl~1g=-0kslJVayS#n|Wd`?$(Sw!Drz$3ZwMiRjxrBy|8E5x$oV^T{PRZ9p1x^^)#nC#&^evQW8WO3?E z?mEggnheNxWlG!Ftdwu1U~cFBnwOL#3onw{oQ*{rkf}_cVUSxAvLVhKrF%&Kqda;& z(kaiw!2&Zr3xo5bl!+)z`C$W^v*sUS5o{@L0a9a<9wd`J=RD4OJen!H&npKWe*y^v zLh_azef>frL^%4oa%hFJVdeYukAsHSQ?u^au6wluctwvK0%^{@xQSK@jn$lxl@LCb zgB7Jryc>+{I@Hmi+B&bDpUE%R^0kk;yLX*x~Hh5$wW`Vzmaj=T4V@zV8Gi zEzqTd)!wecbG~l%Tw&Ltf-zvqk-z7l89pcLuR;M>3=zXbOME21eUbbE%xGR>jf&)E z!jfO)ReK{3s>1BZGdBDp6KF5oeyejkM+(Y{*Bhyo*F$f7si3A7t>4ERyEb~YSoO{` zg37csqPdwCvm3H;ZgP8`Eynm*FV#J2)cOlZwR&5P`E9j?r5;uZu#li#VEjTqL;Ik` zcA&+uUhrEit=R)(ZU%3T;Y~JtBlvD+46W>px;l}y=aPE2j{9Si9tXHUs(d+YeIX?81NHpBx%Ikz+U}%1iiG$S(^1tTQujl zD1`52Hm8_G@_95TySljs;`*nq+N@n&a041jjGNNw&@8fWL|43O7yO0phN2rxD4pMZ zgN1!@m3|j=Q*%J|P5NG^C8YDd-PQ{FoivF4Nj8$S)OX+0di{1GGrkb*XB>T#mi}or z2rl{Y2^_P+*bBhL$Bb~w9s1o=MsLB1cj(cR3FEp02&)2oW`(LGn#f-xq$+7-Bm6t! zPo$lBR=za|6BU+>PN5vED$8ZDD`5WOXPEp`&kpvM`H_rZz${9Zk45A5!AB@OUq68X z%Wvp&^buifqsXTV-Y*gqZ`nrZ3LW4cP55d9UJO;AIcg zE7PN@a_H9}7JrV6W9?ln`MTq(6^VG?_~|fjd=c3j#UuAPKfxs?2jg+~Gko>4ruf~2 zMY9dnTkpCzDC=vW$oOkzIb|eajG+Nm{~YoWFD*=BP+Yh%g74T^`g6>m8o*WIPszum z_?5x2S$vZaYPhB{DeFT03?MHHUuaPnjSWE7A3(3bRlEtwC0m09N?E_m0;TdCQoSU; z+;*3-yyPJhkU*I^9UPFw>5e`gq8higiIXAPSHt}nc6+Q=c%sCN&Y9`ToKtJVqv`aK zCr3_|j%$}FNgjAD^@xHiel^DCh0Qh>E2e3jFu_8{b+}IO(&i%q^2tdrfkP@@-=m;^ ztlqp}>_Yv<`4ML+inI8DsHUk^zWHcAJj8G5>8-3>&bX{ffx8*Y@BPTxY}3#;k{3J& zZN5x(2O;rI6t6tdLXR@;TfE81o*TMO7>S2o^fOxe4}j@~NMZzBiS#E#Dg-(CuB0o` z){=2IbI;b=-zmqHbn|Z{qD1Cd!G!lDK^ZF#Z3qPt)Z9nDc`?E7Wgb z^mp+k3{ZU^KrOC3uKK)Pm$Ta&m%>H8QwNW>h!_5cGGJ#NnFKKsDsKbuxXEtasCV= zC=9)@i}`;v;wEXo8w8Y=Kg3w(`)JhuiJeOfBx&Uvu=*2Oe6=MV@3)ePEWZ3OaLvH_ z!8HTd4xGv+1~ODE`Nyxi1kVi!nUy71mnNQNZw;2~_)236oCGc0*!UZ~o&!Aq literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc b/.venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08c69f4d827d44dcfffec1c1fafd4643619ae674 GIT binary patch literal 94035 zcmeFa3wT_|dEdP^01FTVFQO<)rlmC{i-1HzSIagn$s|Eik|jZm2wl7~yL1J9m4J7>JujuuA1Kt{M&|B*bdF#CO-Ue@@cZs*jyVTq4UFL1^F88kRUgmA} zUhZA#UFDU$S9sgJtG#QyS9;fa+r43L#JkSB-rM2r^hUiKyc@lnyqmpSyj#6jdAE75 z_Fm(?*4yR1&b!^a!@JXay|>%j_H-Z`^ypJLr9v z_n>#koA4g;9`+vb9`)YnmA%KjH+hG>H+vQDh*$NFdXt{#`QDT_?H%)K-pq8Zyv93T z9`x6ihwjRFv)8V`#3j1}2U*FBImsw43wVM8t5qaBe|J>H{)@-J}4amR8dpnT7-Cuh) zUw%2i&w4q2=lqv@=bp-!w^GuT-^uT*DED1Y70M<56@I_hb2j&ME*Q5u zvfdN#$X%ZCo}@0N_0Mc8Z>yJh``zAqc>6tmDSY>8|7x(|z1~y6w=IS*7rdQ!t|?zr zFM99ucF<4Pc;D;Y%=arT&(l`!kCW%x^0oDS-uHRm&$I2`4|wnAdzgBD(E9-Oe1IGy zVNKVO`a|9illsGP?brL)dp|_PExDeS@4r(I$9p(dPDh!`VK#P z{zgB4{w6;=bEALrg&aM8i}$16tEqLT_d)M^zDK=hykWj?;GJ8`w{m?|`BhwRE8oWT z)#X=neNFi_Twhy$E!SP;U0h#RejV4_%eNZ@TMYvB@g3zm>Khr|JE`#we~W+lRPI8q zd2y_nh}*-j91f;r%1;W8OdZe$sp1`zPMVy`S>+kpesrNJ9&w4-S{k-?7W4#Y#!so)^LU6mk|NH^(7cOM88GGx~minNje#TPo z^7o(3miK#~^*%>0-R=FN_e*@=1D@aQectiS*pYGAn9 zzxQk&2p_Suf9}14v{!^_k6PNl@JghW!n8M9+V6Q+k#<#>R<^X?_qLI?ElhjN(*C7) zC23ds_xe{{p0Rq~Wa)q4T|@dcsr19%AA0|acD>o!^hb_(!VWKQfgo*Xq4|XUjG3 z-+H$KYt?dXw_IN&*Gzea@%eLaJI`k9**<&r7d$&&K3?DCeZ~7K&t}1~H+X;H-2{#u zw|uW8Utb`)J6E3LS})h@*U*B0@BJk$_)AhE>QX25Yu+nKkzYlBiMhJS@BiiX^Sj@E zzs1VwvvNMcv;Xb&@vJYb<&4eMzYo*C+dp--P(EXC6!b>(&w1njFvgj48D0JFriQly z$J_Xo<->Xhj(t!3Mt?BG)3=wk7QMCn*7|+R`m8^=*)Q=XJdM5k_Bv}1zYBbNtd<@> zTItUEXDz+gdi3p9%WmN6HyUxSd~U_^zu(I5^LAVL=fd)fluxhd8kheL{~g|LQUvpHPlh?xd3!C#la@m>Z6J7<9Pci_o9lbZ@2MYK){g_h6V}f4-adQx z-S%sPx8Hufr+%BYW+M<@Vy(F(ZuNWp_j>zC-(;r(sm9_}`mpR(Gt4h;lf z1%mgL-$(joe71ne-&_BgWzeh%-eC1zPM#~QzANJTp0+11^8H}>2g&!O|0FrKTfSlMTJrs1+^>VdjpX}4`2+Q1VA#L2|1Xn!1PCV45buXV+@wtuF=f_C@@$ygjcX=Np<<;JWV_NqYz6%oa*|s?|1nQ?@p&EC{geKi{hxFzDJi#mFFTi|oab!hei{gd zf?m?^C_nH26aP8CIP-Bq8~nZhy#HL~r|Lz0&wQftQ?w*IlkqO)=}>T`?q@z({$%}T zgXd1~QZVmQc&(oX%RcFU^87#bf5tdH-TiEQ_j7jl3cu*xVC8t!_w(hSuMYsh>%AL* z_U8>Q$tOd`|9`6dsrq`WV>i8$@or;<_>}eP>#YRw|G!ZFh5A-X*uw|9Q+Bgq%zHig z$yNRZ%YTdI|1$YMQ~nIs&z3*S3b@w)A>P_&IKAJy1$_7nY5g;w^UoVDx+e#`8+r0s z(tol1i(G%H{7YOvU;aGTA1(hV*IzFGGS@GZzrgiZ%D=+(pOya^*Uyzd$Msjszshx@ zJi+zX%D=|-*UP`o^*74D!Sy%GzsdEBW$`J$RsJomzg_-quD?_M9j?Dy{#~yBy!_9( z{)_Uz;QD*z-{boG<=^Lep)73tm*s!S^$*H_!1WKyf5`P;mH!pjKPvwb*FP@*G1nh1 z+w3cA{{2b$Pq?~4`qh$%VsiPlNw;Wo!?VG-7b#JR-4U-t3i9s zSff5!ZTWRR?Vba*dUdwF_P$!n52~|=T0yNo-R?hF4XSg8=Kaa`+W2-)Fx_mgi+|pG zvZ{o_A%AwNU6?pM@3;GORTYEb&BVg|tl#c^s6JnvJl^i#bFx}%RgaRic2DzkeexdF z*=hvopL*Iq)(9F4tytnntlFMbz!!(uQu6g4~$pme9ytU=7GTT1K+a;{c480 zU2|w*e!da3ntP5m+iRmAdr!A~`Xu@})|jKcr;_IfW*gO3^7Ed$$J4l|d+MoY4+5Y^ z7uD;H76aq82N^CuXjSU|YW#{HA(-gYr+hPw-D z9%%=|s@iJ;nhzM(?!JIQtj+oD4dG2?@|Zt)+%T#z0YbEG#P-bAstl4!w_B^mp4_!i z4d{%CHy+$y8M}M`*uD3R-_`CJw;nEzHy-p`3qieId=MO|fduU}3bdk`Kq(C2Fk!#V|Lb`Y}Fcdp>n+iQZj@EhinHL0W-&Y(4T7e z9|#(YeqH7DCn(-$x3$T3@$PE#n3b5L{C;N3T=U_Yf3jV)iKCg~?lgsp_xh*Z)53kV zCLPT*nAcoh6W-XHJ@;2zlgHXa_b=EyjPk4te;?B1s89OsfjFVnEa zzO3VC#q%c{Mj<99MarVT95=i9G&gbaGtyv|b4Y0L{Ae-rhcY9Dc7NrN53s@(uy(#bn%tY2@^#AcXMNm54Vp}v($z-+8k-mAI=e7G`xnSgD*?sLr}4K_h}KfikEo?KqeB@Uc3IS^GViCqaKbeERuV z2mBg0OS$I8R%R*lLAv7E+}Z5gvrD;F_INSa+sZAWFFczIu3O5?(GeEX2Z&SYCX=mwEUma_UyN@1zs^&Kw+AJDr?g)N!m zJ;4XO;-O3n3DL?c1V8Q#)N|e%;2Sh3*DmF`A6m+NF!O9t@GAevy2W>oi4c^)7ARhe zZwN&RDp;D=Lgs_C%~E5kR4q+wC8EiFpohTe~*a&_ORG_H~wy2Ke+PTpi+u8Xp zMEJ(Q?X!@9Nmisg&#PQj(wkY_=168G?1$0YXB(5%+2)aeU%}(L#FNR;^c(%R3xHGe!JQX)YQPmTi?3J} zxF~m^`8&Q?m}oRg<-%OGe!85W@=q?VPY<-leX;*_B}g?hrnIG#_XnSAsc)T&qs1!%k%X$ z*>&R4P|G!e$M`fibJ3J+WoL4&{7ivQ&s6?w&W%NHaEj;cUPqkTYb$p-tal4zuMym4 zd$1$5-zc<}N)RmD>Tb(bmFBU=!mL+e{ny%7nF<ivbk*VZoV1*xAXNi z5uA=jD3>*2BRAE$H*4>4Vq8Yh{LI6bFJ;^8j6YA=(Im{(u zs|@ADS{2KAyO(;jST4MaC9B*6!u2p!V21DakwBtJpl_9?kC8kmRfb8hzQttFvfav^ z&799KfxeUg2X-6%1s|2>nkbWXR^m|Us9#!WLcCAbTE|#iqg7^jWTarN2o|ZQ-P2rP z5pQp(RH6)y{8ni9oHFDaM`zSmEWIWwRZ@uZtTG5%&E1R<<;5$acEO%?6&d5KsB+X= z8@RBggW@e&B{S!97er!c~*FKo>R5N@gK&EuZvfXW=+w8XDDQ)qIfbf5OM8c`-ZK6DVb6L@Dtk zLKH6>B8bta6oR-hs$v+)NTUErbyTTVM?{cx z;Ht#V@Ph=hKrb*u`J6n#BL*+&s!O9%!CXvh(;jR84=1;3<4(z47q;5EfDK92krkyE=q>3aH^xFJ*`qG;qI`eyS3Mt%FekUaReeAlV2+$)xsE0quGcXNTzuWmz8GZ zOn!+4W-0q2mZkTFGxLhhdFcA3Rg+dBJ^KRTFZ>khij$QJNc~p*E|_wm_qeHwA}mWV z`T}|W6Q3BPi`m6B>g=ePZd_IcUSks6)vLjIT~@|o&B?Fwaadd|WHs?Y0H-DCz-DFL zt*jT3CO231#}ZzM#4LbwarZ`KU`*wRZS%5l7n#e#slRdg)CZm(lk>v)p0vXWa+>Y` zL!}8kgvF~?h9E6Dc2E3Og~T7H#Qz?ZjgY9{22apvw7#Yaqotyc`<~zoP^H{IoKhs2?(WA*$ZL>p_yA@;wSxi=2QbKYpGg-_)jzY zHD5--KXHidH7N~3@DrpM&j=2Rjs|a2mICU{xvnneJy`RWo>VG1MleLfUfA-*%}E>R z;y4@fd3P^=T$RK~=6ZG|#V#!K2$2j@p`+kg-%Lx=pil2{+f3Nk8x3 z^JwMJJ>~toN;b%)J4&y;@x~ih12FwY>H0fLHB>Kf=A@yGjnAo(d~!1j9*{BQLg2)$=Vh zcj6d&Xs1eu76aEs!WdQ(RvwfP=wxAfS~b5p$_&m!96M-|gs(9^#?qZ05LK$kKVeG& z=A@OI${imFwmF{z=WVcL6s!7opsDFWVhx;lv6vC-K+{I&>Sb$VJS2I-Fg6!yc_89m-PEu7<{((q!Pn#y0A^N>j5k5!4a* z$&F&MRGn);uM+(k@`)*@HdVqbX)RRny}&93xcEl6y!Y`lc$y1MeVZQjT0zZ~bc*fE zDq-c7Sy#DJPc`?c#|C*jlS7{7e<(MU4St^A@z6l+tiLAtZkD*5y2AQu;~97qdW(LT za{A8RM{u83pNwme#D*|%KgSy@g0u+@2nLS|q|Nat0&HCHXmm2b68r++sy6-;EW7!b z+?)tkk#R%LNw{cB^6m|OhJ3Nmts*t>Ht0eX0j^Ff1*-3q+ZdiP_IZo3KRCSm2d=hO!?!n6XM6XzL6g-TiT@DQ&SxV%dS#D z$9t^Zk4%Qmt+OFc4?`5BHy1)YH078Hk*jGS{K5Rwd+!70peDPDf7^8{W z5u?dwemJIJDO*4$tcXF#8HVS^gIDpCnJ1RIT#(=uJf{?=PO(x`Z4!mj)UDNPtxDz1 zQJXTTu@)~)1H=HjJTXYpxfJ;r=1LfeF?an^c1pG*X-V~MSnDwO^q|v>p2@?{Y=WQZ zg_mKj>mOd`(ML0_z9mqAEBe#pncx|SVByq`r5w7~YtHm6^?>ue!I7oH`QlQKm%SWH zoXsrd&-X9&7&$!h2)}~&w+2)SDy!^L!C+W}h{CL*r|BYL-^ifT5sFY5U1=9&OmP$C zGfI?xDmbHyC|bKW@aN!sbpV1Znh@%dynHOP0jLR8P9m3Pn8qhT0!Ct z%tF|lZ=ic(Su*O3f=HG=cONbt$eQv2APvHI(SqTADHb;TaU2)CWTCqlcN#&J`bI^& zD_S%kyHzsEtqD7o$`{>EP^ng*NNPfVh7w=eAWs|<+Ntdnxn1%@N0X#{Yh1KJ6zsa< zR^!O)jgrxDmzd)5B1lr-A=P;dUhr^=$xpNFz}+p?Tnrl1XW2+$wVgVxyLc#L#8)Go zt=Q>ja>6~EzI=X zE{Q6lK=5ZF1;W$2)h8-ZeI9zdFLGrt#z}IITz9~jDKwuV0nHm?{bUUMJtn)i7LJyt zYP0^1()?_7l5s!Dm|%}?(34F)M7j_~RUuZoFtV9e8$@+DWkAq4iAA(Jc`PMvnL2fM z1lH(k3V}FB45B2Ph1S$-hOOIonb4F-PaTrd3%`6+{#5q1-R*jbuS1QxUyk9luBboes&X z@yv--69LR=4U>R}fEWvT3(^>BFyoGw(^_2A@JL)tA_0nx(Ud`vU2OM}UjirQy67!@ zd8W0%pH8eSdS$ZV$x~-&vVrgjEuO`cQEvpFfQ+=)B`StrktHE03DdieA89%TZGvOMnta7HqKbH@8MvD>`j(eYUvRUf zBkDOScE0C=vmNIaZ*wkiX4){SA~8CoRj%8w6V%sXEn(s`LwB*!;5PsP&gD1xa((he z-37Y*3YT`TQHLhXjL8A*^%N26m5((V$B~nwLQJDXAzz>nGu1G8Vvo>@W|N@5 ziYbFeMxF`oVdPj^k+Pr37kZFrK`!@HrW?U@nJ&O@sD%VknF|_JNjvx*RJp~x*$RA| zQB7zw5mhd9Y8KfmvJ5-GVwN_lLGw(#D`p_n8l)sl*)3w*#SA}MnX}TTycro2*F!I> z?Xd_I_c6tCGdVAZSaI!%&2r`N^0f@CLmu5rZlm>Tdm_-S3%xI#)x`AH1nG z;F;t`zBOlZC$6DO^`scImhfDxd#yo}Dtq{*t|v1~J-C@zrvwhB&5{Y$4bs$u)@gy-0F8-Ul z&DStqb)07dl<8pT@*IiB(bTF`j1R9&fScxven0CGnat1{^5a?^jh@K*Y_SgT6g-z6 zYQTqzI3a~OS1!C)7dMTVr-3|Vq;FuUW-z{yee4_A!z1egO@8wivLSIAigQXchq|xm zE}l@3}X1en(@3kSP{t395rPp|pIt#ecWQ$s(Z-h*1e=%5h#GCJIKD=4Q)-(?DjF zJ9)}MM3jS7#9lUn(P*Hw53_+!UadJ9KsK~l2ue!*ypH zr4Hlkf2-eYD#!D=y|n_EjgzqHlgDXoGhFsvw~R*z?M>wQECAJwG`=3<4d50c^^5`0o< zn|VNf36uH}{Rzt5e42Z?MA~2>Hu_)oK1AjLty1WNiOa%wuVSpd|5?1?$Yfbmjt!c5_E-%@Rfkz6ZVhQqKo-ZX3dh z9oV1N&J4}0ld@Iji79v{^GPaH}YFPx0?Pr%2r;UgdHYZc^5{6wbG z({c{S=JEMNW~Rq&+~7%{O@y9t!|wxeRe)(I)3rp)AoGOK2UfUyiO#i)kqltcW3*WR zXNqEWi!pUQqP4>o#_v&Qs3sQbk?y8D!@>&7G+eRL+>vFLTInr#40tA&&g@1Yb3ht9K2#fF~)aOR?yH1Z&OQV zSb9i{6H_S~ikVj7Y^FIQL#)~HUeoFgIoixjU-MzOVkVQsh}HmH?ZZ4}Dq*Qm3B4Lj z-X%7ZrLCD6OzIdZhC{cwt%GK>V&k(i2h$^0kE$co!Jn$Rw?|EDI@Om{X>;aKiC2eh z2bA~3_7<*2wo#H*B3TRqxz;Y;ch9Oz6;#wsUaC!8eRoIlt5I(AV2@|=$XZ7RL}n$~ zMU`1rL{A%D(RauB7;mHDb$pQ~Ez+}$_XM zV9VXDJ`Xz;SdhvWlw~kJH6e_FI3GBZJH5Wue;$KBdkk`BLE8*dv<3^>dmTe`P&PC) z*h_g&j@w6DgQ^Mn$>wly^kC-1QB2{KYI03)h)@3j13i%*Y3IyrW1CE88)X~dKcoNJ zeJsRs>agvpl3Xj!$=0~EU=2fv;aWr7E=GJzAac{rqonE{@n?DPj7Iz#ZZdgBoG~9l zCj}##AIcVNytR?1nB78JA-8(C#l39U@MyBBdI=VKYO!p=ZIT zfzcMT;4gJ&!>?7Qy(Xo6beQs}GH96&l|O+|JIw+U?1I16UD9{fZ9{b1Z>ifPd}r{X z5%Lcrm2roLnrR`)EGG#qP~J&pi~jQAO;d;-v8_Hk*Jc!GFbj*CEBAT%a?unoa%U)( z`)!ZO0FCZ-2rYmn5_UsnihLSp^JZ?Omz$ASG2ZK#@=+R{4`sgQ&8>oCj!6yq7?d(B zn97CzZ7*&DnM#pgy+N64e`{c-AHr9LKh0G7jo*ogT#WicSOFoKIVJKlQ=ysNBEOi; zkh^JTk9K#iMEBN5G_-w2BIX(EYE(V-fhd|W?=XDn&Wdw`ire6Ga0z(8y8iIoUb1S3ZUh+gJ z2KPSpt7Y;`q*=0D3vdX$9UMz84h5jw~`;4-8xN0i# z&;oL})u%nrXba~N`B5|>@F&ceTST1}%9b+isWxLgVs>M?&bI$p5uie`kKxh2fD@p+ z&z+1_8V*bG7ABAHbZJ;yr%(j0u$NG!=+E`U*vbuhiEVd_SLw#Yvgqn?{=ZT(44>NN zhRaOJt9E2q(5X@D_>tx1Sy^N3QIj+6L7emH+hu*&`Pw1hFCE-}u=J{1Z?!)0kREHZ zE1^%P<+!8YcZcGvZBMk21f$E@Xxt?_Uc#J*av06)PE@JSmNs^E$=QypbSh#zC81O;RS zX~KfbN`6kFg*1#iG^3${B?|-44}8q`DR=trNCTNpuK#{O;|L z&KH<%FZWDH*PAqcMIF=Yy1rTA*h z-6v*XoeCIc_m_pdTm)$pdHD z%AH>u3F#w)EW28fQT=#4WnQMj?23smmlRBz#U4hduN}KF< zT7lE(08h-9@jhwrH0;>!y1>h)3=o4|FeYodbEFr9Hzg37k7e*rNnG69*^d!6M#dv; zTt`0*eNbN}wi4Fgc&HW&au-`1jZb znPDuDj^T=&RDs2AKC5d4GJ@e<`Z0EW9t?T7g&xn?3sLhF#LrWqM$C!R76fw zC-lnrU|eb`L^P%XY+5zD8}-BKa{hKd`sGAoCq;R%aWXvr9ZF z?oCkcn_|C1lbd13LEv$Ax64(V;fX9&PFuW1X@8=ht8(5>LlJyLnLf&;-Qz1_NjKc$ zi+2m|E##5GU-Wf%K>L1}6jqC;yQ8y2g7@Kq(g7{>g6GE^oX z6iddIOK|KRx*{G)+F-aj#&>fU7brSw0UH-KF z9<0__aJ6Wg`7dT+YIvB=&(GFis37}96GCY^AKJJaP$_=L_S>1^%6zLj*s&BdZH!lk zJzr(R2gS9rZEa^`YRY1Jq$Gd29l?sj>eCT-hoQw1r#C~$1B<&?P`ZZQ;kMu=?dfcZ z4{s;q$^@!*X&p?NqM$&L9O@P*n;E8>uu0J-Cj`)lV%MC!okwpJZcC=i^lz5pO+Ik? z75x>s+0CaTWJM&?`52#kNEH?@DHK@rIm5tqNCa2&&f@T%dI=ki(`VCZ7((f1SmS7) zqBbhvD>WLC=}SPZ4y+aCj;VUVVbm-;9%VLjUuTo#qhlq0x0)pamdPz%5=9TZr`|GQ zpBl#rK++{2KSyRaEzP(z6v66r@WCcP2}-&oRVL(3%{{F;WpXZJHZSm*?MJXIkV%x--o4f*l&Xg1&3_Sa$7*UAZ6C+PD9M z^kYf=xZ{QUQ4uf*$n)*&Nt_7dQlC!s<;$YJ9CLNjn{mDu*`Iyk3&Az3^{CqYo_~-Y zy-Gd$A~4fD&A*-fDeap4*ejJEN%dxonS1q&z6|rc$e!%6?7_9G^`lz*{ukGe*N`=> z{_@em`siOFld|-RO!kHQ3%8LqqG#VS@uOd)TL5=2tkf^}=$R2f%QMb0(nSJ|DKWE; zCaWWP!>e_OKz~;CNGgToeY*&rl;4Y$c&&Zm84IDth0k#qieO_NTm*xGudU&&7wVBD zu%y;vk#3g7Z@JG|aIAjqKv}ln>^UktwC67l3xf{;Rxq+!m#b@jEXF~C+%4;L$+Nrp zn44D`2c?45a?Mcza#ATgle1uvn6q(H(I%SyKxn&IeF+^;2w}F}ep6lVw)N%OefU33 zGfHkCY{3Q!ebWc4to-5b$m=?LNm7RN?jcY=pBj&tGFS*;MkLI`4r2$$GP_qNFJMcT zn+-NT*LT*OZ~^MUPb?cBwM2hv6%U z5_1sR$2~fA+=Fl>k~cBA8ml#)s}D z<-+{wdA3TpZSL=(8n#VnqXk?t{@gfh%j20HdTjfUBfHI-f#C1R*dFTKgX8>e262Ox zN)$pg)o2eob!^B%eTugn#rZ$>{=z&#mHo;|;@%NqBiKnlh1(a(MI3qD&V?rhQ?|V( z1&3q6Y`lAF#3>0rr!F5NV30S(_5l} z1u-naD%rGBF`reP8lX&ea7`eQDD1_rttGA9>m2;b{jrUAQhB34jqYwfri6&6X`iRa zUf4_gf@~#l)OeQpy(|{usf&cWlmHaFC{Ijkw(C!7PX!WEvCXdo%c<+kM{L`f9wa^H zI3Z{IgI@f_oOTeWZs%@yg5CDgKTvJxa*a{+ZslTAa4$#D6wdUb50i&k-%>Ab;MpI> z@Oq)}q`ZQ&mHsEPGXt$YeAZ6c?}65uCpgLjx$+6ZEoLi&wagi|2;33z`#eRPsX@>iE@%*|Ac=w};EY>&MoWK;+nciB@et>?v4y63w`p$2_(`{o^ zzI^+a`s1`UIPO@0$EATdZ7@nZ@#i?J>;0nMI`zH?ioB!{%rFZFe*vAwl z!Y|>tZu&W*y|5J}l+B&DT}m1*@n;gTo1RkIY1$)6pFD;|Ax1Slh$Kwk+Yzr1dLOgW z^32X1!$mL~byb|Kp6+-rDLiy$LLj$TZ|p895xBlpJth0hTobE<++&YA*J~~3Y?4QY z#JrI#=7Qu<=oc&dnt9tpda#g~vwl)r$P0vVYt=i@D(rAFi>Q?7Z}Dy*p*G45w}*9NEFGIuWPueNqe}JxuuZS@*%)K66%rjGEWhu@&_#X@(3~Hg4;w& z^NFtAEZ8Jyhe11AZ|7R`^o8`f?LIVR$@VtUYJxH=K|;};d3xJ=q&K&C-3#_e{8~p7 z#M)XD#Ccg0Hb+e$xEf8kzz#nLe6*0*h&@mC5a!@D8pqeFRiPR>;TK*gB2K5pIR>oKBUd_4=vS*AtKBp}ru;EI=mmgbo7PnIxNq_B z+6C)0=2xaTfYD$O6Tv{PP}qzqLBSvN(as9kb8}@I$PL1cD18(ETln6H{@C_fm_N^e zyj%H*b6HPLZN$_syj|nzcz7gY3abuF7j zGUof~T+FPdXJDk$p*^oq3QtUpx3f8}HiZoq|<7h@2w%@NX?NzsL!E#cd*^FP=t zZSh}4H?{LcQ7|k70|@{f7lEHhgAlpe%w;hFqPQd$tAcGZO>Oi-d(eVTgxre*#K=ip z4BepFc?UeEr#7 zati8n@TlT!<0>QM$y>Ic+PsH6v2HfHKD}ycB4!(esM{|+rvb0Xf~*zN;s_UE*e-6;!MhUYVT<| z^5|qH+RP-=bcvZb=T~H!vlN>6L)_)x+L=Q6~2sCQj;lemF zTGDH+)7{NkWd`7Cq!;cuz^1>IB0OGvI>bPQA`NFWIh9~F8u%37E_0is9z?yi-Mqf* zh{jxv;CckU++zq87aGwe+GsYq__PbUAX-qXIH_1jKJcFwNH$X3MA-s`P!^wo%HlGW zXf4LOYMM~m7^mC|RHA3eFd<;f!Mr&c$+)rD84J2c-ndNHwMQG?Y58bGn42O=6BPVl z$YR>cKc1Yw8J?hKvEUH&sAR-z4 zevyc}D3AHmbhC$+Cs**&`9ACUygwh=K8iciKYK3%IB6m$S z6k6!ddd=-g(5uB^IXdc{BMP2+B*L!cIlqxTvbYwKpOB2jUTDRckt2)GXc14&E;Br^ z6_-wAJ1S(MancFg;U@H3MsIo*$O&zA3WgMM2(=5gl-@{iAHfT{SgUA(Z7S80kB_Q} z^@Lcmmexz=xRqiFh?q1wJz8pKM}v>SP>EZEL)HG$$NkyG-EligEt?BI;TGT&98)1o z10zmyc1Ap#-~tFNWC$q1eeoxR`z}!WPRZw9O3{$?lABp!sHe_uVy-3q!J-v)nTs`N zd&86GERh;{?Y-3$&>V8{!&qi5AoH92p4SLQ=a( zr1v_#%ejEMYj4~ao=#93eHJltLvJ)*jb+}`$yhnCEaVD5D>(}5}#AMG}s-?$!eM>}{n_H4x8 zN{4TlrJSt|^0Si2Q)Hi)a&>U?F#S%%*~X2wIwIucf-Ul3VP`=x*rE+m+C0T(KJG^H zRqe(Zv-7It9|9SR7kpv+IzciLL8dQLk`=rKhlz`v#y9FE?ywI_bfM&JNjP)x)>NB>!h zxsR~ZR>$=1+jq~{gxwuN$dR6+dlYZwwWl?T5_mF$Iz*{M1mzVsKIB2mBU!7efIfR1 zqc_aDAz~(!i-PHmkOIrBWJmEBmT(<*{>;jpTDBgMMzXt*5-!j>hD>hqRnuLXIAXOL zf)C^Qp7J^Jq2c6&^4Mu(phidinx-KPj)^g+BH-v=w&V~$jiRzOtQlm3oy22{yIy0f zKd7A!nN));zYUj-RwG$TUDlN{!^~Ocbnm$aBv`vA7CvYZJ?XTZj*AFS8wxoL9RhN! zTAzmai8|Td?UQ&`#ZX6T0?qnlsd9uUM?4&b+tnA~bfd|3M*qizCQ?ac*2Ysm*o8)|^AhJwfgkzi5yOh#mW3)w_*=0Gfi(HO*fLx$g%kAU}6nh3^Iw|g) zCUaz#%d^Z8$ApGUne%Jh0XXdI8`3}IKw%^+z;UHyjltWSS7Ru<&aEFFSl=4 zrS$RU--o53hUcF6G^>{Kbt`4v`Sq<0GaFqgHbMFq?>K}Kd%nrxBjBB+(H*O@3@)|{ zC+nG~zs-!`D|DtQ0z0}nuP)Xn@zw-XGy`2*rHDuX&8W@0z)sCjx7^NFyT??H!k>@E zluc8mj`tE%T71}?9U=Bj!4y0UYD8M@N4Q@JmS0U^3FKq@4_DI{lbS{@arAN>M*)R{ zwMPe_8pLiSjJ)mxAgBBMS>2t}A}dP-kC-T$(Md@D$1|)Ka%Cv3t^-3Ni%W z$~%)Di$P!Y2?~GE_O!Z10OA567LyAxUS^jv0nXL~g*g|Awjhy67i8_0-W`vJS_-P> z5s4%wWRwnn#5NnBbBncC2DKH-g?8RhlDZQfIuzL86cNUorRW&e$2h`5j6+;lD2jz^ z72*@@EUTJ0a4{6pJc*pLO=|(`H|*+Z?k$uk>rG01wLM0l$0p2>av1S_dn78bS7y5y z+3n+rOlE1uTyLM)9>X)dP*>EI()LWLsduYx)fjJjM=87U#qCq-1_2rGOg5e5qYgt`KqQ~M>Au9nm`#t z7aG?nC=76rhMe`%Tz%ESoLMD)JzTNl2Js|Zw5txWjH!^s7KXctYf6FQ_;PUp+BlMu zKdd6dQdbpmc~h^^jmat*>Pb@I?%n^$o(K1rcJ4HUJ?f)fsL`MB6E2Jq+6ZBYodwE0 zkcX@bQ(*yV%#X(ij>@@rvo0_Y%&I@hErQQ+jttbO z#cgiFZ{mvV&K{&fcMd5c8i6xyTUR}VExjddXX&0PI@P)*#vEV=4#{m=rsz6$o2mEI zj5$K=YA&E5P}AeuOHtu&^@e zfnsV2(@BKN71uU80O(bPBPxl}!=1L60uG2x0TkA2ty&2oR7q->t$Q@ zj?<7EY$9-GGL9NYBT^uQFej7M3Rmdij>0=TpT@;Hwz$()DtAY!n`cvptC_)$1322n z2r=7zAy(qi(?L#Hd=ytaP^9^Ip%sgvHRBMU<`rDbD!MVUiYiD^r$sdD7WT-1dptR+ zF|~rp5c>aU1rxKVLv$7SP@IlC_dLaDsBg@?%f7orsJV&Pg1r=isPiG+$AAYFQp*J` zIo%9}Uiv*%I>b$;q@{AbMQiW!+*XtIXR&=^XPvIY_(FFbHa2^G77$9lEd+$}2D~+V z7cC@ICbi>!D0mdes`qkv&>gz2HN!S`>cl!!NDvRrwTS015|_e7xPHkq#9K#Ev?t2- z7;~GwtEeZqqEuI;a0^ndqQte>6w@3riDG*zSyha_*h&&r3KZ;(ozPNXuNqxrC7rDu zCkZ+c%xNWbXKY!PWX>jDAX;geA*wT4$vYqFiD^e>UHoyzopoL6#rkwSVVGDFBzb1! z(?~#6WFo0dMuQdMslJ;xa}gt~Eib_pM3EqjDCRbc&Wp!f;cVtS1~l>KnB3rN!UGyG z8M?DnY^ZcVIIc2PoYshi>iE8ADA>02W9-*VP#5;r(fXbARJMA z7Kht{#<2kLAR2oKtJ4+TNNv$)jE{v&am>AZ0-JDToGp$sq2drDH95)3)FI=xwa=sl zCe0aM4t`Y^;a^bY5(00htdxuL6;U^LPnS26^Af>rY5){CoF#a9H_S1U8xsuPGEWc# zdIvu|x5JXC5EruAo$4uuL?p`D9yd$xdDc!~;etwy)q<^EWgUT6B&t)NSfcJD%QQ&EJyhI)24tQS2zuEm6(H zYgqv^T+JPwEUIjstet9dv2oHhhF-P~UY424O$i&o>7L**2F1c|%b4I?IKFamn4~jw z5=y1ARiLT13>4GOa7{}^ply_~Lrat=zkzohH_>Et2j@5uoBfgb;7S*ehe*DJda(m@ za^uop*?uQOSQ*=0HyY}O&cL5lYL~~r=SX{nV72W{CJMl4qACE zfw3H*9r_aFgJ0|fWaXj!Jeh_sK9nx_&hmI2P7i$F8akRq7Yo!aGM@0{0N-0Fzb zm`td?DyU*DZbjmK4)zs$iUmG>Ht{D(j{nr!-F%EtrdK!@xI^lVGCLS%*tOsh_RzL@ zxxk10o;(N!42P;0K#DycC(F6O+o3Ix2)Ge3H2qxnI<`MN<2q4=$Pfen;#Ng>#QW$& z80K~MB9a;F!Xz3KR+P?NdB;xAOQFSSuPjO(Z-;y)OOPoYwHPrYwJ5PFE`%k^*q$sT z`z@ZYDah0wopo#MyeZi1ZOIuHYC()IMa7LYUR8#Yc_niV5x zY??LGP|cm&TN+jsk@=xkj|ho_JEUbjXz&h}Vxhk(rw_#mz~AGWVs4(nv}RkDORI@ob@k&+{;^;kwlQPfwMf4) zM-&;a)YS{&WEqVz438X+A(v`8O83I!J=3qJ=W0g*E0>^i>N~1e0$PrEzIT+N%A>y+ z2z!HSyGAokzIahaFXM$%luzrs?b;vYrX@8rtdwn#AW+D)6QUFy-7cL2dX!|a5fP!i z<}{ZI`;mmUbR^oy@&&3GPpt<6*ugu*8-p-$U@sAm*l9}RjB;W!8q zYi2Zpamfz5_)rX@ivkgzwIYkAlrknYKvp>of|2c*(9o$68zEQB_G+w88W}Zqbn%*` zY$(2D6?}|SG*5(f)YwH9#zAT2H;WNEO z65FE#$25?JW75nE$KWQ6`we5WAWyUVXL0?Q^-=6^Us@bUm|d7vYqLzlu*48*}?Ew6j_PS?3pyYBRySeE-6IN+x7?b0nsLjyEQx z=_*>yG4M$Hh<21Fv|#QinI(2dDLk5MhdZ^Id{VAH9G(Rr8m2WnL6=gf5H}sNG(`f> z;<^Hy&>q1%}wHaHI8>J4#vY zjc`mYZ+QO#Srrya;J!d^XXIuj7qzz+EM>LA-BO}ak$QdN@ZqotEc&yoGON9Ia1<7V zL$QG8V4Py&1S zM2yTjshW^5&j}nL5J*Hw@|Ve0sX4$#V_8m_7mu6EFZuui zPQS*>Ylh6Q%~0W%*bX)@L$qRMO91sR5ZGxg&ccCC(h!61)&lN(FGp&0TN70RmYiRs zi8i0KD8`IixCX%LX@=nfvEWWhLx&(D+o3@{V5ly|5-Of*6XC$ZqSdCv(<|AnDtHpw zP#f=Uaqf7}w9rYJ5o3^=CQ*{Uh4vcQ;eDtKAH(7kp%Lgnlsxyd(jxj)aTujtBpqE1NSCq&Ebv3aO3wzk}yNO+SBAcV^?XMfXyr$>%<}hX?KA z{@Gb9+qI@0OvR!lMzh!uATs-GtY2rwW zW+t=%H(+s!r%w5YnHv`qA$~vf5>4Avgzkw$QJhowc@Q;;39`G)`^;zvoN+vca6?QH z4rDl-2mmHv)#})P5Cv`Lo#X%Or$dMLQ^mO;2XHQkbSi9?s< z-{$3#D14}+^YtsqQ9wU-d#mTXG5BmeQ+lt*M5yFVS}BajoRq3yjGQyb72Kpl+bOVE z=n!ID(&FZQ&Lg~w@s3YS7egItO553GPJZ$c`RxcHP_JE8!5+@})aGQqf^KxR>WHzO zaQMGMp=IKxgvFp!l=ox8-?L49KwOeLI;hn` zZ%4nybY?3##j1O`rxYX+sfhvDf}MavoWl;cee+D3|1IGDkPF@P_qsP8Jy%{M7>P$A zgNXrIVPAMRkZTM`w_*Gb1fwa~apNG&^9eymf$<-|GrRd%JhE<8o!>*4XRXu)Jbc1I zy}x#3c_UFrIG&NCc*&4~L59CSA4E=A^l{Xg$k|UyaZm z<@~m8pv-RLpt1!)(pC4l&VeQ<2f;zzSKsm0r1q~wHGvEI-O-=IlihqQq+1#n6mUiX zzcH)i6`zZ6A3dhJ&0&bld411hZR@>Gs8NRuSV+aiA@w*uF7EuRQR&?|M@2C{f*+!m z;74?+1B494c-80_s+u-g8)XB~jQC!*l4b7V(+s%8PDI1zFqDN|?fa07Q~9OBk|N@8 z;tad~Z(aVBU>12jTj~uSUdlJemkJ!eK|`eKSn6FWRuBW(-G&HA+)#d76C6xJV z>NVYnKJ{{z2uhsw9TQ5kayK6{uBInc+74n9Nk={@YEBWu*gbP|3)TsXw>T;dpo_BB{ ztJmU~KTcEf+0@cGbh3eazCZ8E+mNd7vX1(aJQrP4mH;C7Ze5aU?9M3dTX-;_DkM`| zzpy)gjT_jtH5zAc@?=lZu zc9bdDZ7NIY;Es~hB8aVKVnoZ5)Jt*ZJ=Bphpmd~%b#W+j6}PA=a!Ba5h>$#aJhXHX z%sYN5Wp{BkGs;dU#3n@3WW?;Jsk3YvlRoEH5qzX@3YGp63xkG8o;jUJONB*JK43-$ zB}(y%2~f$g_AGCh*_>FENIjBj^w)uBnp1|&QV1IJO~$gww<(cwi{- z1s;@AShhKCzjbEpA;BoxpT6S?hxoyw?-Z>_ii|o6{T`?7$vOQ@NTm#buDTn%e)Yxb z4sGzNPk;K(^RdQ?=XPv8!Ej7_DLsu&gEpf!jW0NE*Yri7CU-|)d{zlv@W||Yt>EDU zk&wP)jbFlS z6KhbF-+^YE+lBS5&bP3Xi_ExtaRFX=&bcSw+N^W+|6e=rUY)}IEis;jUHZ+;yuMM_ zV@&w3fDI;UKm%5rd%G@P|F>oK2`k;HK7uHsM61odI|LD*X!a%4DDIVSasCOO>s8CD z^H0_9=5tY=-?;u4;`zm>FS>#C*+Uh3YnU3=xc_cWRZOa}t1-hbFjbDxym4+~hQH)k z`jFKp#Mo0kXZq?c6grkk2>`a2pl_*XsjtF`(*&pJHD;dQ#>|Vo;wZ|Oz|13NC7ijy z3Qh~+gbNQ(*LTpcU$ey}y}CGw z7FpIp)yV;gd*kaYfF;bh{(bghJ=0?$sTWitlH0s|;83BJN23-YE2!kkeMuYh7MF6QEfrKM%7jM&vY_vP?>`Gd8M$h)`+xM6tu(Mg6l14EcT=VtA889r|x&B3nFv?po zc1UF4PtaIM&f)9CwGnm3IQ1Q+>#lQrgHl2cLU65oTu@lusCs;OYWrKJM1$wTbZC^j&cTW!q22RE}FB z$IhVY)P61Z6s?&BH;^k3Gmqh)m6>8ZA}Dbm8_r@DPbHW zI2fax?6>KCd*MUVsUoKHwA&Fw@5X)SvUKj~4~yvN(saJKd&e6@0yUebQPzaun^+&2 z+vCMd0YMy%gXX!dL8T^Y9)_}-P$w*;^EHL!U{e&3*k6b4N-TvjgW?Qjq>cQgv!-uZ zh28%MnSUteNOFrqhOuIIj0C*c8pJ)XQo~1i^ubgO>ysKBNii?;F3oJr6L#>s(#qxe zG^IPxftW;s%uHu3_^fP0I;x#L?c5c(Lt)Kb4|hFw*SnMp4wx5S&SSp`&-z0n9*1SA zq@~^qQfaRtj9VYU+j7{PX5o#a!+dZOyL7K~@?FNdQD=TyYbR7XJB^ug9)|h@@u4N!hfDPF}kx3mwc;DFg9gigG-3tjzha#=zKT^wuua zq3ydO?BQUZ_#fHu&@UVNWkRN~E5@*!`62aAFz8{Pt8bNkN3lS-U(Y?3RHE)>Erv11 zJE>pfCWC#To%u%g`fp@+ek1$cXkko5c&p@ux9MUEp-==GOM=hyU==jhqtC`@+*O&|NU*Zy38>B1!WOp*yy<}8n#)(B3qu<1JknU63q;o6p}W4fhNb$;?6>z1I`PB zh2HF@4aGImz7-3TJc<9*5&CPsflDMI>6l-4$gjyhl97sRJ#>0+PUNvIiT!5t%ajNF zHEvTPlGC8cJ!=`R!S+zlrc;U2JI`c-#{F60KUdsfc8khQVr&prA9w7I7#lX)=#v)6+0Mhy z(ncRFbXZ_*l;6acBcvp@#;q4=pQ9ryI8y|FLn+}#GgpCi^WT!{`Z_iFA`q;0;c8p8 zYch$5EncjDFGj~i1+~&&Y=@K$dkU0PH+-Jg|1|0bv=J8rBcyQOKBDlI7g@2R5gqs? z+#2I!&TGz1#DdXe70KSXp44d$TC`*!x1EXGxWOOi3LP~m$DbKE26O$vtG@$@A{#+M zgoM-~R;}n$DxCUS)FyCh*F|tD<_HNhy#i)Y&C`^&42x1jr`G&Mj6)by7q`F2`Z(=T zOGC=h#M<}{r5V@oUfp#ORU@VE)Fe{H!FgR)CaUiu)9(ndA@UUSy?M^V>#^-``9RM) z)<{hNBNSzB@bY0dZLppJb-OBH9a^|$HA_o4FEC=}2ZYCLp0wM@Wey2m562qhjGTzp zvctk5f%X<_)it-1qC2>3@!B!xXrM55rD`cfbfwh6?q(X9QS--K+=Em^U{tAs5{*rx z)1FCp*o3p`_-8d3YcE_~EW12Oe(}yJdA~sRW3<0)G%VU!Ckt4B~apZ_8p3<5r z$*3Z%I?EY%iddjZtI*j?bg&?CYS`a|W&Uw#?a&DZL^_pnNg*iETT5SQ>b#^p z5icq8Qnu#R6chu{72o@nYb1F2pHs)Rkpw>x)?3mB@(5~mn!FYM;_jj<0Gum(K(A2DkRq+UGbhX5e@oAR0 zm}~`4>fFTH?8dnh=MlJ~;;MHN)}bwa3#73OyAoJ4+~}CwT2HB|`{IA>(|f&?K_~qCU;eTYD3F>_P#@1rp{X z^wi)8j*z-2>`ri88aHh`CjM>c$sQ>ttL8V3+eT{2cY;u@K`=~5=FAD#S?%>Ikr7V< z&UK1pR4ujq$zygpbG#|zVm1e-|AYQ;!o5~D(|kkTCUtbHmG2^&5Ih;0r&FSA;|PQ^ zp;gFN(@-(C5i3@g6s0Fo-aXVL;ub-*I)Rj%i>F{bY!;~!VfOSQkjMQ7F^=PF$7LA} z)`77u&3~#R8@}sq9me zpykghNIXNZf-@26SXh{gbe@GhjN2GZft1SiCKsY61Q%8Dg4^1kOoB*Nc{9c!7a*!T zGqZ!(X_%J`q6k?nUT8QYV+g=HL2Y^P^HT8hj=7a;J4?_i%dE3@G!;&97>IYd-A-e9C4nB;8^0vqWVwy2>*N=tI80vC03nR&tTUv1+eq(5?mtRMnSbo0XD z@R1{cdF05lTJ$!%RFI7BEvVsTlC$z)aw z@KN<;cblXYkTW+(dud+XCnfa4B#My{JwLH>*b-p9F#(u+cww0NDdj(rsLk3@g>ZRT zIhAw7Xo{h~f;}@cHSc5a1lLaXcFHye)g$hHX!V4IL-`03(S!~Pr!>PLcZT&8M~LT= zwhhE3C5=0B#CAG5uhPT7$Gc$~1EmB5v~{epFn!FBb=K^)Hm;3iA0$i9!qI3bgwtw| z&&D{W?4+<-)leGHY0r`Tq=`{)@t|nRJkH9sqlBg-ie4(L{mFoEcG_;GhFi0(2E$W} z+%)S?nR!MPY6(rvmyUTvcMyDDk?mOG6#CA}iR2pf;sK^tw|N!d{iM$hijTPU)umxr z^kC<{(84hx?7K^gag$()HV3#YZpEr3e`eU{I*U!m!aR!7%0$%X;VdkwXQah?n-czs zF0m}?_Kxo+O>P8E!?I&zc9Mkn@5QjQ?z}$(l%^)kY@SkLR%aVOB35T6*TL)%5<6jb z#us09k@mr`Ce8Z^ihOZx6j%GG+K4b^TBIQb1XBOTP=B+0@q6HdA4&1W`u!b-E%yKT z4#Q>?^E(XNcNn&a8Dq)*4#Q?b$9EXE?=Wot_cLrA{FHd2-F%wT_$KN>RD@YTL*6<(LI=F{-UhzccpJS-_#X5&d6)9N)*qT#=WX^bvoLt;y)BpuFK1g+s74Z> z24`p-)N??>`6{7SFjiEF^V4UHk44aRn_}1-;tZ(l5y6n^wse~b^(iq6CP!SxAu zZ|?jn@WX9(bJGOaRZx{MvYrZKi&liFS;Hyx!IMu3oO2fKTg z1yDk@yO;v3e}xXy!Q($FfUG;D+U*1;b@VunGi0_ued`4SXpkF=>4dg1+Gw;9c?Cfz z9k&!<)Kz?~w&~&76dc`ywt^8>Ko|hxzujOt$BTD+x!ye6C4vOL9j%RVxM8iRTu8O_iqrGV)(n+IxB9 zy@E;(cG_cs$-CElh~!5U{#&jWJzm;0nXl@QuLmPbrJVS2$~{`c^cbM(oCj`aIbGWwEw>SV-uz8N(UZ%;C_yh!!EjQ`Dsip^Hf*vx76zM3$5XiGwuz| zG0t#`>xj*vuXaZQE_X40kzscfuP`;hHnt-0pN=tZ!%G{$#s7-_%Or#5JZkque~rkr zt?AEBZ8P(=_AU^2E@{yV4Pi8HhbSU>iw(fG3*td@r*G77XP8|mwk?@*bqq7o>+g}#=N|M%j)UiZ@ay81k;(*!apM?bV2vZL_E zmL{d6nKi=g)hnENB5R)X%u#Gj^t#R~oA)EbhbtorC4i!rLnac1rxr>b(qWd9&R6P| z*Y(x1kb)PVm*aXh>00%?M$k&E*xEej4`aIII8EiWA(Ur(_pp~3^k#E;LD-G73`0U( zDf})iiK1Mjq-B+_c1&7=C+?1IIC7)_+IZ%svrH1ClG(sCU-`N6vMq}Y+oEvC{Mfc^ zkBF6Ng{fIDwlFpNVr5lU2WsUGX&eXnaPk4OnCymxHb%)HdrN($ zJYJHvYmgkVy1(&w%}py~5yy=RC$oHvwa3$Yhng%88G2?AUVE#h@y;{;b$L zwu^k+Uu6|M#raS=kQUkz8e5aY3)Kr6)$n9mS3q)A<#*il+Sk4|+2y8(sZEH~;w;zr zoJGMPtQHnuM`fyU2U?#~o7;DTbp%5_XaD-ifi@P6F5&%EhF-_=#L6>418i_!w7KP* zvq$U`;^EZcY%Uu%B?nc0b0~S_C8K2AQmpCm@Di6^c5(Azn5)_Oy)PLfS4To{FRm#X ze}{VGse{BIQYqIh<@^5_4>9rFDDEAm|Z4(a=cTY@9f z_y2bH?ZI(f=Y6|(A6P7wz!C((hbd_dDZ&B$huu?rFe z2!Ll7A-Mu3vgk%oJho-oN!&(qNK0{&aq8Gk(xjbcGLhrSYufzT=}t3~KQc|Hopv&v zwv$ORaeu$>Jnp%>3y_xObf$~J*}M1N^Zw2`-}|flC-5P7V!-?N3jI9U;Gdwuhy(E4 zZ+~RMpEvM$_ToHL#`qF^SCO!;L!pcqQv<3cpbPk9B3l<7uzH~^0Y2!PSd@XzK@XAY zRb|%y$%+yW!_a@Ch5qQus!`6mTv%RhjLKn^_0gw$MfpPNvv#~1k1C&7UM>?!#rN4~ zrB`R$Dn56PIL+}ZtMkw{GHPyo+qI1N*>pX$YnP_MxV`jw~aqWcDXQbM2*wd|gq-h_emKp9braAQ}7 zPPW$1=CqV`x1~uklEj5Lj0o%pZO8_&Cv?@uuDKW5p~l+k?78wJ=?FcN=vC1^FatSV zKL@=qqjQDl;%J(k`D6tSfsxbP(-X`GN2o)CVaC(!34%x%p&p@8L~Drzr>NS1>J)X# zRngd!o{R%XVDH9wv_|2M6E)sGp{TiAtH;q^(_8^(Ta?hawn|}9Ru-2rMxy0oAX2bJ z(QL9xxY@FG1b~r6lS7J_{+uf?-G{;^Re~&UQd-;rrW`ugpGM4OS1er?h9rQO*9j6P&Ce{O?;g^2d(}D zbR7z{U6eA(8RGbMRkE-lfv;SFn$3TEpha1GUu1nlW)EN(M~*#Jdh!#;)H}#)8ORjUp-)|`p+D^~RG2t6KhW7GC#r*q zUz@?yyQpC+8>lx>>kT_xz~T5iGFl2V!msiq#JBMko7#fh!3q{%?{ z`X=1ykR|;k)Ux5Vg1_BBbATP2pnxA;_1KISo7hl6!uNe*(yZ{ds(OUF&$zh=KrL`^ z_~AF3c?|y&(u8o!Fp^fvB*sWm$>vb|x*dR6lni0vhgtAuGoV=Tdms2O*?Ke4dI{iC z?+`BR%(t1+0Geel+MM_)AoKsL2_xzAW%kY^eRg>*ey@bj&tbfOAsjWu-|sIh{E{ub z4HgJwhw)#ZKoZW$47_90moq(I!D};(mFdG-!tlX+v$&vD+mNL>L_E&9^U$aa!&1>< zv#dCLWB>EOxqu&f0&m3;35q`1VCfi#Z6p0xAQCE#szd`p7CLM3e5oZpkH)NHCeiq* zju5-Ikmu{{G5)cb7?~d02+~xGa$>4<+$*+^AC3eeRK(5PT`1}I1)SD^(#rQbScY1T zVWph6lReWL@wdWRY2NK4#C8L=b!{FhDIB9ab&19S{hA#d?Gmj&J&T*}p8s zsJ8UfGH~!6Hx9l56x9qARkBsOK%)Z7rY_Jhy@LWgmG5F5b%URfQ`*hL*``Rk;8Vm2 zPa?!0Fk%V&OEV?G*Zsi39>kKnNVH?Ax*zD>oDe74G|Cm%Ac#A9rc6AF6pN;ltY&yY zqo?C!j&>Aio^4j5P#Pg2LIVW%YM1eeN^8*SvPI>~Wk^VXdjfT4P@9nLd5l`~v>o8M z%q>&npGcXdtvs_9j-SR}k0@2S?q~rYtL8iWOq1*&9RrNHa~miK+87DmTsG9;G^l{- zgD@Egxx_k>2ugbprI8xM}};S{jZ&vK-V zFquI^F2Z_40uo&>(2xOaTV(Av3ufRndE*zBSlf7Bfqaw3XS`gzH+^F zlSVBAL}@d@2=D{acDP+^K8Vm z5wdvsO2Eq(uq`NCCe;1Fzvwe8wHDh0BBO-RKBU5?v|}$5nT2sywDOP(Gb1#!`guHn z5s&oY+o(*3m7pW8c1@CZ@$|3R8{$^<{GuIiK?}2^UrY0iHjPIPsdR{lx36$W>a_b9 zigMHc++z5;=rty6HSg6)*8kq3zW3Wt*57({?Pvpy_svz--+PtpYOAEH#->A|N#sE{ zHCX5g-I@q!C8pG`;+bKaJ18(01jyh2;(+SQCYAjnul0EM~tM>jpGLU)mixZ z!}dZ{mWnpif+&}jR3Qw!0w^`M?*}6rx?kHh zPk-Q<)g>KJylc~obc{(1=koQH>*ewoj4IJ08~_H@byY}%p-xa;h0Q70A4PgEX z+vJy{fGRNh7+y)kg{59M`Mq%sm1t8ZRC004HXNakwX)`ecz6Vge9))VLI&MHt3P5$ zutoZ4K=;Kp0%m1(38u*CWzGI4DqPc%5*Uis!I_&D1n~4%H>5UzrDflIItu=n)W$`)^B^XT zMMukKak;_WMym<>(0tEvk#Jy{2}A&LsDu~-1%2dv7f^?+>L%nFPpU`_d5^a-eOfp>c*w2Gw9Y^toAEReu>FV zCbyWpjT-e5VcldXLnV#zrDA>f7ZaOTW3R?v4PH&WntU}imljrMW<9-@27;BS{4x%P zCquW@oEW-S;g)MRkO@uKh+ZYUd{i`*0|G{?L4ksI^F>uwdAy(2`}{$4my!Q^5Su8=dK9k9FpMP5DJrLwj_xZD6{ z0hx^&0~*#Ai?fSx*v&2VY{|F{w?8_m94cnBN&d%BJt!vH?8AO7kz9HTj)8Fip|^UP zt>~<3zA8srBqOU0C4Z4e{vb&}GpQu<${h@jZke>`D3nRHyf#uum$nz(`&|^het>Q` zXpJ=B`|HKifcPTk(+YF_nQQB9(N*|_^oV&k&lZ`!_iG4_;~W$A2TuEPIZ_3A7n(b4 z6syH=n~#=g{Ap?Vsv9rOE3zmFy%5n+kXs{W9T+nkVi@IeIJ{7&cW-(gRNM-Tr~y(S zZ_o*QSO{`dzrKVA_4y`HH}az_2g556qkeJOM^C0vl0|2PgCw1F^@<4IQ!}5Hb;KIv zJ?S%ct#C!re@eKcV;oInWhh~QVTk5wjwWBiL&tOyCTzV9pH^ai;AyIZX$g-z)Ikvk z=LNc~Y4CNU&??cD(Fr-KaLQSjV?!dx$rf#q_u87{3MzmBjj{46r)39!;I0*6_y-mC#)?6GXnsA{b~tL6dC zf;NET=#dZQvRi*xi}C_VCJ*)Lz?#BE!f4=d5)*MNKwmgqr>;d@kFJjJcrKODMH;cr zpI?RkhEP8)JO)qV^OvAe;4?X&zNIyEwhh~B8$cNv=adzNejJ-Bu8>x-NMz9gz zU@+Y@*hiWq4JbX{5_1}h&+OWy19;Sn6PalK+>$Nl7Evxiz61?>8%@wynWMH_y>0|Q zMU;@z^%%Uv+P`ejyuZtUg&sd$cA@2Oi~4<)En@ArZKBXwV|epXM`xWJ&bETm381xf z{vR1(yrYS%A}+3HY2RClJr`TrorDGeqjfK2)kqvH#dz$6*i!Jk8S%=gL@ahv$DQYP zDtNx$pSit(ZmKOoah}Hr*x^b+8iWO4Um$)Kq8=W2XaQUlJJM&bAQ=uE?LJ8qO&1#S zp2a4otIICt>a@+#*q2NpQz zH#g$Y>^+%SXS57Q&{&1m<|Tu<@yEn%iK(OD`dKmq$Mwt|5(~uzYKxyzzlpd z(3Itzb~BM9Gaoc%vT_4tX!{-@Qx`h%BYEOEVpp&aLjJi@TLRv#*+TV?xeieWLtv-|oC=S%VlC{L#Kos| zr5R}!;J94oG2?TkVP9rDgy*KkdLyEzB51rWV)vxuN#H!%eXLLwR5)>*U7kYPu~F$@4*XT<;)c^T7`-0nQb|<*83g{ibPvI7Ic2 zQoy;{ll1U)o)n_10m!S&VXmZJ5WF^%%%SZZ;fJ+_9q=4u>HvpmDc`W!sS}`CL1-(q zkjrJtg6-3K8|H40j*lGJET$J!aD`jB!^iEohm$)f*z>RB0yuMQA)^L?K?B3vfY`MW z-+)8^8-beJK-{3$0;CYkUP>18<3_5OG-bxf!01&7H+DV~c|I?N|-K!B6q@e42@b zGrEO_X~+E{BTi_&!LRb}+eo0<{58JIgSVA|Y*vD~v~oI_d1aB>f%-sp1cqXff5Y=V zhl?2Wb+hq&kc$rn&B<^Lb)hH1TUP0i`T5})?}k!~`Y@DnP*f1kyP*VzzZU1vjX`$W zJ|KWK*K=Hl9ZYH%biHirO{?ds;ufsF=ZF&Y=#G10GB;oF4p!`=b`1(XyR^KtpPMrF zIF0m#F&}&^TH_1c^ntoj5;P%Ra>x2+`avN&^aPG;u3@;ebW3LUUH+8G{vNJcDYmJu z4scrgn1~0agdPUT@N2jWt?cNK;D#*LUtyMCWg_$%$-Do;p(&tj%9GQGe9mwUx!~@; zEEMMvr98ebg>Ob6xhrgEINNSGK<2%}s*`P1tB{6lZ5`UE^h8%YD?Y=@DA>OMkUW=r5kb$^5k2M$!Ik70PXdk+WdI`eCQyZ9HSabrO3S{yLJ|cH(2`-H*6VFoMt~ zov6Y)fOLZRKhQ$Trt0bu0z{x*VSS%reLZR?Znd%`{;Dz%>Ob(|EhZG?st52KB#HDx zr0{iQ60Msr@G(nNUuPM*t9A81aJ!XWx?F0kEVj)7g7f*!y_X%KmO>2SNEi^0p-K7^ zgm?8DESH<;ET7vCx30tZ-^!SIpfttKh{Dp-lwVosrGyMMYPyE80%6|}ETrqXM*Nld zwfonCCo!k%$+cu7h9hJU-}*2aY=F;1rR*z%&&3)D?~RaS$Z5jf;JmzLtY_;!ZFG3>%p5DS!)cYdp%|fLrb+hkQOssqm!>`A$ z45P(iE7V%%=B``d9j#?>o(xVkAEF_i7kM8bm`x+T)Dc`NfW=Z+v;@?_GLZe^zoURQFjb7&^O#*_2rV`4WhO{j zJ$`S~AT5Mg4~Jy=H1EO*#6Zeibs~V%YfCe2>3tjh$97F`zogmcf^m|ZemCL(CxeF_C^V3 zg)!vPmrbBG43~$n#GRil$=PasK{}NyVz$&XuKAN3qRV5u)wfvIchM-lA@YFH$kgk+ z`gQcR-aU_SzPM3c>AyT{vY$%T_tdbF2a*L$Vds5tmj4V zZgt_cwDxLQJh3siDVi5rJ?;X;4BM`#hBekFcwQ?*xgj$talI&`E#SqS67kseEK9NV zR#xw*^7=PW$jr9Lu(c8}y_C7K^CnYv3ne|wDLaG<1`7nY2h3)sL=I?j!taNZ0j}~u z8-O}+Qw?B_!hdYE!}!bLX>->m)7>Sa53BVSNqDG!6D@zpf)Fh4_}eX1Tnn-(=mPh7 z8kE@$7ffX$m$11>s1LAsnRtQ#I^4x|Wowr|AD*AebF5zWcyvqs9vi?Nf*;~5#B`s+ zfBoMhF?$5bfMG;Z1t)7gdF5rqP6bsW{sp0s`ins|{Z?u{Rqa_z0UOTjimfM?P9RuX zFX*NQa-MF)t6ABXU#|AuHfIhwUPg`_bLjf(uba}oEqi405^$vIwrc-p1Dq}c)jUa= zwcuv@Rtz*2!r>xU=0>c#{j-VnbfXt!O}dm7eU8D(GP*hqsDt`AR7Xe*gBudUtw)P@ zHEPjV@NwupEnlzIic{|3?85zKsgFVZtuq=7?Our6Nq#$OD+SeH`_HU)?#H0G-ENqoZiUaWT;UWxHn?sJ-_6}fTX_J zE&M9A={&{;Vq+2i@x8Fmg(Ig=ie0?s^c?{+eG#k&n0(Lw6c}LPcv{XDy%9oWUb#k| zqO`$UHg7TBQ*NH4V_dX@O!nbKp~$g@Di-*V7;(#cY(8|1+AtirupG-f1M80uI?TqK zS6*T#*Q1jdR|0Ny%ZGDm|J;FYb8QxD31sH)LhtC@a z&C8u^9z0PCuEF-dn3Ke<>fE?cPYDQ%Xu8)Qye037rN3$Ow8FsDMOauJRjg_0X ze$YNlFB=UCG$pLS0Ig832aH_Tj3a@gW2PreZ=mURc?AJUcqUIsZ1#fsakPJ``QkB+ zUP!Msi;~;Y}sTf}jom$hYL=`3siRqdvjsrA(ezIq7rv2X6$~^Sq&soD@+*m0j1o)(R~~0uZ*6cux>&m`&PV_d=U3-o z^+KsxV;TFfcVbL;KGkxrx?P=Gt}lBdkl$rgSt-ECZ@;j(-G%|@kB~jtim;p1)Ldm2 z4lIt=(6*W_3=@1%^ggkX5jRG8h`F;EvULF(TQ;5B#tJ-R*aE5CDO!vaSGv}q6j3;G zsyr1lPOfadP};`@_MNVb(6PutSv{6H&ILx9qRuN4MI&mJoeewC>@0ZIt{k+5S=y@7 zw2-MocY^yQ-gFruhwzTf%K6#JqcV-IsH&|&}0ZbCRRvTg`<&O_jce6I5tPr!-*n}L}9dU^St|RmsXQZ2ZUtne(}-L+Vp-QCqRBz!0I1S&7r(q*g~AhgHiN&Ab$) z0Z|pvl$yUVkJytXB42eV$w0*X1dKD=yBQg@t@1Z@e%JMh=y-3QmA%(_y*a(p%;~kHE9O8;pY_S-OqXJMKT6#RIW#E8VjmS_xjkt!^=@5>Epen!1d*pRO2@R?l zP($-J03rJyz{5Z1+9wqq+ZljE+7C=Zr}_9S@7fQE-^2Kqy&#Gska2nY=peP;OWA5} zA*H5Bl!{vg5T*FeRkxFUryfD+l~br^s&P=+J=BO)J_Dj3FB<=V)(5%INQvHQ{hN>dUPq= z7(KaSpvACy`SNuq5z^R_v5+?}N7N%pltAtbLW?WKen6N(J+>W2@$r);KT10pQkB$cGeXn0#0&uceB^xX|Xx(0XJfn0;&U zoAD|(A-=9Cp0lk}26_S%R!trQAwWfcj1aStF% zd}dpzB>I1x5=a+?3b}$eBL>YMWmzjs+DMLf@n(vBBmqE!=8T9=(sI@GdOWY~nK_vJ zu(!6?hG%{$_FC-YTACm}!>Z5$fM6{Uwp?OrR`QvI+4&I#T)U_E?#6Ub^5*^FkVg*t zkWv05mzcv{*gOi>gq=;n8Zj3zy)gVDP6Hz!>^P_@KrE7ctA{K!8Sd0n^W%obb(Xws z+pcX%;WV}vGIOpkufppEP`<_Gx+qlrap7Un=)HS*~%hzim zuKvJYi{!SIlF=QqYXJP%cku#el8CTD?wdW23jR6xedUV@%$d!fmqxJ=`ObOtXmc_$68~( zI;aWP-X=9L^vH-;!(iA!Yg~?YzJdbO4J46$iR(b>>&L}=4aB29&!O;I&>yzohZBHD zy^b0uyc!3>8YS+|)Yvu+@NRmG@8Vd;#N?`>5f(Lz+=e_6yOlS7!6 zL?)ZbGeAo=nMp)|h;t}|dp9oD06+_wm3`U=9r@(=hhEZLQai_MK6Y#wzB(A0mlmd= zPwVh-0a}B)9MIMQDJefSqBc3p8^<(FJxM$))av*d)TUl#vccp>kpObK959ex`;|Pz z@kG~f=#Z-e-cMY82jex%TlT{}m!JCAkl2m08rPxP-i+6h&YM+wCRIz;()4KcCcHP! zLEZqLR=JrT+|5+`-VCag`6g$2<##`R6Ddp1WKqU;c*J7pwj?}Y>CkOC9kvZZr`^>( zK;8PQd#fM7_dpFY-|9XfcVDUARlOT`2CMf}3;5n49wUdaSU)IZQ27S{yKs69f0}GZ zgsZ34B5bF?k04F~Z>uB*JX%hOa7Tbs!GCr^0^Vo^Z3NP|3irIo3!@l_&@>|oljHGJ z+8jekMW;X?eL|h7HO@}cql?fCxI*L%xfQZ1fHHb)a)=$mN5nn0r0`rNs9_pS6lajU zD2}*CAe-7NhxQ=eDar8EpD0dGz%h-(gQmgY;R#W2B~bWFB07wHqQw<5mX56=y@p_1 z)xe%3gh$3$W7noir;%o3-W#{b=KfLBI%{tq-VZu72}Au8_PDY(P!w>Xx2kT*)0>>Mf-SNT@gSDD~H$x>P&Es0C0;s z#G3YJ2dw~~NIMu~U%(tvtBbX|H}(6)P1fAJ0u|z#DH^n#n=wx%2lzIT0~6}Wx5eX3 zM(cHCp4AhbzYNV2=nU7u_aT$~!V(t>Z78iT3^(irt9|Q?FD6M!E9)}?lCI}F!SDru zABoUWjxht3!`pGl86&yQ2cyqV6kh1e{JhBwH)#Iw6-QjD2odfYXwZXJALqkB8aBpn zVZ?w#_XS+cmJa8$o>#YA2#JqY-EA?+5BJ$!im92`HJ|M+LF9R3in| zl%s3On@|oD1(_nQA$Zl-P$J2!C83-WEA=+AK)s>ylUKho8JEa2n`k#uhm;BiD(E2`G4lkZA?DTpilm-jI-vL-I(|VvQX=;7QZyXtl0^?okeRoJ zB=q2GNjQw0b{C2d!{rJH%7LygIAw-7*;?2Q_MsVzA0s|b} z3XCHuAaR06Cbgc$a7k6*p{?XpI7;H9LD5Sv17I2r3Amdwi02=1JpLF7ps3A3@So!D z0!Jjx7Rop@_q6vtEHF?~mh{R}IQ(YM1Qdy$Nu)dJivUQRULF2~wHp#riil#LY&LA` z*`rcv#lx36+Tz|qXkN2(uwB&wi&RRT%}S-u7*mo;9CeTEqkO?`_EX5S!6G>0?xjzR%-kPZhV?G z3i{0LF32V_LFbYO+Zn1_m){4+Y^3@=Z#xOPa(863#IvXj9+3#~avp?TYe4 z-$sg-lbVYPNS{{C;L6f=uPguqV^qd}8kL2r^d31SV@9(74R(ObJw~R&J&}6s;Sll; zTu-<<*b~_rbGV>6pW~&#&-h-Jq;Ywo4{WVfi?_}5p+;7-G>Y`$KletpWBq8x8=&D8 zRJ#Q|y;oXAa}uiK!We|gqu4gXP_s!PuGGI_IRa*LxH4eYNL@xJFZFC_0S}7Md&w4Nb<3rT`6+GS>EL! zhz$Y{PIZ(&|BP2W-*kXgE-^)*7Y#*C$af>!Z}L62J!7`zWR}S#CHy$s%7Mu2O$I|d zhEw@OzP~?_p*y)A(D3n04;0LkB`AA$?#SFJ1?CRmf=C82!{tea6`8+NZ$#K3rIlN}z$}XXEh24%0K*VKo2; ze3#d7TE%tj$)14+5|uGAMLEjw?i3!aC6m8FvI!`0hxiUbNic$bN;OCfX=bj`^x_c$W3(wcuplIk{e>dZ zr!80p+7x2c_wa@q;PbOgWbgX|@BIuDIYFQq5ray1NrXc)J&5E|`tTzM#MW!3&sZH$ z-Cr#*%S%i?#pD4N__Mrvg9!m#<(Pbt$(NY?9Fw1C@?|CglV4=Q6(M1%)z^3>BgB1D zeVxe!lY>k?%;a~N{A(t}snl;V`2!~Zj>$)ue27UANvqH3ms5we)gw};%Az{Vw*Dz! z!suc^m<%%6&Lq!d50hO?Xl13i+bdG0Gii(r$V;`GcZQklVDbc$BTUjP{J-+*zcG=S z<|M2C!$d?|++I|i?}3brsU(t_?IjCQ99^oasUAK|F!^mJ{Y*|X>*Gv5#^hcmA7oNs zau1UcCS(_@`W?SRKFZ1ycKK@ZAxA+svFfsKklTrSBkjW?c z^GA5~Jg+8swV%mF{A~4|lqlY^bTspLo^KuE3(LH^!bCh6*LlSqQuQ)M*Z9gDXtK394NvVlj&ALm&80^6EH~FYx^@GU?~f29r1VlOa_k zu7_r5JjMt2GZ|w-6DU>V)f|(POde(OHXn@h>K$H*-lX6iKZ$#-p69f|z8c~~>OhLI z)=ZygTcQ3HpZyM#Z!)1;zo_QJx)KcFQaC5qSY+-5ypB>)h}#k36_pybYmkE3P*>o} zh#+Do-%UWltCi7;Up3XrYVASwh#*;@F+8Te9&FKK|O))va zD2`uH~6gM2|U$e+o>o@eL`o(6F6yd60cnY^UC za}#(661L&d{wIbcR{-T>SOdk)caYhg*^PH$d)+?(n83(jbb9(T`SjpEwhIoUv-w^5 z-MPfjJ%e+(VCaK`19BfZ@&h0RkSELW;qL=`)A&7}P44>;@AMBzIw +Maintainer-email: team@aiohttp.org +License: Apache 2 +Project-URL: Chat: Matrix, https://matrix.to/#/#aio-libs:matrix.org +Project-URL: Chat: Matrix Space, https://matrix.to/#/#aio-libs-space:matrix.org +Project-URL: CI: GitHub Actions, https://github.com/aio-libs/aiohttp/actions?query=workflow%3ACI +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp +Project-URL: Docs: Changelog, https://docs.aiohttp.org/en/stable/changes.html +Project-URL: Docs: RTD, https://docs.aiohttp.org +Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: AsyncIO +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Topic :: Internet :: WWW/HTTP +Requires-Python: >=3.6 +Description-Content-Type: text/x-rst +License-File: LICENSE.txt +Requires-Dist: attrs >=17.3.0 +Requires-Dist: charset-normalizer <4.0,>=2.0 +Requires-Dist: multidict <7.0,>=4.5 +Requires-Dist: async-timeout <5.0,>=4.0.0a3 +Requires-Dist: yarl <2.0,>=1.0 +Requires-Dist: frozenlist >=1.1.1 +Requires-Dist: aiosignal >=1.1.2 +Requires-Dist: idna-ssl >=1.0 ; python_version < "3.7" +Requires-Dist: asynctest ==0.13.0 ; python_version < "3.8" +Requires-Dist: typing-extensions >=3.7.4 ; python_version < "3.8" +Provides-Extra: speedups +Requires-Dist: aiodns ; extra == 'speedups' +Requires-Dist: Brotli ; extra == 'speedups' +Requires-Dist: cchardet ; (python_version < "3.10") and extra == 'speedups' + +================================== +Async http client/server framework +================================== + +.. image:: https://raw.githubusercontent.com/aio-libs/aiohttp/master/docs/aiohttp-plain.svg + :height: 64px + :width: 64px + :alt: aiohttp logo + +| + +.. image:: https://github.com/aio-libs/aiohttp/workflows/CI/badge.svg + :target: https://github.com/aio-libs/aiohttp/actions?query=workflow%3ACI + :alt: GitHub Actions status for master branch + +.. image:: https://codecov.io/gh/aio-libs/aiohttp/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/aiohttp + :alt: codecov.io status for master branch + +.. image:: https://badge.fury.io/py/aiohttp.svg + :target: https://pypi.org/project/aiohttp + :alt: Latest PyPI package version + +.. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest + :target: https://docs.aiohttp.org/ + :alt: Latest Read The Docs + +.. image:: https://img.shields.io/matrix/aio-libs:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat + :target: https://matrix.to/#/%23aio-libs:matrix.org + :alt: Matrix Room — #aio-libs:matrix.org + +.. image:: https://img.shields.io/matrix/aio-libs-space:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs-space%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat + :target: https://matrix.to/#/%23aio-libs-space:matrix.org + :alt: Matrix Space — #aio-libs-space:matrix.org + + +Key Features +============ + +- Supports both client and server side of HTTP protocol. +- Supports both client and server Web-Sockets out-of-the-box and avoids + Callback Hell. +- Provides Web-server with middlewares and plugable routing. + + +Getting started +=============== + +Client +------ + +To get something from the web: + +.. code-block:: python + + import aiohttp + import asyncio + + async def main(): + + async with aiohttp.ClientSession() as session: + async with session.get('http://python.org') as response: + + print("Status:", response.status) + print("Content-type:", response.headers['content-type']) + + html = await response.text() + print("Body:", html[:15], "...") + + asyncio.run(main()) + +This prints: + +.. code-block:: + + Status: 200 + Content-type: text/html; charset=utf-8 + Body: ... + +Coming from `requests `_ ? Read `why we need so many lines `_. + +Server +------ + +An example using a simple server: + +.. code-block:: python + + # examples/server_simple.py + from aiohttp import web + + async def handle(request): + name = request.match_info.get('name', "Anonymous") + text = "Hello, " + name + return web.Response(text=text) + + async def wshandle(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + async for msg in ws: + if msg.type == web.WSMsgType.text: + await ws.send_str("Hello, {}".format(msg.data)) + elif msg.type == web.WSMsgType.binary: + await ws.send_bytes(msg.data) + elif msg.type == web.WSMsgType.close: + break + + return ws + + + app = web.Application() + app.add_routes([web.get('/', handle), + web.get('/echo', wshandle), + web.get('/{name}', handle)]) + + if __name__ == '__main__': + web.run_app(app) + + +Documentation +============= + +https://aiohttp.readthedocs.io/ + + +Demos +===== + +https://github.com/aio-libs/aiohttp-demos + + +External links +============== + +* `Third party libraries + `_ +* `Built with aiohttp + `_ +* `Powered by aiohttp + `_ + +Feel free to make a Pull Request for adding your link to these pages! + + +Communication channels +====================== + +*aio-libs discourse group*: https://aio-libs.discourse.group + +*gitter chat* https://gitter.im/aio-libs/Lobby + +We support `Stack Overflow +`_. +Please add *aiohttp* tag to your question there. + +Requirements +============ + +- Python >= 3.6 +- async-timeout_ +- attrs_ +- charset-normalizer_ +- multidict_ +- yarl_ +- frozenlist_ + +Optionally you may install the cChardet_ and aiodns_ libraries (highly +recommended for sake of speed). + +.. _charset-normalizer: https://pypi.org/project/charset-normalizer +.. _aiodns: https://pypi.python.org/pypi/aiodns +.. _attrs: https://github.com/python-attrs/attrs +.. _multidict: https://pypi.python.org/pypi/multidict +.. _frozenlist: https://pypi.org/project/frozenlist/ +.. _yarl: https://pypi.python.org/pypi/yarl +.. _async-timeout: https://pypi.python.org/pypi/async_timeout +.. _cChardet: https://pypi.python.org/pypi/cchardet + +License +======= + +``aiohttp`` is offered under the Apache 2 license. + + +Keepsafe +======== + +The aiohttp community would like to thank Keepsafe +(https://www.getkeepsafe.com) for its support in the early days of +the project. + + +Source code +=========== + +The latest developer version is available in a GitHub repository: +https://github.com/aio-libs/aiohttp + +Benchmarks +========== + +If you are interested in efficiency, the AsyncIO community maintains a +list of benchmarks on the official wiki: +https://github.com/python/asyncio/wiki/Benchmarks diff --git a/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/RECORD b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/RECORD new file mode 100644 index 0000000..8503e0e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/RECORD @@ -0,0 +1,117 @@ +aiohttp-3.8.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +aiohttp-3.8.6.dist-info/LICENSE.txt,sha256=n4DQ2311WpQdtFchcsJw7L2PCCuiFd3QlZhZQu2Uqes,588 +aiohttp-3.8.6.dist-info/METADATA,sha256=OdVemdf27mXov6yoW0zrhzmxQRlLKtU43RXG0m8Efbk,7695 +aiohttp-3.8.6.dist-info/RECORD,, +aiohttp-3.8.6.dist-info/WHEEL,sha256=uAP-ukXX4cQcmS4DJIfTMngbzZ5Fat-TcU2LYkL-U3k,104 +aiohttp-3.8.6.dist-info/top_level.txt,sha256=iv-JIaacmTl-hSho3QmphcKnbRRYx1st47yjz_178Ro,8 +aiohttp/.hash/_cparser.pxd.hash,sha256=hYa9Vje-oMs2eh_7MfCPOh2QW_1x1yCjcZuc7AmwLd0,121 +aiohttp/.hash/_find_header.pxd.hash,sha256=_mbpD6vM-CVCKq3ulUvsOAz5Wdo88wrDzfpOsMQaMNA,125 +aiohttp/.hash/_helpers.pyi.hash,sha256=Ew4BZDc2LqFwszgZZUHHrJvw5P8HBhJ700n1Ntg52hE,121 +aiohttp/.hash/_helpers.pyx.hash,sha256=5JQ6BlMBE4HnRaCGdkK9_wpL3ZSWpU1gyLYva0Wwx2c,121 +aiohttp/.hash/_http_parser.pyx.hash,sha256=IRBIywLdT4-0kqWhb0g0WPjh6Gu10TreFmLI8JQF-L8,125 +aiohttp/.hash/_http_writer.pyx.hash,sha256=3Qg3T3D-Ud73elzPHBufK0yEu9tP5jsu6g-aPKQY9gE,125 +aiohttp/.hash/_websocket.pyx.hash,sha256=M97f-Yti-4vnE4GNTD1s_DzKs-fG_ww3jle6EUvixnE,123 +aiohttp/.hash/hdrs.py.hash,sha256=KpTaDTcWfiQrW2QPA5glgIfw6o5JC1hsAYZHeFMuBnI,116 +aiohttp/__init__.py,sha256=kghOjJA6KwR3D2cTMLbgGwLlkzQzPwm11FiWGyWzBRk,6870 +aiohttp/__pycache__/__init__.cpython-37.pyc,, +aiohttp/__pycache__/abc.cpython-37.pyc,, +aiohttp/__pycache__/base_protocol.cpython-37.pyc,, +aiohttp/__pycache__/client.cpython-37.pyc,, +aiohttp/__pycache__/client_exceptions.cpython-37.pyc,, +aiohttp/__pycache__/client_proto.cpython-37.pyc,, +aiohttp/__pycache__/client_reqrep.cpython-37.pyc,, +aiohttp/__pycache__/client_ws.cpython-37.pyc,, +aiohttp/__pycache__/connector.cpython-37.pyc,, +aiohttp/__pycache__/cookiejar.cpython-37.pyc,, +aiohttp/__pycache__/formdata.cpython-37.pyc,, +aiohttp/__pycache__/hdrs.cpython-37.pyc,, +aiohttp/__pycache__/helpers.cpython-37.pyc,, +aiohttp/__pycache__/http.cpython-37.pyc,, +aiohttp/__pycache__/http_exceptions.cpython-37.pyc,, +aiohttp/__pycache__/http_parser.cpython-37.pyc,, +aiohttp/__pycache__/http_websocket.cpython-37.pyc,, +aiohttp/__pycache__/http_writer.cpython-37.pyc,, +aiohttp/__pycache__/locks.cpython-37.pyc,, +aiohttp/__pycache__/log.cpython-37.pyc,, +aiohttp/__pycache__/multipart.cpython-37.pyc,, +aiohttp/__pycache__/payload.cpython-37.pyc,, +aiohttp/__pycache__/payload_streamer.cpython-37.pyc,, +aiohttp/__pycache__/pytest_plugin.cpython-37.pyc,, +aiohttp/__pycache__/resolver.cpython-37.pyc,, +aiohttp/__pycache__/streams.cpython-37.pyc,, +aiohttp/__pycache__/tcp_helpers.cpython-37.pyc,, +aiohttp/__pycache__/test_utils.cpython-37.pyc,, +aiohttp/__pycache__/tracing.cpython-37.pyc,, +aiohttp/__pycache__/typedefs.cpython-37.pyc,, +aiohttp/__pycache__/web.cpython-37.pyc,, +aiohttp/__pycache__/web_app.cpython-37.pyc,, +aiohttp/__pycache__/web_exceptions.cpython-37.pyc,, +aiohttp/__pycache__/web_fileresponse.cpython-37.pyc,, +aiohttp/__pycache__/web_log.cpython-37.pyc,, +aiohttp/__pycache__/web_middlewares.cpython-37.pyc,, +aiohttp/__pycache__/web_protocol.cpython-37.pyc,, +aiohttp/__pycache__/web_request.cpython-37.pyc,, +aiohttp/__pycache__/web_response.cpython-37.pyc,, +aiohttp/__pycache__/web_routedef.cpython-37.pyc,, +aiohttp/__pycache__/web_runner.cpython-37.pyc,, +aiohttp/__pycache__/web_server.cpython-37.pyc,, +aiohttp/__pycache__/web_urldispatcher.cpython-37.pyc,, +aiohttp/__pycache__/web_ws.cpython-37.pyc,, +aiohttp/__pycache__/worker.cpython-37.pyc,, +aiohttp/_cparser.pxd,sha256=8jGIg-VJ9p3llwCakUYDsPGxA4HiZe9dmK9Jmtlz-5g,4318 +aiohttp/_find_header.pxd,sha256=0GfwFCPN2zxEKTO1_MA5sYq2UfzsG8kcV3aTqvwlz3g,68 +aiohttp/_headers.pxi,sha256=n701k28dVPjwRnx5j6LpJhLTfj7dqu2vJt7f0O60Oyg,2007 +aiohttp/_helpers.cpython-37m-arm-linux-gnueabihf.so,sha256=4NPiUR371dQX1BwRVLtGkbhvjq2UGLM1f6OA4rjswF8,106032 +aiohttp/_helpers.pyi,sha256=ZoKiJSS51PxELhI2cmIr5737YjjZcJt7FbIRO3ym1Ss,202 +aiohttp/_helpers.pyx,sha256=XeLbNft5X_4ifi8QB8i6TyrRuayijMSO3IDHeSA89uM,1049 +aiohttp/_http_parser.cpython-37m-arm-linux-gnueabihf.so,sha256=BvlsqfKOfQBkzHTj_QWGzW8EFQrwlyGexddUbPw56xM,687336 +aiohttp/_http_parser.pyx,sha256=fzKwwVlcGnGVeiGOzo05d-2Rccqtl9-PzYKqgK3fxdI,28058 +aiohttp/_http_writer.cpython-37m-arm-linux-gnueabihf.so,sha256=NDoCugEAYbg5FMJSnv5CDGRqPWp9eU0sn6iE4RJMbNA,94692 +aiohttp/_http_writer.pyx,sha256=aIHAp8g4ZV5kbGRdmZce-vXjELw2M6fGKyJuOdgYQqw,4575 +aiohttp/_websocket.cpython-37m-arm-linux-gnueabihf.so,sha256=uYvMX7eTSGugBQCgmmPMkAOtSsVAO-QZUAfrc2H9F8g,64796 +aiohttp/_websocket.pyx,sha256=1XuOSNDCbyDrzF5uMA2isqausSs8l2jWTLDlNDLM9Io,1561 +aiohttp/abc.py,sha256=0FhHtbb3W7wRNtJISACN1teP8LZ49553v5Xoh5zNAFQ,5505 +aiohttp/base_protocol.py,sha256=5JUyuIGwKf7sFhf0YLAnk36_hkSIxBnP4hN09RdMGGk,2741 +aiohttp/client.py,sha256=MasEUwsbJI6OKfPPT7ogmMqqjjye9_6tIrqDJoKEUIc,45872 +aiohttp/client_exceptions.py,sha256=tiaUIb2xy3s-O-KTPVL6L_P0rpGQT0rV1dujwwgJKoI,9270 +aiohttp/client_proto.py,sha256=c4TAK8CVdycukenCJj7LtlQ3SEj04ilJ3DfmN3kPgeE,8170 +aiohttp/client_reqrep.py,sha256=AlEa1SzB6BpMcvfqCkSO2OkjRpThyHlRDpsocGhUQDo,37151 +aiohttp/client_ws.py,sha256=Sc0u3S-vZMadtEO6JpbLhVVw7KgtlsgZWHwaSYjkN0I,10516 +aiohttp/connector.py,sha256=1itHerlRDWpyCqcJGKvoKijCg3gC0OaI28qFwWor7Go,51367 +aiohttp/cookiejar.py,sha256=iJW-DtJuMmOW7I_OdT65U1MRmc1dVQNpNZ0QWI1r89g,13768 +aiohttp/formdata.py,sha256=q2gpeiM9NFsl_eSFVxHZ7Qez6RbM8_BujERMkooQkx0,6106 +aiohttp/hdrs.py,sha256=owNRw0dgodeDWyobBVLkY88dLbkNoM20czE9xm40oDE,4724 +aiohttp/helpers.py,sha256=yS8PJca6UopZBl3jsLlVsV-qHuUKG6Wrga7mzkuf_3s,26527 +aiohttp/http.py,sha256=_B20NZc113uNtg0jabY-x4_3RrIpTsqmbRIwMcm-Bco,1800 +aiohttp/http_exceptions.py,sha256=2KqKKgLOZiRvWTJO60TQcrYD79taBcck2Q7WoMuiVYo,2715 +aiohttp/http_parser.py,sha256=1WlZbVIaxsnBmTbspZKYaIUDrDuxRbqIhIVmZ0LCe9c,35434 +aiohttp/http_websocket.py,sha256=X6kzIgu0-wRLU9yQxP4iH-Hv_36uVjTCOmF2HgpZLlk,25299 +aiohttp/http_writer.py,sha256=PGQjDjtLCluVuxao1Vef8SN9lJFO8joASSHbHipTGgQ,5933 +aiohttp/locks.py,sha256=wRYFo1U82LwBBdqwU24JEPaoTAlKaaJd2FtfDKhkTb4,1136 +aiohttp/log.py,sha256=BbNKx9e3VMIm0xYjZI0IcBBoS7wjdeIeSaiJE7-qK2g,325 +aiohttp/multipart.py,sha256=gmqFziP4ou8ZuoAOibOjoW7OJOsURzI5gkxoLPARQy8,32313 +aiohttp/payload.py,sha256=tx2XE25Auoz22haty49YsuSN8-7ApxObwl9Js2zLlB8,13632 +aiohttp/payload_streamer.py,sha256=3WmZ77SQ4dc8aKU6i2ZAb8L7FPdesCSoqRonSVOd_kE,2112 +aiohttp/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 +aiohttp/pytest_plugin.py,sha256=4-5LfdrnZIBP2wLp8CjE54eshOolFbBpOTufvp4tUcI,11772 +aiohttp/resolver.py,sha256=CASOnXp5oZh_1sCFWzFlD-5x3V49HAXbAJw-5RYjgms,5092 +aiohttp/streams.py,sha256=_OTvFQVA8-8GJ120Y95lH-hmLq1QaFNBFdaA49TECIc,20758 +aiohttp/tcp_helpers.py,sha256=BSadqVWaBpMFDRWnhaaR941N9MiDZ7bdTrxgCb0CW-M,961 +aiohttp/test_utils.py,sha256=MNQb4Zq6rKLLC3PABy5hIjONlsoxd-lc3OirNGHIJS4,21434 +aiohttp/tracing.py,sha256=gn_O9btTDB66nQ1wJWT3N2gEsO5kYFSIynnd8cp4YgA,15177 +aiohttp/typedefs.py,sha256=oLnG3fxcBEdu4kIzUi0Npcg5kjq01cRkK27VSgjNnmw,1766 +aiohttp/web.py,sha256=bAhkE0oeP6eI06ohkBoPu4ZLchctpEz23cVym_JECSg,18081 +aiohttp/web_app.py,sha256=QkVmy8pR_oaJ3od2fYfSfjzfZ8oGEPg9FPW_d0r2THo,17170 +aiohttp/web_exceptions.py,sha256=T_ghTJB_hnPkoWa3qyeY_GtVbehYQwPCpcCRb-072N0,10098 +aiohttp/web_fileresponse.py,sha256=F_xRvYFL2ox4oVNW3WSjwQ6LmVpkkYM8MPxsqiNsfUg,10784 +aiohttp/web_log.py,sha256=OH-C5shv59-nXchWX8owfLfToMxVdtj0PuK3uGIGEJQ,7557 +aiohttp/web_middlewares.py,sha256=nnllFgxX9GjvkG3YW43jPDH7C03iCfyMBxhYw-OkTI0,4137 +aiohttp/web_protocol.py,sha256=EFr0sy29rW7ffRz-tlRlBnHogmlyt6YvaJP6X1Sg3i8,22399 +aiohttp/web_request.py,sha256=t0RvF_yOJG6uq9-nZjmwXjfqc9Mvgpc3sXUxC67uGvw,28187 +aiohttp/web_response.py,sha256=7WTmyeXY2DrWAhr9HWuxY1SecgxiO_QwRql86PSUS-U,27471 +aiohttp/web_routedef.py,sha256=EFk3v1dcFnLimTT5z0JSBO3PShF0w9sIzfK9iJd-LNs,6152 +aiohttp/web_runner.py,sha256=EzxH4v1lntydU3W-c6iLgDu5LI7kAyD7sAmkz6W5-9g,11157 +aiohttp/web_server.py,sha256=EA1YUxv_4szhpaED1O_VVCUFHNhPUJhl2Cq7W1BK72s,2050 +aiohttp/web_urldispatcher.py,sha256=IAvlOBqCPLjasMnYtCwSqbhj-j1JTQRRHFnNvMFd4d4,39483 +aiohttp/web_ws.py,sha256=8Qmp_zH-F7t9V4NLRFwfoTBr4oWuo3cZrnYT-i-zBI0,17144 +aiohttp/worker.py,sha256=-o-cEhGcUqAG5LhZzO182UTXzAARWwxT0Licd6HHv-w,8755 diff --git a/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/WHEEL new file mode 100644 index 0000000..b161278 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp37-cp37m-linux_armv7l + diff --git a/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/top_level.txt new file mode 100644 index 0000000..ee4ba4f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp-3.8.6.dist-info/top_level.txt @@ -0,0 +1 @@ +aiohttp diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_cparser.pxd.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_cparser.pxd.hash new file mode 100644 index 0000000..65e3d4b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_cparser.pxd.hash @@ -0,0 +1 @@ +f2318883e549f69de597009a914603b0f1b10381e265ef5d98af499ad973fb98 /home/runner/work/aiohttp/aiohttp/aiohttp/_cparser.pxd diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_find_header.pxd.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_find_header.pxd.hash new file mode 100644 index 0000000..f006c2d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_find_header.pxd.hash @@ -0,0 +1 @@ +d067f01423cddb3c442933b5fcc039b18ab651fcec1bc91c577693aafc25cf78 /home/runner/work/aiohttp/aiohttp/aiohttp/_find_header.pxd diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyi.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyi.hash new file mode 100644 index 0000000..6a30d63 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyi.hash @@ -0,0 +1 @@ +6682a22524b9d4fc442e123672622be7bdfb6238d9709b7b15b2113b7ca6d52b /home/runner/work/aiohttp/aiohttp/aiohttp/_helpers.pyi diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyx.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyx.hash new file mode 100644 index 0000000..8f38727 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_helpers.pyx.hash @@ -0,0 +1 @@ +5de2db35fb795ffe227e2f1007c8ba4f2ad1b9aca28cc48edc80c779203cf6e3 /home/runner/work/aiohttp/aiohttp/aiohttp/_helpers.pyx diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_parser.pyx.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_parser.pyx.hash new file mode 100644 index 0000000..8e5a141 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_parser.pyx.hash @@ -0,0 +1 @@ +7f32b0c1595c1a71957a218ece8d3977ed9171caad97df8fcd82aa80addfc5d2 /home/runner/work/aiohttp/aiohttp/aiohttp/_http_parser.pyx diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_writer.pyx.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_writer.pyx.hash new file mode 100644 index 0000000..8e1aaab --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_http_writer.pyx.hash @@ -0,0 +1 @@ +6881c0a7c838655e646c645d99971efaf5e310bc3633a7c62b226e39d81842ac /home/runner/work/aiohttp/aiohttp/aiohttp/_http_writer.pyx diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/_websocket.pyx.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_websocket.pyx.hash new file mode 100644 index 0000000..ddbb4c7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/_websocket.pyx.hash @@ -0,0 +1 @@ +d57b8e48d0c26f20ebcc5e6e300da2b2a6aeb12b3c9768d64cb0e53432ccf48a /home/runner/work/aiohttp/aiohttp/aiohttp/_websocket.pyx diff --git a/.venv/lib/python3.7/site-packages/aiohttp/.hash/hdrs.py.hash b/.venv/lib/python3.7/site-packages/aiohttp/.hash/hdrs.py.hash new file mode 100644 index 0000000..1c8653f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/.hash/hdrs.py.hash @@ -0,0 +1 @@ +a30351c34760a1d7835b2a1b0552e463cf1d2db90da0cdb473313dc66e34a031 /home/runner/work/aiohttp/aiohttp/aiohttp/hdrs.py diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__init__.py b/.venv/lib/python3.7/site-packages/aiohttp/__init__.py new file mode 100644 index 0000000..8bc7a4a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/__init__.py @@ -0,0 +1,216 @@ +__version__ = "3.8.6" + +from typing import Tuple + +from . import hdrs as hdrs +from .client import ( + BaseConnector as BaseConnector, + ClientConnectionError as ClientConnectionError, + ClientConnectorCertificateError as ClientConnectorCertificateError, + ClientConnectorError as ClientConnectorError, + ClientConnectorSSLError as ClientConnectorSSLError, + ClientError as ClientError, + ClientHttpProxyError as ClientHttpProxyError, + ClientOSError as ClientOSError, + ClientPayloadError as ClientPayloadError, + ClientProxyConnectionError as ClientProxyConnectionError, + ClientRequest as ClientRequest, + ClientResponse as ClientResponse, + ClientResponseError as ClientResponseError, + ClientSession as ClientSession, + ClientSSLError as ClientSSLError, + ClientTimeout as ClientTimeout, + ClientWebSocketResponse as ClientWebSocketResponse, + ContentTypeError as ContentTypeError, + Fingerprint as Fingerprint, + InvalidURL as InvalidURL, + NamedPipeConnector as NamedPipeConnector, + RequestInfo as RequestInfo, + ServerConnectionError as ServerConnectionError, + ServerDisconnectedError as ServerDisconnectedError, + ServerFingerprintMismatch as ServerFingerprintMismatch, + ServerTimeoutError as ServerTimeoutError, + TCPConnector as TCPConnector, + TooManyRedirects as TooManyRedirects, + UnixConnector as UnixConnector, + WSServerHandshakeError as WSServerHandshakeError, + request as request, +) +from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar +from .formdata import FormData as FormData +from .helpers import BasicAuth, ChainMapProxy, ETag +from .http import ( + HttpVersion as HttpVersion, + HttpVersion10 as HttpVersion10, + HttpVersion11 as HttpVersion11, + WebSocketError as WebSocketError, + WSCloseCode as WSCloseCode, + WSMessage as WSMessage, + WSMsgType as WSMsgType, +) +from .multipart import ( + BadContentDispositionHeader as BadContentDispositionHeader, + BadContentDispositionParam as BadContentDispositionParam, + BodyPartReader as BodyPartReader, + MultipartReader as MultipartReader, + MultipartWriter as MultipartWriter, + content_disposition_filename as content_disposition_filename, + parse_content_disposition as parse_content_disposition, +) +from .payload import ( + PAYLOAD_REGISTRY as PAYLOAD_REGISTRY, + AsyncIterablePayload as AsyncIterablePayload, + BufferedReaderPayload as BufferedReaderPayload, + BytesIOPayload as BytesIOPayload, + BytesPayload as BytesPayload, + IOBasePayload as IOBasePayload, + JsonPayload as JsonPayload, + Payload as Payload, + StringIOPayload as StringIOPayload, + StringPayload as StringPayload, + TextIOPayload as TextIOPayload, + get_payload as get_payload, + payload_type as payload_type, +) +from .payload_streamer import streamer as streamer +from .resolver import ( + AsyncResolver as AsyncResolver, + DefaultResolver as DefaultResolver, + ThreadedResolver as ThreadedResolver, +) +from .streams import ( + EMPTY_PAYLOAD as EMPTY_PAYLOAD, + DataQueue as DataQueue, + EofStream as EofStream, + FlowControlDataQueue as FlowControlDataQueue, + StreamReader as StreamReader, +) +from .tracing import ( + TraceConfig as TraceConfig, + TraceConnectionCreateEndParams as TraceConnectionCreateEndParams, + TraceConnectionCreateStartParams as TraceConnectionCreateStartParams, + TraceConnectionQueuedEndParams as TraceConnectionQueuedEndParams, + TraceConnectionQueuedStartParams as TraceConnectionQueuedStartParams, + TraceConnectionReuseconnParams as TraceConnectionReuseconnParams, + TraceDnsCacheHitParams as TraceDnsCacheHitParams, + TraceDnsCacheMissParams as TraceDnsCacheMissParams, + TraceDnsResolveHostEndParams as TraceDnsResolveHostEndParams, + TraceDnsResolveHostStartParams as TraceDnsResolveHostStartParams, + TraceRequestChunkSentParams as TraceRequestChunkSentParams, + TraceRequestEndParams as TraceRequestEndParams, + TraceRequestExceptionParams as TraceRequestExceptionParams, + TraceRequestRedirectParams as TraceRequestRedirectParams, + TraceRequestStartParams as TraceRequestStartParams, + TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams, +) + +__all__: Tuple[str, ...] = ( + "hdrs", + # client + "BaseConnector", + "ClientConnectionError", + "ClientConnectorCertificateError", + "ClientConnectorError", + "ClientConnectorSSLError", + "ClientError", + "ClientHttpProxyError", + "ClientOSError", + "ClientPayloadError", + "ClientProxyConnectionError", + "ClientResponse", + "ClientRequest", + "ClientResponseError", + "ClientSSLError", + "ClientSession", + "ClientTimeout", + "ClientWebSocketResponse", + "ContentTypeError", + "Fingerprint", + "InvalidURL", + "RequestInfo", + "ServerConnectionError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ServerTimeoutError", + "TCPConnector", + "TooManyRedirects", + "UnixConnector", + "NamedPipeConnector", + "WSServerHandshakeError", + "request", + # cookiejar + "CookieJar", + "DummyCookieJar", + # formdata + "FormData", + # helpers + "BasicAuth", + "ChainMapProxy", + "ETag", + # http + "HttpVersion", + "HttpVersion10", + "HttpVersion11", + "WSMsgType", + "WSCloseCode", + "WSMessage", + "WebSocketError", + # multipart + "BadContentDispositionHeader", + "BadContentDispositionParam", + "BodyPartReader", + "MultipartReader", + "MultipartWriter", + "content_disposition_filename", + "parse_content_disposition", + # payload + "AsyncIterablePayload", + "BufferedReaderPayload", + "BytesIOPayload", + "BytesPayload", + "IOBasePayload", + "JsonPayload", + "PAYLOAD_REGISTRY", + "Payload", + "StringIOPayload", + "StringPayload", + "TextIOPayload", + "get_payload", + "payload_type", + # payload_streamer + "streamer", + # resolver + "AsyncResolver", + "DefaultResolver", + "ThreadedResolver", + # streams + "DataQueue", + "EMPTY_PAYLOAD", + "EofStream", + "FlowControlDataQueue", + "StreamReader", + # tracing + "TraceConfig", + "TraceConnectionCreateEndParams", + "TraceConnectionCreateStartParams", + "TraceConnectionQueuedEndParams", + "TraceConnectionQueuedStartParams", + "TraceConnectionReuseconnParams", + "TraceDnsCacheHitParams", + "TraceDnsCacheMissParams", + "TraceDnsResolveHostEndParams", + "TraceDnsResolveHostStartParams", + "TraceRequestChunkSentParams", + "TraceRequestEndParams", + "TraceRequestExceptionParams", + "TraceRequestRedirectParams", + "TraceRequestStartParams", + "TraceResponseChunkReceivedParams", +) + +try: + from .worker import GunicornUVLoopWebWorker, GunicornWebWorker + + __all__ += ("GunicornWebWorker", "GunicornUVLoopWebWorker") +except ImportError: # pragma: no cover + pass diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d53ec1d9794722939eb4edcf23f41e3dd44c8fc9 GIT binary patch literal 3655 zcmb`JTT|Oe7RO}=Fvd0*Fc2;YBw>>ABtQruS8@S!GlAgP28WZ2qF8NPgO22F$(gWk zTeTlx-}W=?7uv1r*L|9=uut2kC1ap6si~=f;z##6-ACPh{yMF-RH{#tKmYvOf9n69 z(6s+jr~T6_8!zRbcQdMK2b!sYW=71Y9lBbs^1?6NOm7j&t1x803B(1S6EVK4Mz z9OBpqeVBj*CLxI_NMS$p;{Xg`8qzojgE$03I1Iy>feeno2#&%ij=>mShRZk(<2V5m zI0=(D1ygthuHaR;iqkNSGcbeK;2K_s>v#ih;4I9lHT2j&;7z!Rx8RoQ$Lt?53t83f zwSU6fa2xNy9h`$XWsBSMxBv@y7w+OBEaE-5hfA=8_u)P+!?GIFXFtG)@DLxtBYX^x z@d-S^r|=Y4U5Jkq6sE4U|541)}f9KXvjEeuvnD+Y!23< z;~G0QhgP(cDVg12+eQRL2b_q;EHm>^1FNDrqg@(vkNf@+wArtbpx4zfxtE<5sWro6IoEMm)pxlV$=Mcj{Lo;z&Iaew zJbljW@*Ly7RkNyw&w>G&3j+e{*ad5;v>P}Qf#clVZQpMexcl`au%?0``=y{e6m$#5 ziR~I@V4DbSH0k1s!|6r#mlpGU(H{&gGOy`69uvdo`{y26VxA{=-kx*1=rCm2Lgu!7 z5pJ%+K9}6;G4oGjr{!9Fd5GncW_UV@P0Oh>-sG0!i@v<`#jq{&ptviBUK_~Fg4H~e zf<(CHyi;?^ND@6~fpu z%jvS~?itQWk(m~kdhkT*z_Gq|28>opL6B|3F};Ry9PTg1gJaG{MLg%a#}?Z$xaePR zA1nqHj}BjZo58K&GDrAi)T)AcN0rhS_k zCgWn_o6ds44HW%ru6ZJxGUaOQz+TJtt>(836>j-5+LTNaJx4b?57KLv%^aD3F)pWi zO#jB1Y)YgHt4F*0tLu7kV=G@O7mq|{)jM&jc^TLEY_sr<5F=}?T8(jL28(K&``1o< z=H>U>{iN!*d#U_Bz5nfQV#jlxb|=ClEFo0({_KM%yQT63`hpv;CQlWktlPcO7C6Gs*9`b4%I=af}9K_ zYnx-LjC*3{oBon7a~_Vk7(uPd{Ot&V|9cUNtmQE&3Yih9I!}zMHLN>c&Zsunw$*;} z*g3m=-@S0cRNE0A;I`}eodpF8mf_BL&n{mJpLsMZxtMw5}hUrR@lkxXPZ XJ{w;dkge{i*mfpUk4Dncn~wY+byrJ| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/abc.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/abc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d3c5fe8a3eb016f114ecdae7ae69c271e0d87c4 GIT binary patch literal 8597 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/base_protocol.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/base_protocol.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1be8bb2e1465e2eeb5d07a4a77253a0de40d087c GIT binary patch literal 2777 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 bJBIonPY?HW^|ZF{T+8B7AEw6t8{z*4rbwUh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_exceptions.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c393d68f41c32580f60c0842c7546c72222bc37 GIT binary patch literal 11332 zcmcIqONjarn)a^*L{Ac#1-#zJhNiiiqq(|kG;~Mj zui+T@nhmpQIaV{~#F}v@-b^@&X3|OOnrpeSMyi>1(wvVsCYl*1qiY)l?wxhABD^W1c10Z+IYz!@-d)<8~*(VMIgAI7U zdjRkOVFNw__@H|T@F9ke0zT~8fNgOQ^~V4oagPE%Dvkj@4)~aR9Pn{*Oz5lc0LKZG zz2lxh*$HlQ67Wg)6yQ@#)hWP5_cY+sVpbH<<1|X%b>~nr$5`JLS=V@&`a@m*H+EsJ zraNZ@%8)ah629{ℑ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 sc#V{gs?s9x2cB)jBa^-M2 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 U@EDtqY)`{39!q~qi2s)UFE2q_g8%>k literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_ws.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/client_ws.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8f631c408dd35cbf86449a8122dfea6b92a40b0 GIT binary patch literal 8823 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 KR5ML*JpDh7Rre79 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/connector.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/connector.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1f60717d6bef5336b79ca5ffe819f43906b2edc GIT binary patch literal 35246 zcmeHwdz2j6SzlN6yQin;q0wkG(n`HrtyZIzMz8fgWUV|}Jyx>iku1&bddryJ)>O?* zkNPpXRU>Jdo;6;rF&K7PI2;VNNJhi~^9mfF@CXpV*bqa=;dMedm0*Z5Iawc)@Jxt9 zNPfTXR#iV{W-)Mb!XM0>zE$_uy|?b`dw=)VGyVO!82&!`!GAaZy`PK4exH%>FN2#Y z{M@T%EM~`SqZ+gH)vyeSo0cipxD}Uc!b-?BX(e$rtEpPrO4l-0#$dU4HCxMBIk`_% z`)YYBFZao6f308@Y6I4Q#8cJ5+K@FQ_vz|zZHu)K!B_FMbqK3|=v9k3469DnplRP7zsJLLIbb*gsSIxY7@)n{sFtTS>yTs>PmXPq-*E5kCP=dJV3`Ne0gXJ3fb zcO_!Zg&Vmy4E0GP#(&$u(~H)#FUIQTdt>$%>z&S4JpFC-ZKV3H+9m6f)VUSyd$;v& zxgV`g*DhO^jo7m>dz(G>YRn$HYg$(j+is5|HjdbP5ZhtzL~JKwR}p)_-i6pM#I7N> z+b$wjL~I7J2kkwG?QyQ%ja$zl{*b*F@x2m%9`T3meTeUq_zSjiEjIDUn_Owr6QiDUOTdmA8 zbGFu~H@rr@GK)z6j4IDM*UPgvW>%J*i2@Q{ymGE|=EAu%@47hstRFvJU-7f2Z9$>q)(K?NV3v3!b-hMK$iM=+tqY zT~c~mu>G2&(8TkV`n;o-RHg2{yW-Z$-t2-uhR)vUd6TZNZx-z=IqZV#=UlfM+@tdY z==4&f?m8FBb-Rkb$Nhd?$5l={#<#EIUH(w1=BRn6#5$JBs$6p?QhxHvi>2d_`}tX? zQZ0Fvn$uYJ{K0w0E2-sr9W52l4n zuT+-W1yE_w;Thd>Nr>kCUCs&;lCpqj2_NBK95++=xeS~bF)*;NVa1(j1j2l(5=f03={8Og~pDx1mDc zJ2pWy+fGj@$6HqQSx^P}1!T1G2Y0#-tZR^n~u^!W)>y&aF#NdyE6*Qw5_ zrxE$Sn3}@n%a0%SYDE zpDpRJDV0#yJ5XHupo7zlax9+1uic=X8#YKrwN&bA3i}{qIf@%JBIXWzXozii@%tvQ zw{B4LY_#eoXR8g@**{UNxW#gDwxIwISmFnZKulPx#bx~DMR*o0+px$)LVD$AZkH7y z2VlZGf4FOL$fJ#W>ZeO3+o_gHFS55}894k2!!(=Y8}?W-Ph>f7bpS`Hgf&;HHSFao z@AIY7&E;}6c!FVes}0XBl~f)Tt3C$LFyQ#8XBkX&2QvC6kT#8G$fO3*fYB6macH&;r21pTnoUEM&FlFp4VmYU8&T#U`kpuAc z+4)zKR=-n_Qq0wF7hX-=HLL-o4I*_2fXeg%dr;DcC7s~Q)FFFVQnxrG^8lYY6X}M% z1vQV@Tk*E7h%w)&y$!L^AU0-iM{HXV8@G2LHimk)OWvLK15)R>klbB z{Z>yRm`M8BXl?lM8xG)VNr9fuHmZJt*i=JI5_$Q@D}S;~3DPZ-ATNM#v=X>CTXBT( zc`V>kqLo-n-p8A~)LPohtYvNEKK}6}7c6EqhB|6g3A=fgMQP zT|Y~tZ#&nQ=lv{6s?dDD-?=07wFEped&7^rE67=6*#V-G5#%OM7kL_FHnm9_z$gvLMn#I`1fxy2j z4pbSRZuYgSIr(Md6yT1iZ4>YV7%AZKQt3AGxWrBZ;FmifA2u!NrDDb6TjfE$Dv zsVQzJUW+piVd$Q@ij}dLmHIv2wc>XAq^=>?ir+_VvMMsueo9YNbL6?Ypg223U|7Ay z8PLhRyUaOU|8HM>xjPLcsDQ^lJNR=1JYaoB-{n zvE)6j+bN{#K-L>^ToXT+5E3(TK&?45VT|(595r*e=8WcWd&yws35x9^DbehbqDdERl5HeRvf{3+~QH5Zop*Lu~0VYLe zP7pyIJf`wCdH)Sm_pSH^@8^&^gQw4lp(HNprR!B%rw>z5kx(oNn(Eb<+ElR%o; zg&;zF2Dr?G2(23|Stvpkoc}8C>}u@2v70-2uLm)%*my-e8YoGS^NU5k%(x0tP7Oxi|ItIg@K(Wy-vtvj_Lr|YK!y!X%8c2Oo7Y506R~Vs}YoAZwzsMO5@}oXJZ1O8|ocGdt!&WfDGy)gLg6zbe$tZ zpdnxFL#m%HyDRnCO2Z!tC3cY!FOePM;s!+_M3zqJ%~;z||l z)*^eXr0P^)aMWi$D6ZVrxdo-x~Dfl zKaG?_n2A$pJKBt%$L)8Zwki8GMtrj4Ek$|DGxiyjIBb(YIw#^%`L{9GT;3roiq$?_ zExYbyE?30g4aZq3S1Y$5U1;@A@lbJpBhVO56yJr%hva!Ncs?n`05lLt1bLwV^om8V zQJhiB4zKbMZ-J0s1PfWT8$~E?G$xeNd~taW8l0k2o?XC0(WDjkGxK%FyX`o2B-#~} z^4tmi#%iTj@$jyh1-=6cmtuXnb{$nT=8A5m1}#{*4#k=q_7iL~`p7p)$r8|8X`$h= zis`?$AbZiMJ4F`Il{j_kThU{uTwh)aSZUOCPSWvKJ~*_zq`Pewp#UsK=s9Qz8?({h z*^0}`(f1Xwt)f{DT27|+P%%{C7QwpKy(0Nd{d{Jcq81+Or;%ivW8A7XHYL4+X5Z>I5!*puHvq-CmIEzOu5 zXc->a!UGx&v^oG3QmT{M|{uYt=NAPT`JR5DLkh;wqTiouAw^DZU zHRjsk?UXtm5H@L-gu7eGJnJorZs0+%Eqlml3Cd4RHy>X&)Wz9y9XuXZa?u4~ROU25 z1keJ}gm4l}+~m}GtxGWUC_khQW3>F-^X2NYR++1VOh^YSPCbv9dV#@v8BmL*EC#|7 zq=eyc{ZvU$@PNKXiys^SOaR$ZdG_WqpvzVyMo_JW@hGF(#s|r{YNPDo`MN$r@zt@O z6sa;qN~&UEGYBM3A)nw1AS^-^?p4ZF&8B2Zb1)_})QaK~p(IHoiR%wU(4_@We>6(a zTv8yA`eVK6b^t*Bc<+-o2zFGjYr~2bnd7aO^%R<@N$qLgJ%fPj*?kN_tS?~G9h=Zw6Oisuj?G&Av3oKK>mlJhh8xnGX} zJaJ5k5{lfhJHkas&i++C5#{gM7=Q;$c`eRG>Lt`E0ut0AaZ!iFp$-9=57Z$ks6*mf z9nvyM_V2}4DJ`T$Zo9*~Rw7V#Kn>Oc@I}gwh%x38Vk0R*yCVn)C-2V#k|6-zHNM5X znYgBh5Hfgz${mQ1=HwCInC;^(vrw&EZ~UO9QqXMGczY7tkh>3{^&ox{hEXr#{Skj=P__MSvt=$>M3N zTNF7g0X|vvYK|oX^&BS@mOl_aR}tRT0)we2kQMbTqJ8Xa5jR>F4SlpZg7p-rPE7L2 zlu@8K*}CCSY{Z{N>t+zudXT@VLb(rpe2Y?wIo-Ul=XS+gD4q#bDElW)?CDmV928Cb z9+4`F8)b&!!ztSs#ir1pf8ghuNv#^ZS|`dJF{ ztQ#RgSe=Te=F#V>U?5=!uC4@}VH@bcYJuIOHWC&c(n}J^NwoJ3G-cy)6+Q$m3&GsQ zo7=kww1YT(1&#ZbbxbA7zXewrF|iltG@rANmtT*&?&90I6Z?UA$T(`n#?e}=E4|J zgtBg_0jqi-KCnyYf+QI86nOJ6C*~3NE0VZSzJ;Q+ltn|gpS(3pe$aa!ME7Yip8&^P zfeo;07(TN3FuaOK&vp#M&JBhk;%K7rpw@#+Q`RWFdjKsUs-q0o4B_lVCy2O7B1#S6 zVuB=fF{!=;ivmb!%N&cXChmMc)7Db=W6&Mm`zmuaxtf}ft)}n1(n=wviImK0wv|~+ zgMN>SL|UVrDgmCs|S1B^Pt*lc=lDWtd;td&-0TWN5|$&<00XAvi#oJ6i99BoowVQm1`jW~JYMe{!GUtl9Z z77|cCY6+*fT!$If?v!DsMY;g$41}PGLG|qzN9eH1^;xH?xxNI&MD@)`*Mu_(j-_T;ck85;rk0YPoodszBT&z^si> zIfX0OI0*~pAf7Nj2-2Jf*#g_Qo@xZ6qwSP&X__Ag64y98&R5}&tR3%V6_T06Oz5>0 zzmZmOqJmWlD{VX08LW|5aa;kdgnNYfTE^3%$_Yg7HI(+@ANG#7hw>;+*eVWb5px*`l>`7$O(yN(4MZ@zrCu?%6Fhn0Zo585ZJW_5ZiUtxB;~T<#tzGh}>eWyix=-0Cl;I*&7h$U|p&UBLs(qz}OU4 zMnuTJY4tJmZX&Bbii`R|23+4*m)C*m^n&LyS3knkbrKG=6qSaptxxB-d{9fu7k3)}&@$?Pyj|gD?)V2-}PUz8R3Sj>3qZV;iP?NaZgkBTuKgt#h(<0XA?luZv9kq<$K?YG;_C?%qrD(~A z=G{`P`5j0RiANO$SYnHDMc{~2VIX#pq?$rJspEGJ;vVLFLDsugjXPLfSZ#wq(lqdz zYZ;ch3DkM>(hIRWBnMeM&jay?&u$@|t28I86ksV*((3@vJ}LY93t}#k_vC{%WY@yG zetjn@1t8RTZ* z8#fZT3X5}+GXiv-{3~=irU?tXJI*} zwTdh)EU_Q2I(5D5$r@_v7l*TqUpVaob4Sjop`gP_hC5(5CRQdSh`l6mv=n6u?RFfv zU*baAiArMGlsT9n2S98~E~3=B01s)aQ)Y zDxBh*C&Txsf4)Mqr>;GtYe)VOYW-W#McC93U9 zVO?%;_cSc-Et9?JYHzNiy?+6&Hns-cFUBF;$^zIjZvwj_XpG2c47Y24!yqYG0YO>YLVh29K5;!Rcvoz31ZD5FvTIw3=DkrH zfXzPEr}TK?>F4zb=)CT4OG`3gOV+lb=Q*v6SsP;=uW(fMpwFz^ba@?E+bF+@K7Ire zhGvyGhub?^ZQjhI6*fi=xxUho=o*9ZuG%b)@g^B2(0l< zilH*N{Q=*Iid;0>VrdnWTwoyNU07~n?49-UWIC8*6ikWaXKqOa4qm4c4cZiWd#BN?h?D$9M1bNz%|)~_1C(U|W$n=b zOFm4%Pz(R@J0F4R>LY}6{&j8 zW!Sft*C_JlkF`wqBl`VM14ORHZXVg7B>C8!heAoC{gB#H-9=}O7w0T$1Os-Rz-Mr6$2|5G$dXHm<(oO@I)~71(0eJW6gmx(5UgMTk6wJ;sW#x?&dSSTh$c(riCQsYE;=x0hmASlm$HHw;SSAR zKnY+=m@nYcV>fDk+Fe+lo5OY%;!l|88qm7UArshb$I8J*2(-hEC4mfKr37cXTA7g! z2Eb40n;x{Fei?Os71svkT)G@55(NN#4y(eXdWB#O5MC#wc4ImSma-rzxOA&d;z)@g z`T`=HX)PPB?8H5!!a!XDD;SA432gxB2|)S@4e21bIYRnck_1@fFJpQlrO~j6RYDAi zhSjezV875R(Vn-PHpNF0oW>oTwZm?NZ00Qv#UP$RumU)k01yaM&@?r7_kcogNk}&@ zp%@rhdEI5)OG0}%fOti%5~)_GaA*$)ItOKn9ss185S2wRaSyai2ryR>CIAqo9s(e( zl;|PTqKAwOeszjJIdEDOYshiZo7J0#tb`bzvSOhKP{g~EQA_kvVa zE=((IhL}ebHsTKp|M3~o!%Yn9f&cgH-x6^N`cps4%pxum^J#H8(y)jo5|i4V zwDu@U-QUeJQ&GS<6z9hean|-Ah6RjSBLzz6#Vcq{Be@ZzY@h)Q=5aRU;(6sv2^XKk zjTgHcdj;MQRIk7;<8PU6co(@}utrmntv7Q8cA6e)J%!@!<)(fK(eGhX@q^^r?D1q< z&t+i1r>7^5^!S&l53pKF)Y_E!le|03U=)F$YFu9goma0jWtAy$2!e_lBXx(t3WH}D zoMq6*;8_O$guy>$@I4H+G9VFF^hHzO&){nqyu#ovgI5{+0E2xD1pKJ((mQH|hTUhB z<^o_o*8?!x%+2k6w7zh}A!>|Vd-fq~>Lw`KP;gJW=F8Ja(+`|L120y%h z+!uH+r84*6jVD{?2HLq$TOUg2?S7OVM63W$GTF^z4YhOi)Ws6Ax5pap$di_uwCCOy zA(Nwip>%fo+8Ow8IWzQN;>NqU=LM>6S(4}>ul$|C&*gd&*Bu=aJz?`r2nuofrhtQX zOG^2DqPYjZTwB66uM+AFExNylN;;-fX7U-N{SaQ`5*Jd31z(G8-OX!na^Wsln4dHv zW!w12D}T~Xf+^d!7`u@Qz*PN5q=ilRBJO*dz|CObKD{!id8za%wneIz&3&E2gm$#^ z1#}JyV)na@+EKq~qT;wpi^yrgr2-l#@InaTyFme*$d}rv{a%8uON&XSgyWe~91Zm| z4A^@0`wU1t)fW(SQM3QV)Tti4@`5Ur!AtTjYO0#ws${@ zuniPYv~rrtcxoW-V$xR=9+cI0!L(9%AoU2w>NinLr4eA?Ft+7%*@3PwIR&-Zytkk> zm}Wo6A{y|1f$io3iIJtJo_>2z+uM1g4sZaYLEMW7J0PULKtzEUrhU7lZi~^fa6@am z&tn0~iu?k~$g&Kmg}9U~kuX>~Uw8y#wju>TT_YQ^A94du(jNL))|V zE)cHWIOPFbSn=+MP)f$aeh}$31$36^fY#j&EIHhQBE*}PV!dU>J2#Gy(+9ModF1IJq5W3E@8-#xLhS*4XVuC)| zK^qr}_=6Z59=d>{SKwq$oqzFqrCwGmMR%cm>}`)n;;mho$LR_5-ew-aEEr5k!0meB z6jLvrJ$IGHTbOYv2kWLqRfs&y(w&7E*9KgejU1kyKtnFhe{kGMII6<{QFR+p72K!q zo;ZBisZZXn+`zd9cBMSoQ1gcwJ3JHafGJ%nufTEbnlrnsD&ERNXQJLarKO6T;UHDw zg>phh@kAZtT_qKZrmA26%EF$IUu3&?Em?cYvN}faR8VvgwKAl8E zc1M-kPy)`VtJJ&8cQ6ECF>Dv=f?IT|lG4yGNMVeLS~*ypra}T0!mAu}FB4dTBg&{jEZ406Pj(Fxr@Kk20_cz`RTM zr#K8qR8^exXh=(9ucR22@FWF2Z>)r40ATNrzeZ^#+wqVU^wiM11*djjM)sb%Z76bYD zJA8f3v!&~p#ieRh^F9RPeh>M zfAXq0%oSZQ9$;j^dJy>@W;4V(Nk1A<_k$h>V zMC6*Ssfo7(R#xLSb^s^T|3oL+CPtAHLlK;Vp#F-%R1|P&`2!*=w(0v`jw`WnEHP*d z)3|0fcXo|$PXX~az{}fj_$=SB&d-2#eg;4HNh~0}cY}Mj@J~ephF&yNsd+8XneNxY zsB#{*<9O%}MP>VaBlJ4IIVlFK1QilN4LH3)KZV{nu3qUXo9ZgNh_Xotjwm^2!mLJ5 zhBO>(ev4Pw#o^81>iaD3VZD#5-{`6jTIr6q{3Pm2qdwNtCtecNJoL3vFb`!~aoFnz z-=Z`<4Kj4s3j6kkQO|k(sG-2UWUL2D7}oM$IEZmPM#aoD(Afrf6r6&G#b;MAZpisc zSI(}HL(YY_7(1Llg7QD#RlaNVQ2vurJ`JsVs+A42Ez;YyAtFT>L!N}E!Y~fyGu0S; zJKzT091BMTeiAvHfMU=qfoC4rc>Xd>CEA;VDa;AK2=OTqV`&=Nf5d>nlG;lcdk`~( z3?7WsvGRzcv|Sln%gXaOT~25XE}y^?i0g-#fk;l!OJMCLM;wqr)~PM`>VF^?ck>I! zZH}#S@&*gQReKlo_uvU{psGa$b z4KuK@!zMv1IPB^A%I#;Puu@12N|C(SDrhGk28k8xIa0M1eO$-Q0?@~BeApN>3po6$ z3x#wwLVGPefkps}5JPl04|HJ>>SUJa*n%YdHBKP zI$w*ngV{6=^rN%*ofU2?l=t!IraLPg9wYwt@QL1%-0>(hEp-ozZK zW{9uhl!}54meFx@3}(RYp*+TEUBI5& z9Pwc4v(2>vZLPGT2dKh)8E1M1j$g*wfGARd7=%NPPoHmo_-h_?S5L@3m@6yZ0-Up9 zO5#zC4)=r8*$3PID%=fSo~I_=!}e#VjuRn^CyPfXkKn&})tNg{3?+BFG3(-7J=P?G z`|-oo%5?>W!(njJlM7z0`Vem}UnxyrE}gmj?khM%@!G}9)8K!}+~Uw9J?X)woJbVO z;gx6f8Atw>D_1YiTt0L8QfcPWwbGeO7tc-4_-VaM-u3%*-N=9ISZCxoyp^ag5lAK? z^s{HqU7bNYrqB6(fz*VP&wBxne82R5S&CG;sfLHEHT+GUJ7bk zDtikqSPGn9gH6QfH|-1%tl;#B>UgSUFTTNnm2m8&)Dial8@NDsVQ6A;c>BZJIf#E6 z?dhL02>g?Xk5ezat9#k@Rs()nfI={Yu%xUp_?^MkrJ@yVI*zSTihIE!evO3;8!!j9 zu~OIV8HQXUp)(&!z*CUhW%X|&Sw4VfU24o% zW+{Hd4@ERlIF69V4ivfKg3;5O3o1yk_`n&%XLAw*CVn2!CgI>h?fEJim3HQ%lDT7K zS)k2sLc4{E^d8HKC(0GR;+T}`oRD?JcoyZla>pl&U`HKwyW%=0qS{!aZbw^6XMOZK z*|;gJoV^Q|LswO(ZU5~Gd|>7s?7E@*UOC#$77Uhn2P>QM0!CG8YrlG;t2W)$_ER=Y zOCQ0|Z19%OX<_HWKXe~6(_PnjP7bw*GR_^9byR{mFSiFjsO@&6{)pGBZJcgyWw~(h zaMmwG1;?H|KLZD4{>!`gdgDM3m&)_P) zTqM~%1`B{^0_;WvoIpi7()Kg0ZK@L$!2|37YhKqk@<6?(#07opP!@ffeWR&_mRmYi z=y0RHbd-YYL_Rny52y_rx>J6Fr_*W7^C>pxK{jljcY=rzlm60DMuF#7@pHd`VC6~L zRu^G6cr0M^KQ^jOfH*@d(MrA^2sYPn9GDgZcqka?;wL~C=~c7;)i>&Ga2EV}IVFtSq`02~n z#6<t$Jfe!5jCE6AIMnRdHd%G9?#+7s}d(tFX_D|wQ(;*ipqk^Ug?a{Qx-Q}6s zz5#D3xE03LL3u99B<(gh5ih@h{#-2s>lVw!6H6;6uu=QOOPxsICGKyg^gx{W(o5n1 zT=J^!{)v}f>R@OuLv4U_xMeS}STKlEDeq@K7)xt|m^4{A9L4dXi(0&r2jg)4=i}N&`mJy*0<7Fdcqy>D<>GF@F|EKH0NC(5l8M^Lp zY0=gd%?38#=xLIkPlDf;iFaTU;xYBqas`u50?Ek-ugOh3%m(J5a~&bW3QiO);9wte2N}OZ!I*W_)A3r=b_fIEMhAZ5 zJet{M01b8z9e(`CV~^z^I8&$KXCvTM+qjl@A_x`B0gH~qE~b#R%?PMRk?D`QAoED4 zuQge6C<1cLecj7(Gf;?@Br0lq&K^L7OH!X38TiN26TWCbMWoRiC`U-^A-m0>scejH z_J&$$2+;zH!FXYpH+NYO9?b-LKzPtS;AVj4!`UaxvQ7NC0hfV#!8cF0;4o-ZEg1+#I^?EjA-?KaXs$tJz1xX|{=XoMH@Tt#ZY5mQBJb0FK3H}5e!yJAkCT`kz&i8O z;P5HltFz2}4uM|?_>bTSXrLdl7#$(-5^Ag+0n#o-fC>;r#e~!z{DV#ET>T|%U|$wU z4zlG4(Br5qmMVZoYVBkSI)enXkY*p^@#aI_0KQ>8AnsASI@m;E*OROsfAqf^z>jTr ze;&QiXlpe|-#8v}i|rs#Lt)QfYNZYaJidrCAtW+UA9i2QKE@dlCqKS%k8HqT%G4dkYl-cXMP`6qD(2)u8x z*U?a;-bgFsZCxC_%e{=F5Cbp@o4vdKb*O8b)b$4H%A&2OyfK~uvY7oi&P~O2yPfm(c32`U_g#J9QL<6LvM*zm10KPjQt@;tW4?8cVB{+RA z2Ujd|(8;wOt+ebFOt+GA#IE_~-WR~?YkXS1UBpu9IHN(1n*v)hNuS~Y?a&h`(yXmi zQ1FyEI2A#A6`TsvJa$H(yvGl0;J7&+tW)mfZ`SRq^2;QD!d~qUuq8ctU;&lG z9%&R7MM>yqG%>MLeH+%e-diY=wP+1?5pXHGsfTz+UPAFWDQ!DV%6XXDB0)>^rjna_ zm}T}ch-5bP2%dOnO*03YyRmga(ljvyjM$I9L>s zaM&2fvt7n8{P-VB@KkM{(+8bGyxGIRN8Cv$3}d2!kBDYEj2xmv5PU@b0v(GD;TPef z1jsq@5v_gP5kr4w+`%Td2;9V-#Sq!EE*!K02RMEY7RQXFoM4Ishl(L_PY&>VHL==q(7NGP9+)d1Ng?@{^KB_)wf_y{ z&PXc<3+IguNo*KTXXyZ za3W4;0zT5U^Gv4lk(7NB4_k=Ku`Nr z#_q~CG6E|s(U@XiabAunhy>&P5nCnO{^a=+%=D*B6R>=c*&k4X5sQ3;58K78j4Iz2 z@*wH~jlQUn!q;u;F1CV)JHpc}!9lfB?n1?>+G>i$hv4a0;^xQbLj%32l2}shVk>@u z!G1;sQ~xES)K1{+6{;fC9wrDH{tn)KCxaS-i6PB|ZG>Dz|0_;dUu1S-U#nki-GP1E zh9(52Z&#h>i$8(qeg>yFUP}Re#TNTpX&hP__Xh0 zS$tb7p*|0|15;VMTF<9?j_V*JNn11gt;6oAm#;=75}JdS(V z*~&-c0O+`BuRI2X{(zukjg(HZ$F0KRE}&I$<7oA-?d~Ww5Fpp0phO%a#ed{^P!M8X zUr9Q^u8Qusl`ru?*1+OJcJcE*{+#zPpTc9Fjx~ec zzE=O@BS_iL)Yc$Ed^+c~BwCliAr~Nn@Q(*6w6h>~LoJN09N`i34%lEDk!xt}QOx=f z+FJw)XM0VGJks7wyPa$$F`?9Y3a&cR6R@Ow%M!-?pb+F?jN&2uCPA8pTO@Xep$h1G zjR&6KpiD6)9^ve?aD;v6szh{;nuF0nopKx>*w=n+z2R39!4l!4fr;`m7)T<0u>t|X z3Z9A!59Q}XiBw`9Ygpe01;NC+3loM_0C3nP*->6{8gp-cjx_;hVJ3pE6XM-+a5C*V zB=S2$JdX@-Ie}<%BJxugJ*(*N;84%w*8}hC&;|wGCc?A$rX6Zgf?f%7phJS1m|^0m zI)s|lVZN=utHp{fP}`BoN?f>nZAN;ivF;;G%)I;D%!Sgk=VsKi%t&0Ty-10I)Psz^ z!ho(bR{!beW-eU5deJ&P1CzXA^y}YDpQ=38vO2_9@V-s68q5#&`K(ETR z(AF5~aTekhXs;pu>$4byHl9a?dOv=G9J&>(G0=-8`BVpwTE=Y|4Y$&ujxyOoXQtQ} z2~P74l3?toNE+4$bnlfT0C2Af3ZLL$0K6d;he{JHyqxoaQ$EPBha?BvYvT#= zeHxC#xY?sJ4A>C8LfeuG&Nl`xHa+oJ@BXh3u*ZiP$gZzp-1*7tD<0gmKF?H^4k$%e2UynCI&?=T>5(Xs29npsWrzlL|h!O#g-{T~LD78Jz=y^l3+7VmbGKIwimaV9pOM^7qxJBE!H9{O~6%@vxHeC@FHLSjBtbE5>x_( zoN~C1YhP_LhoQgr6zT(35%1>HtotzpzX?+8el>0~+d6kfYw4>qtd5SRgT2v7Y#z)F z8sqQ6l;`2+ZH#Okd2pmKjL9DBAKX$HD&#o9g?(^8J2h&IUBEtRzH1i0=#LCA|6GoC z_qI4}gM$v&PR=Fu1~_aZ%Ob{al;pTW+JR{lWQa$ar)A3;KP}pC6&!4s!#7Ky$-p;D zuuTkmqOo1dX5Iq6PBMV)Qug{M%UgC4N??_+xa_82Z6oR7~YYePI%y9_xgedjrLy&4l4`H-*Y zsMGL6?!vu?VC5`)E#h6i7JJC!FXGH4gt7zYz8Uf1a23^Zu1*R3E-ry1OhK(dWhVVD zCgB@FMN3B2u~#SMWfyZ$Yt*6E=tG@(aC`mm$%t>@lL7A0!$(6}$-7ibf@%!*sM@U1 zN05WqA?s=ZkVDxkEed%Mk?|q)SILSHreqtV#Qou7;h=P=n)+Co(DzU9!BiBS=G`wL zc!^U(x)lRa905^10J2LLh`nZ0uuprc)_YM*Y~7q73YinCDD+RroDjUv^VNJ~FVz!T zCw&tN7m+meB6~5#5)8Ts3UTSv>;hks$+Zbe(HPEwcqBmxm}eHh=rK!^S&yD$G{bV$SZD_9)rgADF6c$L8w2Ah*1 zuBVO35Vj}6=?*FaASL&pm(tsqgg61o0Zqlv1CT#@Y~!(h&hR-^P& zTW4?Ubu*D^(=}}*5DAV5%^JEAtm4SCUW6V^OoFfJ{4I#z2SRj!16F~@^gs1ZdHmod zutPf2^-=o21tr`TQbK}b8#ulKV)#+EFCd27HfYP=ks^K)L%TAwjv_+Xd@G6w!vG9! zp(ZHQ1b0zLD*iLtOdu4J-h+CV>&spa6cR=RP{@}-Aw%l8k;h^;bu@$RJ)4q9;>3+f zB$p86?JB+~*Gn#Yl&gPtB6*KfM&T_alB21;*at&0S%eI^!6g2Dq?JSuOCfM%`nzc5 zU_dLGXX3q@GE;U`|CYgv3|?Sx76CtS1OtG4%hHuke(4W(aE$Q^&O(@1;PhDi;cY5fute9bz!a zfa(OCCxxLCU6GZ<&e_$!SBOSZ}7j<<`}YB{JJMLiIz(I9BhTB zGd#h}Ps$_cmu5MtPci8P11h%kk+a8n_qz-zI}6{WxFFiRm%clVG(U3^drg+B&MCAZ z=Dvi0>Y4B#Tb9MIjN#M}RXlm)NS0%=06983@r!vj~7M?7QWT`ff)a* Pg+~VU-3Maz!Q=lIu>2(; literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/cookiejar.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/cookiejar.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e185c9b51ff0dea491ed12e347f3d58793bef9e8 GIT binary patch literal 10787 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 P#}rLPjPE_^J*oPC@JbEL literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/formdata.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/formdata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cd98f846563f7542b6d12fe53735386a9e12b31 GIT binary patch literal 4443 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/hdrs.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/hdrs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc756e1afedc000a4a359322551a6f4c15f780ba GIT binary patch literal 5259 zcmd7W*?-ek76))U-V$eZ0s+d>v<2GG8X72FDIn~dSj4eiNsbfIRyFobqT*PtBq;H$ zozA}Ro$0Kdy|ZtB#=Otxb6@9)e_@{HoMZby0(~Fy;TPYp&b_vzd#?;v#>dkU`19U7 z|K1FzBa#1LWAJALUR;L1!NF7{QjIhtcBC0?4z;3o6n@8AL)$Ss7DbD<;@b&35sk>` zo5^P4M#8@cnuLm!or*@cdc#XdZbtYR`fv$c~a713SR>Fxec~LAFQ89tAtZ_88f5 zu!q=AkeviO%=S3h6JST!=E+Wh9c6ox>?yEgY+16?U=OpMA$uBZj%|VLEZ8G#=g6J` zdz9@w*|T7eu{}rjJlJuz7sy@&JHhr6*#)qZY%h~t1bdwA64_<2C)hNyD`4|%IkG(1 zDKS+>{6UI%-Q%^`aO?0L32*>$iN*cxO_uou}R*#_84 zY@1|TU>De2vNyqAX1hVw0=vkzP1Xjx#O9H8z%H}BMdpKPYynvac7^RG*)6af+uLNf z!SZZ7WL+@9_A#=LgDtXsg6xxEOKhJa`!raA?H#hufaz@Sl6@BJD%$kCfj>t zKLE4Xen|E{Se5O4vLAu1vi+FsCtx+UpOXCyY>n;bWFLU7vwcAJ3ox7Qmt?;JyT?gpVhKXfMsd}kN}EV1ae z>n#;MrG{68RdBS@x}D0EOC^!B)ELpA6)y-auSUq|Wo$`U{ciXwnHNQ22{lR;{YI)> zvGj7u?2k2QB`TVgE2uP;_Fl&;Wz*^pPcLJY>R@<$m9PvgC;DA_ulpalSX4=^(U6@G ze&=$cVs$5a?QCwV?guhd6Fqlw1d&>ew^a1$$Ra-g{x%fwuTF#JD#gIw&Y-1sPUYZD~Q2tP-&Ph zZP}oX>HfmQUNbn2U?ODmZU9%vrGgopLvZh%yl%pE(P{jtK_yS^sX-afZLZP9nHf8(M$CC?PT7Cl?}T}UWX-Z*>MrpH&t9%+LE1wsR}nr zC1Fm&UTLSG?fS3}qyTh7nD)q`=f7R|o3g1!7RyFWGx8#@;)}kw4QZ5DRJ`E9=ZH%@}T#{c9J% za|1TW{^c|6WPejh_Vy1uS@G+e+jW(!7~0Z`)}5~S-tC<%u0Y&2VP;A-T`|gQ>kckM z+$dpgitfzay1OfN=58UcS3A+WcnP|4cFK@29i^{QhJeW@jP9r*Lm%F8BLp2agk`{6 zEn0A7pD7#Jn!Ij$jT>shtsjjxpJ|4aCg194OfIJz zV_4&Q5vnuy?*p0p*1w&qb~b(Z4y01m%8~(3H5IEGdN*ASU;}}@x*e)?72Y2ow7W$rDaJ3Ze}DaUDg z4aZTjU?)(?aHj(w*dKzgdiKcn%~t3(-A3r+_dhiTw*%*ZO?+aTMbi#={tM7>{5) zit!l6af}lfCovw!cmiV{;}phI7+H)n7*As?V4TG`hw%)?d5mW8VCWcEF_tlk7%Lbhj0%Q*Bu`TCHsB?73j`{DOO??s{8c*x}z>O+Pr@*-^t6;E{2&B`-!{fZ$&c$@p+| cY-nsK9i4!jir)7V8;b7!nT_p>{(t`b4|IE$l>h($ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/helpers.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..366047a3ee84514ef0ac19b75c13f03ff3c22d94 GIT binary patch literal 25931 zcmbt+3zSqxdS2g0zvj^l!w4akMJ#wT+Re#;Xy}ext{Qcx>zjx(luOt$G#FzMQ0Fi_E1qaiK z#PbQ2@Dj>WcE$26dD@;WPselQ>3Xg_lU`DuDK90@w3n7=#>>bv>t*HH<#oxk+v}ER zkJls5Uawc4IWH&A72XOwol0MIrMJ=|3~t4(_Iv#jPgYh{2fP7^rz-bVS9_}^p03Od<>K1QHb*s0vI^+#ipYWcL_PQ(Es@uKo z67Q+(sP6Q3R(E;3S4|)gXy}xp(de}Q$9rlLtzREk|cg-E0PpE-O+dCG;??e0oIe)8q@RsGB#WRoRIe+w4!h7Cd@4uiP+Mn>x z``L*X=U!49<}KuUcz;1XjPwiW_oCXU9=YYbVNc!W+r*_FKvBQluJfqWd0Fag+MiIH z)!^-fUjUSk-Lj7)(B5VBcsp&2N%M

n-c5bvWUTsUh`*+NQRv9criArFN@5>PfX% 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 CYnZeE literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..342d4da40c1d01fafce01820af94034fe0bb4b4a GIT binary patch literal 1288 zcmaJ=TXWk)6qe+hY{_=)+?-2OmrFr~)G?R03_}}4!$1;`W$Iy>jz*2Pu7Xw)y9&W{ z^1!d)6(0FT%KL+i5@cDF%w%P9nZ@*_4!omF%lChvTtsQ& z`;e|4=Xo~b={Xewie1iA?o?&-mIWzPyNw6 zf1W0T7YE-SJh{FP%kar{KZw%jpl9%6c+GEN?Jj_`Pb_5b!^Xp;$TB9fB<4a^^Eplw zH?Xz@AT^GMjI^-^96YC44wEI6^5QeT@{#|)EYeaRxS~&m+S=D;DmAaPqNGBmQg|bM z@y9E*@2~rcUdx*A2XXBCvidCLEXbw3JPc6+44ME^b1vIZm?UW)C_VT>VF%fG7zlbi znT!_0eH&D2eO#jtf-@0%YrduDmBtanTQ0OB2Gt^fc4 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_exceptions.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e314273463a06377d5f24ead4ed4adec0d46bb1 GIT binary patch literal 4393 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_websocket.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_websocket.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cdd6cbff7f2ab9b6329fc48d2b68af4d36b9596 GIT binary patch literal 14966 zcmb_@Yj7M_c3!`xr{{^mgLsjmhI(){6bbRUq9lqU00Jad;D8H&qS%(UHJsZ32bc$V zyCD+e!O9l6+Vv)D(~ccKmQKJ*%9T_$NyX*LZnl!mCUIQ(vH4{uu5=QY%gGNTaXAks zuGCg4%6Crp3Tqqu z9^rJNI$AquALMkhdZ_k{{S4A6`|uS-q($a|A~J4bOShjDS<&-Aai6`cY^iqMea7u` zkBlfIiu;_%T~JWFSM;HFAJ=|f^xH3>&Wl_=a6xfX;=q==a@77DQiGg&DatF@$B-IA z-plrJq=q?l0;v&BjYaidwqFsW_DNtxzv%Vg1w|aPPj$YZK`+|&X>nLQEAryVvi?}J z&w#Gy#Pgu*dG`!Pan?QSKEHBKXhOr+=lSc^=<7V{z93#i-51^0Q2IK)kBZOX`*ZyL zhHI`|u-`;~7rFnJ(0@T3!<@V&Ufxo9UM``uhepjcj)S5X-ErVQ@kkeA;*|%6J>iZ# z)a0l;VNcdiZVX^$PF641rtB$Iai{Fbn@WAuP~7R&Bx+q%75byPx0Jf}F0g?ERB=k2 zS~jo>SI}EH!>7?xZ2PJ>^H{ZKklRZ%G7V>=l5;5e!k&`PgZ?Qu$D?`M?RSs3Z!c*h ziZ~BiUlXrCh}pAZnsV`XQCxUrh&RPWE2#wlviCpza|@gqui+GKXj#6Y1F;^sWbUfUF6S??a=lq7Std< zQ}?Ip>op|J1z)b0{X!zp$Lkw`HCd`wOSh|TV9ZuLKd|Q3d>|=RgZTB5@4K=d=nJkN z#1_}rP$_n!j?%y=mpp$*1$JOePn10OdPD`jGsQV)>fObu;=;^aaRC{L%O$_`#dUYx z#Yb$q0_^C%_vV5#IXky7b=kQ#wXiULWh&^4vSx}`I(a7Y-k!P@^mIl%@0NrsyE1Od z3J47nHy5tCo>y9SgKVerl$4FI$Xj0ASaXBa&4tNo!*eGa!Y$MMw0|_3OL#m2t^&cL zkWhg@(I8B82oeKABnAOu+Lnmh31Qhuk+4%DX{WKlGa_wgMaJ$CSu9bH90i)nA3|JJ zb_o0j0{@Y~9~1ab1pYID|3cuu68IAW|Bb+ZC-A2L#X>Hy9H(BYxsDSg9jDe1>s3mp z9p~Vn?9U-?ro3v#Ms&fPk$b$JX!}!H9q5y>y>Hk>8If_@J!|6rs^v# zbxZv@?XIy95(iG!D|Nr11=`rjK&|YOEnh^tA0{q%u3v7{)-IkTT!h$EWC5?Be|&a! z?k3iOx!;+byF9f}MnUJ-;l%66`oG~s*Ra!W%+9!`ops}Ok89aEH(~d>NxRQY+5I93 z&P>S>pq12#%mC~VZ9549q?7F;g6$zZDqQ!H0lzfH59q5T_UAn&FlYV$2Tlay6?-<9xfn0 z1X9Ht188%BtFOSYd8E2A*IZUzlN5|=3hj|5bYVO&A+2IqV^a>H5lP!>qa?h7Ca>T- zFs19S%Q~|=tv{_iJt&$aVwCF!{$|AmFQVxEW{OD6NtZ)~is zbxK0G;`P__C&x~o?i3ePIR&iPB!=f!mzapIm7_%qj1{j@e;+B{BTB59?aa~`6%`Bd zeY_{XfZ8Fh7^P^Uy0Gr@1I@vEco?&#@|-*|#VA+2^8oEBCXw$NZVXn2{z(6-vIHAZ z#2%z=6M5z%Rm6n_yCeQpNDAA+OeN$nnm6+uowKWwdFo`IS$3>g(4jb?c7k{<)Kl^* z8kThc`q7)lLT`^y(rP%0uWl*Z8q(Th>_wr_+5nY&8#RKMx4s6|2NhANSA54o{tWWD zP|hMn>eq3~)sp8qPB=@vSBfaB;_;|QMK#stP=|ijnPVN4YDgwA4E^X$jVAGUIRGCd zf^DEHN0coxPqZQn7SNJLaiDv?42+Uo_P`HJ9WN0BW`Vflpo-(H5k}%iMQsi~K@C^I zWbYG1Xe=6KjO{4eNs^e7#wO2kU6TvQ$bUW4Xb!205pX*Xz+@b z@!9#&s4wB+5qGl+8)SNrySZ=`MwfS|wCeKwHJ|T{V3!~6w5xPj!q_(+xqwcd%FQ=W z;1dNjL*Qom4s!L9U-{5=Zg2Q*L&7ZTs4^m$2E^P%bF)mU?C?(k2lF(1p9hu?A1bu8 zx743yw23{F;&W1R}}71V&dh|z$&ASO%oWmt`jIqXH1@1jbmWRtrn zI+&qlY0onv7)ggN@}BSG38+fMWPd~Cce z^<&l7TM&yvUDdp!$V2*LOoaRn35f@o7;;wLGd8tNebd;CwMb+@PJcxoQML_iT-0sn zTmWtXTe4HCb7_>rrDj*D!KG0Sm&UtFV_X{L!2N)AQm{(*u=ZfS&=$(mprJtXOY8MA znf8(R{($m7$XC34DgOb__6PaK?G?A|=Nn7;s#{<7@8r+Ek^g{1es{f+l%n4J8r(*sQYf+_Xt;np(I_V1*+s;1-L^3jx(Z?m-p7(a%HK4(n>w=feetE zKR0%UFw9R+=0AV-+_{MKV#9ay{+*H!0Q%bl%h%TZ61WDr?rx{c>opJ(wOpk7YwOZI zv9{sgK?ju@yc(*2ZG_KSX(NBz%}aN!S}KE-+Z*tt@(s8|wMx?!Ol#z3-o}$ zr3$-GQ3pFD8K2le9x}b%9YpLkvUdl8#YqQt_E5b`1hA00h0=$FhL{$+r?6}7I<%5b zIH0i$)ke8g^)BvisZbcpm(h+K5v33dk`0H%QRh^O^?PanExlO$1A@KnE8D z3D_lduZoF!!otFf|dS^!l-4fblVQrd z#Bh0Ve(X!f-+#IAR*>7R=PX>GomrfQkTPKjlESnqv=|_KudIq= zB1m4btomalT8d{07;Hk@ge=Ec<%PL{0OtD)0NTc6v)inI>YZh9~ikuPX9B^>p_T*8pDmiLf^H z>&o3f;G6_aSDfeP&Slp68&n&(MtZJgj3&(^uCnuxn%ip6d2(j+@kjnl&7XtS+4sD$}cRb&$R&M7-1M+@nXLz0H|DQ)mXL!9X z{4}_~aD~}dBaWO@c&Qky-;byo+){Oys zkDGPP5oHNIA(op(`yP=)y&N0H{F2&NmQ1!2=FZ-ko-!i%IhM3g7Qo_Y+#-s z?ljieqfI(Xl46t)mOvGzqoQo|xmMbsU_=muO0HDlmEI|NY`O%gs0P_FK@Ym)icV;Q zLhJ9%aG*q&(WWhAU4h67V!4sffK3YA?Jw*=_Bd&b@+$;*MP8s317<^V7|E~Yz>%Vx zyyGm@!oH)w_B;H7t32Fs?ZQ~}kMxy0i=9O$6kgd@AEUFjBd>+?Z!Nj5aNNey(|u(5 zi)cJdBoaFK$4`*ZX|FxS!_m=(;ycWAmLV`jUqN6Fd2j&9$Pxw&r%zg@pID8{PyD2xT1g8SS>IHCRol`& zRyPLG3f?re+Rl&>wi(CC)k!Qy7K`x%EQW=}=;M|>BEF@ytdF&uSOzSF^<}HQ5Pptj zhS`d5>6?lA*_HwNjHo}WrF~NoiI&dL_@?%&CiPvl0YVOPz8&!~9-v<@z5t8viy*HC{*D61BwBYIPyR14<^ zRA>)1&tO`HS9R3-K1;MAv>VwTZ5eD{C@Tja>hf!#3AtMolsdQ?;~bjtLn6KXOn2F1 zo_pX%ZJZ7s>tIJZq9L>W44Ei2Pf;o8kn?Ck)FwdFw0{_7_}(VSupz6b*YiJA^8xnM4GK*m-T-$$)L3se^U*mX zyA1gs-^`Poa)p<#A`ajqqj`aX9AR~eSJWHz6HtA5#!NAl4obg40R=c7jpO-c_!mEZ zL~b@uT<)kV^cqq5nVl81=}@Y^5Tw{Q2-T(h1x!p}kQp3g_UXTCg!h$;%F#K)7}$OhLDngKB%9xIsiqa!9q`K8Uh=Xw)kyw?x>#C za#|XyYFKAzpcQKN87AkZ)lsfzr~{@2Y=p^BEz~9TMs?cdeI}_pJaG8h^#+WjmP8#= zho(BJ^&w@c!?0k|YF2NK?pKYwni4d<;Fg422JwfFnSHEp-T* zP*V^M#t8)i0y>TW$k{ibPcNeeY}gfpHGynFY7fI*gxpi*8mwJ7eL^2%U5B6q(yuCT zA!F}po91Smbmd!$h+TqSL)whe38dpuI*GIurBg^JP&eI5dcWRE;YrBvq5qioJ>T@> zD;A^-$?h~Xupxt%1ud<~ASz378N#O#woEH7(!iDt>x15G3rG5^q(!q)n=H3cRuT_Y zkK}1m^sv@C+d_^!E^>8E^kP<$b?8v!On1}ar&<>2B`48>gmu#R&hU4p1uf)cF>5_| zYjp%^qFL<0ENb#g_{xH=tmxxe{r7uj_4hw(R{dNnMwSVz5VQqmP_~i*RsRw__0>Sjf39N?FZHt;Q{~4*vC5*GYtKFNuM$L{}4ms~Tn}qn>WOo6Mk=d=wmrHdD*gz{* zaVF?WisaYxr%snm=;^OoU#W&;_K;e-58A_Axl3yo4=-CIAf00sq^_Hagfc$xY zz_{ILROL75`yqk9K;S2-Bo(PZ#4S$CpQG%L32f~vJ0pLVvVWQY33^sj@J{cw4_4TB zm2~dJesZBV)JcB_8G*@j;n@ke$r2I0hG!=sVO;1BsX zfWbDT_u(mqrx~7+-=b`*<20M0do2GZWhcsa*6XW;e!sH%%P4+K%IdpFD24&$(1*w% zZbxWYH4D{3ZZ0V=`m@rcHc&?o6`2X;V;KWso;d(D7pgK7kw=piO;XeJET=IhRs*gH8Il~@M#+J|1zlGUDxuvQX(zzt|+zXI#BgbL~+ zW`FOwu*_k&p_y`&Qr{*}BtV`t8xxW|;?RB}l`cu&N!}}EO3}=9&E{^jfFeGh;_ybs*OmU|pEe>)>D(fZ@f-;2l$PfvUM5wFB&EPwQpi~&V%85gq(}SFx=tYfQ@k}SD zPxK?FPaMYO!~r+McSjNkZ-rO~fc1bFM2!RDSsul}YV6|^3MrTPBUzh&?h4Om@{viR5%20#dI5deV z3jC4lK8eSh0DxFzaR^9;1O#R)wnA^cMWHgI1=r8Pm0v&;qMw3i6e6?OHACY=0z^)bAnN(Vd6yo9zsO?b8%Rz#$h6Z~_t(~aj_~0gUfa?{5HUhng{}-BO{y;`AD~4FhDU5A{TN0hm2GGIEKY&`DxZs+ zq>7Pii1>uEY4|;CR$^^eaxf0#@;7l-WYrNYVe>En3jfgW6$rXaKuO{;Th;__p&ILNsEFKUq@hQ06R3z4tH|3=F0g<$o5zwF5QUT%S4k_VihLl&q)XqqKHvINS*}(i; zA&#&uuwmv@r4BQOF+UwE)~$^VGsM9G#`Qzydip-J{mf%!1_t$2iaFBVu%70H1vp~) zQl#(caFnfwj%Ewb=i6>6&gSV9CQ{#H%_Ebc0>4MMZu9VOqy3TRgJRy?V6sSm<0ePd z{m`w-N60Gf{LfE6{dDINk~=>EApb4^4t`Zd{svN29pKZCKK)1!%@epKmF2==NsPPe z#|8s1E9&9>fO!}vKA%;Ge7}vFL8@y%25H-wz`au(uTD)}mcK>iv8C#|cSn-2q2lQq zv$M|h?2U!1^tEuSI2nCem?V#kA@)r}6C@N9>_NkPI29z?$ZGx8r3YRhl1I``N* zkfeSQHs?u`{}dl`oWO4q_&$K0aUgmsb?1&-#nBaRX>#0pmdZ)<^8jrfR)PHIR6R*Y z43P;yRM{5a0)Ukkn0NSsba+_5SIi)6?qOJA0AZ2D4F!W017?6`#BjQ#4e(i0ACxYs z_(AqCEsY}JFbiNbz^8<=9@U0X$|eJ=?iXN8z!!z09z_Zf@?CY^7FN6c;sAFFo$hrw zK?`3tn#9{X4glUoaC6o21}H@_b9u;zw&asz%E754?GTpfTJg`omN*L_S#RU^LtCcH zA0PwKCSqlf#Z%6-?VUFHyQuaHG+ksPC~)+x?i*_DA%=_l32FcruN(_v8XEoRZQvn( z<{`GP8OZ?%K@5#WB@fIuR$`AeY+H@DEm{A1vyZneU5;&sjK-qiR}oh;ZUbw0^k}+> zoZu?hzoMKG0%rl*!(+Pk4etWVf2A`#ta(yx4s;BzXn53dCyxIAX)JUvDUvf!9gFqTD9-ew2J!~VxBrg=L9gHio`}~8KN}x=bS5oRM`wNkA5UE>O`e2w1|QOLAxx~d z7py+m$v3<6!@Gk2kMcK+chVVcXUX?Z6UX09f$aA2*S@jtU4FWpTNl4Z(?-^+5~uYy z5IcI32dLr>{ZB)5|FnzCk;y-Lli9{xei;c&9ZZca4P358T&^|Ae9(QE2Z(-XP>e7z zg!T>Mc%3*Nv0z+hCiCrGq`>{L=7mYR558AX9mhp6T+RR!kw?6HgN)dp?+NVVEu5`= z3l!m?%6i)51wH#?qr7`KdP>7-A5y)IbU5<86Di+B!Eew!rjby1ACWtCSZ^NKzneG= zNf&u>fd+NkFKwFcxBOe=gxN#;-I@t1B9l2V=R;eYypSMX@;2(_N+U=t!hrQy3xAuc z9wk8R96CQXrP#;eO+|7|((aeEb0nFH;T76{Ln#{0Q#~MZ0^X!?9!A14H8_am7!Io0 z47{PYaPT8+YGbiU!f0!YRKQF!rvkAF9`e|0X7wA<#C}1 zr|iO~|HYD%R5V23RRVnkK2M;Zz%LWv@W>6M!fSqfLs-5;CD#f37=iZ*lnKBTQ`k_k zle=LKxq{pvHB%#=3T>?_<;2O%s(_3dwW<^NHh~QS9KiXAQU?eSzdVhR0_#Hf|4bLj zV)WJkC>+rJM>fXsc7Q@R(z)DWJvW>~0HXUZr{?rNJ(oamLC>XfMxXJV-ZxB9a}8Dr dg%gt6Ap|7`Q literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_writer.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/http_writer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4bdefb9c32ec2ea53ab47b9d8b04eb8cff12860 GIT binary patch literal 5505 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 GThTwHe|;zb literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/log.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/log.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..141e803c10ce61fbeb8a4264bba178c88bb79650 GIT binary patch literal 420 zcmYk3y-ve05Xa9++N6Q-@faQ2@F6yY5K<)u#KM*Zh2&%`TqlYR71?+SRv39Aq^wN5 z0uvXfrr7fN_xGLrKg$re^>wj literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/multipart.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/multipart.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bdba8067e363e98a9db5ed9f071f666bd0beec50 GIT binary patch literal 26208 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�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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5873c0000d3284779eddd1d17cd8499fd824e3d GIT binary patch literal 13444 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 N9x{vn6G(aczX5y1G2{RM literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload_streamer.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/payload_streamer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..678882dc65f7823e59d75ae6f71e74c1b3b51fca GIT binary patch literal 3179 zcmbtW&2QX96!-XJ*X!)&qb;Q^l^9VVag}b=Rz)ZfNJvoup@7s%m3(m=&urqxYnz$b zhE#h&snip_a;Z>z#kw^g@eiGKxZ9_d#`oq^?3Kl zIwHXW%+KrjSvCjrb9_P1pJV2I!=H~*(=farqr)_h7)^#n%7;9QRFY?OkP8~;A|I(F z_vPea=5c%VTanbj@4Va};pQ3Rj`7%AsN6^dYsL%rSfq}?}bdaQcb=C7IrR!0W z?paq6^lhE^MG$TihG%@(|Y+eT|slvS_R?M3Skc%6eSs zEB>=u^1}(*m(N4-scQZ;;-Lvl|u_~Phz#;yIz;>UM7dCc)Em5rQYtB5>yztGkT~oL078Qp> zby#pX;7-UD zhkGz?y)apuxiFs5k<=;Y!s^QKKtx3W@v-IGrHuhp+F-vdTl)u9E4UhoEVgT{u(hCU zLXlUYQpQU%Ca=iY2+gqxwKcY&wwVDTOAtHl_Du_B$-rz`;GM0ZMl2rX0lSp=5afLbpmITOtM6U;fEkhwxBXv zUD6^?E}e#8vJpJhsz@Q`VRsBkM}OF&>93(k3f0(nWQ@rGOn*dv2h$&!&&jutN53&3 z1J>qSr>yc#aUPC}cdpoMj_optwa~9YfvP_K#U;H4#$r5VH$@=uE`=2PhJwNFfs;2*>7;RRx`?y;EspRfIbZw<#xUmC*5@ zp{Sa0)2h@=>xj#+K_J}XJ**m1X##0dAy59DMd;F7P$V98$yHZ7`2>H^u65jkX=R!} z%!K@9F&pxi%?McNlo#&Tsa0pMIi~7!>^)MWZ{$#!FzytG7axl&$b_l#cks zfoH|2qcg(>%Bu0Ya+WI9)9X8@fzzS(A)KD_LKA8qz`~ak(XJ_Qd;%h5K7R63s2Yg4 zh0g-OWIrIODJk;lWJ%Z`0i=%qRvw(6@`?&+RB(?W^df?6S0Kb zbqsz4y|1BE(P3V)1kU*9%XS#DJce@%xc7ai$`(AQkcFyDj!vnf5vie5d}&2HvCipb zyM7Qw2NyBrpg{e^R0#s3QnO6o*C^LGq;x;89+odK8YCtQ+jI#;u-PT^rftp6&GzPr I>&%mX0E)D~ZvX%Q literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/pytest_plugin.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/pytest_plugin.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c191abb3cd0a297fb3a2603d697e49703ff95434 GIT binary patch literal 9863 zcmcgy+mG8;dgmc2>M|P5cs#zwacIXkIWw}I%U)bJS;vW+q}xf>cH%7CU6rFlX{ezn z`H=E>6sg;;je1fv35o@>4-K|6K!KtUeJ%P{p#MY*J``B=DG&Vz(mwR}okLL?*;ynl zwi@t|=kQ#<^PTVeeHYH_^YbMQzhC~@zqbB+Rnz{1D&t=P4?n;aX}YFyjk7>=)SWp@ z)^$h6T@Q?o>6nb(89}aNIaVj{n1e6Z9x=p5`UJIkFz&Y{j>=WyqUbEI?BIodhq9P1o+o?+TH&BB5c z&WXEPc+}LqXE#gYpO{8}oH-|ctcCiA<6bA7lT*F^J?nK+_3}(_&O6{8Z0g6f7W4An zp<^07JJ0a~FFw*7o0s?;?x(zR`!p}}`A6DA<~%QJ6}}*AXFS$E%NO|pSvx0dm-#`y z{D`6Nd47l=#tawu5q=c+DnG`L<9<=j@eDs9N4+3x&+?P9wjyiKaa-1o%i1Y^TGm!& z?RkDi)@rhLmY@#+6UqE7cWbIzqURfd?}c$9pVMyTpxf=$8{IJW9>mE) z-1V!4uSNuGO6w;#lbx#0!9=@sNob8>~m>TOeX zaCNfAmLG4}QO|4mO}}B&+pD(fwPN@0Q+>sbyPJO3?g|@6KX_(Bycg23uTrN~?ydJ* zgA=OB_U_{-iNA@Ka655 zwHmzmQq+3oihn8PR(9`g%R}r1{gxlrdfUlj+LBFwhED1v3XPdemwyHQ$tOWwvSTLs zHPS0u#{(Ve$6CyGpzUIrvyWN09P7Krj<(0d8Lp#la^p5o@ME2u=xuK1#alzo#1qeb z7tmQZF-m`|J!X&fra{>Ds4!wfHq`3CONc{Z(7x@(cE1O%)28gE{~+!QuU0DA_+1Zz z?$)?1!b#Zcp55q*Za?-zFRIzMAT3#a($NoXH=H_#nw;&<&9x*iynB5tRAu5h+B`1# zGg0PnQDbx;#Sq|dOdIJtrdXoq-^DhEdRxO5&%}%y582PzP~X+LzQ;b+b_}t;qYp9a zQ?Q9P+yqN_4%;=*%NQDajA=XCuDQc@b9-RmZB33%T8ex@>s%dFp?D+=ZkSoFY}W!3(8NY5-|bQ*=AFAJ?+oW4{`i zyo0!+3n;cLpj88{Ownp;u?_=sTA2=IHYB}l4QjXqg{t?%*bjgr-4N

l56^uuxPdR~}>ndi;GHmU)FxHamOe|znMLd#RF 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/worker.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/worker.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..327e3a3d1403f839a6d4669a850416e2001cb37c GIT binary patch literal 6950 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyi b/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyi new file mode 100644 index 0000000..1e35893 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyi @@ -0,0 +1,6 @@ +from typing import Any + +class reify: + def __init__(self, wrapped: Any) -> None: ... + def __get__(self, inst: Any, owner: Any) -> Any: ... + def __set__(self, inst: Any, value: Any) -> None: ... diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyx b/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyx new file mode 100644 index 0000000..665f367 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/_helpers.pyx @@ -0,0 +1,35 @@ +cdef class reify: + """Use as a class method decorator. It operates almost exactly like + the Python `@property` decorator, but it puts the result of the + method it decorates into the instance dict after the first call, + effectively replacing the function it decorates with an instance + variable. It is, in Python parlance, a data descriptor. + + """ + + cdef object wrapped + cdef object name + + def __init__(self, wrapped): + self.wrapped = wrapped + self.name = wrapped.__name__ + + @property + def __doc__(self): + return self.wrapped.__doc__ + + def __get__(self, inst, owner): + try: + try: + return inst._cache[self.name] + except KeyError: + val = self.wrapped(inst) + inst._cache[self.name] = val + return val + except AttributeError: + if inst is None: + return self + raise + + def __set__(self, inst, value): + raise AttributeError("reified property is read-only") diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_http_parser.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/aiohttp/_http_parser.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..fb60ed00fb90c8b3c85f50ac1106fc7f237b1858 GIT binary patch literal 687336 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�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 xK`{uJhUi-5)5oz|%{||E0^uYiC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_http_parser.pyx b/.venv/lib/python3.7/site-packages/aiohttp/_http_parser.pyx new file mode 100644 index 0000000..3f28fbd --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/_http_parser.pyx @@ -0,0 +1,836 @@ +#cython: language_level=3 +# +# Based on https://github.com/MagicStack/httptools +# + +from cpython cimport ( + Py_buffer, + PyBUF_SIMPLE, + PyBuffer_Release, + PyBytes_AsString, + PyBytes_AsStringAndSize, + PyObject_GetBuffer, +) +from cpython.mem cimport PyMem_Free, PyMem_Malloc +from libc.limits cimport ULLONG_MAX +from libc.string cimport memcpy + +from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy +from yarl import URL as _URL + +from aiohttp import hdrs +from aiohttp.helpers import DEBUG + +from .http_exceptions import ( + BadHttpMessage, + BadStatusLine, + ContentLengthError, + InvalidHeader, + InvalidURLError, + LineTooLong, + PayloadEncodingError, + TransferEncodingError, +) +from .http_parser import DeflateBuffer as _DeflateBuffer +from .http_writer import ( + HttpVersion as _HttpVersion, + HttpVersion10 as _HttpVersion10, + HttpVersion11 as _HttpVersion11, +) +from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader + +cimport cython + +from aiohttp cimport _cparser as cparser + +include "_headers.pxi" + +from aiohttp cimport _find_header + +DEF DEFAULT_FREELIST_SIZE = 250 + +cdef extern from "Python.h": + int PyByteArray_Resize(object, Py_ssize_t) except -1 + Py_ssize_t PyByteArray_Size(object) except -1 + char* PyByteArray_AsString(object) + +__all__ = ('HttpRequestParser', 'HttpResponseParser', + 'RawRequestMessage', 'RawResponseMessage') + +cdef object URL = _URL +cdef object URL_build = URL.build +cdef object CIMultiDict = _CIMultiDict +cdef object CIMultiDictProxy = _CIMultiDictProxy +cdef object HttpVersion = _HttpVersion +cdef object HttpVersion10 = _HttpVersion10 +cdef object HttpVersion11 = _HttpVersion11 +cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 +cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING +cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD +cdef object StreamReader = _StreamReader +cdef object DeflateBuffer = _DeflateBuffer + + +cdef inline object extend(object buf, const char* at, size_t length): + cdef Py_ssize_t s + cdef char* ptr + s = PyByteArray_Size(buf) + PyByteArray_Resize(buf, s + length) + ptr = PyByteArray_AsString(buf) + memcpy(ptr + s, at, length) + + +DEF METHODS_COUNT = 46; + +cdef list _http_method = [] + +for i in range(METHODS_COUNT): + _http_method.append( + cparser.llhttp_method_name( i).decode('ascii')) + + +cdef inline str http_method_str(int i): + if i < METHODS_COUNT: + return _http_method[i] + else: + return "" + +cdef inline object find_header(bytes raw_header): + cdef Py_ssize_t size + cdef char *buf + cdef int idx + PyBytes_AsStringAndSize(raw_header, &buf, &size) + idx = _find_header.find_header(buf, size) + if idx == -1: + return raw_header.decode('utf-8', 'surrogateescape') + return headers[idx] + + +@cython.freelist(DEFAULT_FREELIST_SIZE) +cdef class RawRequestMessage: + cdef readonly str method + cdef readonly str path + cdef readonly object version # HttpVersion + cdef readonly object headers # CIMultiDict + cdef readonly object raw_headers # tuple + cdef readonly object should_close + cdef readonly object compression + cdef readonly object upgrade + cdef readonly object chunked + cdef readonly object url # yarl.URL + + def __init__(self, method, path, version, headers, raw_headers, + should_close, compression, upgrade, chunked, url): + self.method = method + self.path = path + self.version = version + self.headers = headers + self.raw_headers = raw_headers + self.should_close = should_close + self.compression = compression + self.upgrade = upgrade + self.chunked = chunked + self.url = url + + def __repr__(self): + info = [] + info.append(("method", self.method)) + info.append(("path", self.path)) + info.append(("version", self.version)) + info.append(("headers", self.headers)) + info.append(("raw_headers", self.raw_headers)) + info.append(("should_close", self.should_close)) + info.append(("compression", self.compression)) + info.append(("upgrade", self.upgrade)) + info.append(("chunked", self.chunked)) + info.append(("url", self.url)) + sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + return '' + + def _replace(self, **dct): + cdef RawRequestMessage ret + ret = _new_request_message(self.method, + self.path, + self.version, + self.headers, + self.raw_headers, + self.should_close, + self.compression, + self.upgrade, + self.chunked, + self.url) + if "method" in dct: + ret.method = dct["method"] + if "path" in dct: + ret.path = dct["path"] + if "version" in dct: + ret.version = dct["version"] + if "headers" in dct: + ret.headers = dct["headers"] + if "raw_headers" in dct: + ret.raw_headers = dct["raw_headers"] + if "should_close" in dct: + ret.should_close = dct["should_close"] + if "compression" in dct: + ret.compression = dct["compression"] + if "upgrade" in dct: + ret.upgrade = dct["upgrade"] + if "chunked" in dct: + ret.chunked = dct["chunked"] + if "url" in dct: + ret.url = dct["url"] + return ret + +cdef _new_request_message(str method, + str path, + object version, + object headers, + object raw_headers, + bint should_close, + object compression, + bint upgrade, + bint chunked, + object url): + cdef RawRequestMessage ret + ret = RawRequestMessage.__new__(RawRequestMessage) + ret.method = method + ret.path = path + ret.version = version + ret.headers = headers + ret.raw_headers = raw_headers + ret.should_close = should_close + ret.compression = compression + ret.upgrade = upgrade + ret.chunked = chunked + ret.url = url + return ret + + +@cython.freelist(DEFAULT_FREELIST_SIZE) +cdef class RawResponseMessage: + cdef readonly object version # HttpVersion + cdef readonly int code + cdef readonly str reason + cdef readonly object headers # CIMultiDict + cdef readonly object raw_headers # tuple + cdef readonly object should_close + cdef readonly object compression + cdef readonly object upgrade + cdef readonly object chunked + + def __init__(self, version, code, reason, headers, raw_headers, + should_close, compression, upgrade, chunked): + self.version = version + self.code = code + self.reason = reason + self.headers = headers + self.raw_headers = raw_headers + self.should_close = should_close + self.compression = compression + self.upgrade = upgrade + self.chunked = chunked + + def __repr__(self): + info = [] + info.append(("version", self.version)) + info.append(("code", self.code)) + info.append(("reason", self.reason)) + info.append(("headers", self.headers)) + info.append(("raw_headers", self.raw_headers)) + info.append(("should_close", self.should_close)) + info.append(("compression", self.compression)) + info.append(("upgrade", self.upgrade)) + info.append(("chunked", self.chunked)) + sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + return '' + + +cdef _new_response_message(object version, + int code, + str reason, + object headers, + object raw_headers, + bint should_close, + object compression, + bint upgrade, + bint chunked): + cdef RawResponseMessage ret + ret = RawResponseMessage.__new__(RawResponseMessage) + ret.version = version + ret.code = code + ret.reason = reason + ret.headers = headers + ret.raw_headers = raw_headers + ret.should_close = should_close + ret.compression = compression + ret.upgrade = upgrade + ret.chunked = chunked + return ret + + +@cython.internal +cdef class HttpParser: + + cdef: + cparser.llhttp_t* _cparser + cparser.llhttp_settings_t* _csettings + + bytearray _raw_name + bytearray _raw_value + bint _has_value + + object _protocol + object _loop + object _timer + + size_t _max_line_size + size_t _max_field_size + size_t _max_headers + bint _response_with_body + bint _read_until_eof + + bint _started + object _url + bytearray _buf + str _path + str _reason + object _headers + list _raw_headers + bint _upgraded + list _messages + object _payload + bint _payload_error + object _payload_exception + object _last_error + bint _auto_decompress + int _limit + + str _content_encoding + + Py_buffer py_buf + + def __cinit__(self): + self._cparser = \ + PyMem_Malloc(sizeof(cparser.llhttp_t)) + if self._cparser is NULL: + raise MemoryError() + + self._csettings = \ + PyMem_Malloc(sizeof(cparser.llhttp_settings_t)) + if self._csettings is NULL: + raise MemoryError() + + def __dealloc__(self): + PyMem_Free(self._cparser) + PyMem_Free(self._csettings) + + cdef _init( + self, cparser.llhttp_type mode, + object protocol, object loop, int limit, + object timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True, + ): + cparser.llhttp_settings_init(self._csettings) + cparser.llhttp_init(self._cparser, mode, self._csettings) + self._cparser.data = self + self._cparser.content_length = 0 + + self._protocol = protocol + self._loop = loop + self._timer = timer + + self._buf = bytearray() + self._payload = None + self._payload_error = 0 + self._payload_exception = payload_exception + self._messages = [] + + self._raw_name = bytearray() + self._raw_value = bytearray() + self._has_value = False + + self._max_line_size = max_line_size + self._max_headers = max_headers + self._max_field_size = max_field_size + self._response_with_body = response_with_body + self._read_until_eof = read_until_eof + self._upgraded = False + self._auto_decompress = auto_decompress + self._content_encoding = None + + self._csettings.on_url = cb_on_url + self._csettings.on_status = cb_on_status + self._csettings.on_header_field = cb_on_header_field + self._csettings.on_header_value = cb_on_header_value + self._csettings.on_headers_complete = cb_on_headers_complete + self._csettings.on_body = cb_on_body + self._csettings.on_message_begin = cb_on_message_begin + self._csettings.on_message_complete = cb_on_message_complete + self._csettings.on_chunk_header = cb_on_chunk_header + self._csettings.on_chunk_complete = cb_on_chunk_complete + + self._last_error = None + self._limit = limit + + cdef _process_header(self): + if self._raw_name: + raw_name = bytes(self._raw_name) + raw_value = bytes(self._raw_value) + + name = find_header(raw_name) + value = raw_value.decode('utf-8', 'surrogateescape') + + self._headers.add(name, value) + + if name is CONTENT_ENCODING: + self._content_encoding = value + + PyByteArray_Resize(self._raw_name, 0) + PyByteArray_Resize(self._raw_value, 0) + self._has_value = False + self._raw_headers.append((raw_name, raw_value)) + + cdef _on_header_field(self, char* at, size_t length): + cdef Py_ssize_t size + cdef char *buf + if self._has_value: + self._process_header() + + size = PyByteArray_Size(self._raw_name) + PyByteArray_Resize(self._raw_name, size + length) + buf = PyByteArray_AsString(self._raw_name) + memcpy(buf + size, at, length) + + cdef _on_header_value(self, char* at, size_t length): + cdef Py_ssize_t size + cdef char *buf + + size = PyByteArray_Size(self._raw_value) + PyByteArray_Resize(self._raw_value, size + length) + buf = PyByteArray_AsString(self._raw_value) + memcpy(buf + size, at, length) + self._has_value = True + + cdef _on_headers_complete(self): + self._process_header() + + method = http_method_str(self._cparser.method) + should_close = not cparser.llhttp_should_keep_alive(self._cparser) + upgrade = self._cparser.upgrade + chunked = self._cparser.flags & cparser.F_CHUNKED + + raw_headers = tuple(self._raw_headers) + headers = CIMultiDictProxy(self._headers) + + if upgrade or self._cparser.method == cparser.HTTP_CONNECT: + self._upgraded = True + + # do not support old websocket spec + if SEC_WEBSOCKET_KEY1 in headers: + raise InvalidHeader(SEC_WEBSOCKET_KEY1) + + encoding = None + enc = self._content_encoding + if enc is not None: + self._content_encoding = None + enc = enc.lower() + if enc in ('gzip', 'deflate', 'br'): + encoding = enc + + if self._cparser.type == cparser.HTTP_REQUEST: + msg = _new_request_message( + method, self._path, + self.http_version(), headers, raw_headers, + should_close, encoding, upgrade, chunked, self._url) + else: + msg = _new_response_message( + self.http_version(), self._cparser.status_code, self._reason, + headers, raw_headers, should_close, encoding, + upgrade, chunked) + + if ( + ULLONG_MAX > self._cparser.content_length > 0 or chunked or + self._cparser.method == cparser.HTTP_CONNECT or + (self._cparser.status_code >= 199 and + self._cparser.content_length == 0 and + self._read_until_eof) + ): + payload = StreamReader( + self._protocol, timer=self._timer, loop=self._loop, + limit=self._limit) + else: + payload = EMPTY_PAYLOAD + + self._payload = payload + if encoding is not None and self._auto_decompress: + self._payload = DeflateBuffer(payload, encoding) + + if not self._response_with_body: + payload = EMPTY_PAYLOAD + + self._messages.append((msg, payload)) + + cdef _on_message_complete(self): + self._payload.feed_eof() + self._payload = None + + cdef _on_chunk_header(self): + self._payload.begin_http_chunk_receiving() + + cdef _on_chunk_complete(self): + self._payload.end_http_chunk_receiving() + + cdef object _on_status_complete(self): + pass + + cdef inline http_version(self): + cdef cparser.llhttp_t* parser = self._cparser + + if parser.http_major == 1: + if parser.http_minor == 0: + return HttpVersion10 + elif parser.http_minor == 1: + return HttpVersion11 + + return HttpVersion(parser.http_major, parser.http_minor) + + ### Public API ### + + def feed_eof(self): + cdef bytes desc + + if self._payload is not None: + if self._cparser.flags & cparser.F_CHUNKED: + raise TransferEncodingError( + "Not enough data for satisfy transfer length header.") + elif self._cparser.flags & cparser.F_CONTENT_LENGTH: + raise ContentLengthError( + "Not enough data for satisfy content length header.") + elif cparser.llhttp_get_errno(self._cparser) != cparser.HPE_OK: + desc = cparser.llhttp_get_error_reason(self._cparser) + raise PayloadEncodingError(desc.decode('latin-1')) + else: + self._payload.feed_eof() + elif self._started: + self._on_headers_complete() + if self._messages: + return self._messages[-1][0] + + def feed_data(self, data): + cdef: + size_t data_len + size_t nb + cdef cparser.llhttp_errno_t errno + + PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) + data_len = self.py_buf.len + + errno = cparser.llhttp_execute( + self._cparser, + self.py_buf.buf, + data_len) + + if errno is cparser.HPE_PAUSED_UPGRADE: + cparser.llhttp_resume_after_upgrade(self._cparser) + + nb = cparser.llhttp_get_error_pos(self._cparser) - self.py_buf.buf + + PyBuffer_Release(&self.py_buf) + + if errno not in (cparser.HPE_OK, cparser.HPE_PAUSED_UPGRADE): + if self._payload_error == 0: + if self._last_error is not None: + ex = self._last_error + self._last_error = None + else: + after = cparser.llhttp_get_error_pos(self._cparser) + before = data[:after - self.py_buf.buf] + after_b = after.split(b"\r\n", 1)[0] + before = before.rsplit(b"\r\n", 1)[-1] + data = before + after_b + pointer = " " * (len(repr(before))-1) + "^" + ex = parser_error_from_errno(self._cparser, data, pointer) + self._payload = None + raise ex + + if self._messages: + messages = self._messages + self._messages = [] + else: + messages = () + + if self._upgraded: + return messages, True, data[nb:] + else: + return messages, False, b'' + + def set_upgraded(self, val): + self._upgraded = val + + +cdef class HttpRequestParser(HttpParser): + + def __init__( + self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True, + ): + self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, + max_line_size, max_headers, max_field_size, + payload_exception, response_with_body, read_until_eof, + auto_decompress) + + cdef object _on_status_complete(self): + cdef int idx1, idx2 + if not self._buf: + return + self._path = self._buf.decode('utf-8', 'surrogateescape') + try: + idx3 = len(self._path) + if self._cparser.method == cparser.HTTP_CONNECT: + # authority-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3 + self._url = URL.build(authority=self._path, encoded=True) + elif idx3 > 1 and self._path[0] == '/': + # origin-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.1 + idx1 = self._path.find("?") + if idx1 == -1: + query = "" + idx2 = self._path.find("#") + if idx2 == -1: + path = self._path + fragment = "" + else: + path = self._path[0: idx2] + fragment = self._path[idx2+1:] + + else: + path = self._path[0:idx1] + idx1 += 1 + idx2 = self._path.find("#", idx1+1) + if idx2 == -1: + query = self._path[idx1:] + fragment = "" + else: + query = self._path[idx1: idx2] + fragment = self._path[idx2+1:] + + self._url = URL.build( + path=path, + query_string=query, + fragment=fragment, + encoded=True, + ) + else: + # absolute-form for proxy maybe, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2 + self._url = URL(self._path, encoded=True) + finally: + PyByteArray_Resize(self._buf, 0) + + +cdef class HttpResponseParser(HttpParser): + + def __init__( + self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True + ): + self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, + max_line_size, max_headers, max_field_size, + payload_exception, response_with_body, read_until_eof, + auto_decompress) + # Use strict parsing on dev mode, so users are warned about broken servers. + if not DEBUG: + cparser.llhttp_set_lenient_headers(self._cparser, 1) + cparser.llhttp_set_lenient_optional_cr_before_lf(self._cparser, 1) + cparser.llhttp_set_lenient_spaces_after_chunk_size(self._cparser, 1) + + cdef object _on_status_complete(self): + if self._buf: + self._reason = self._buf.decode('utf-8', 'surrogateescape') + PyByteArray_Resize(self._buf, 0) + else: + self._reason = self._reason or '' + +cdef int cb_on_message_begin(cparser.llhttp_t* parser) except -1: + cdef HttpParser pyparser = parser.data + + pyparser._started = True + pyparser._headers = CIMultiDict() + pyparser._raw_headers = [] + PyByteArray_Resize(pyparser._buf, 0) + pyparser._path = None + pyparser._reason = None + return 0 + + +cdef int cb_on_url(cparser.llhttp_t* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + try: + if length > pyparser._max_line_size: + raise LineTooLong( + 'Status line is too long', pyparser._max_line_size, length) + extend(pyparser._buf, at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_status(cparser.llhttp_t* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef str reason + try: + if length > pyparser._max_line_size: + raise LineTooLong( + 'Status line is too long', pyparser._max_line_size, length) + extend(pyparser._buf, at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_header_field(cparser.llhttp_t* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef Py_ssize_t size + try: + pyparser._on_status_complete() + size = len(pyparser._raw_name) + length + if size > pyparser._max_field_size: + raise LineTooLong( + 'Header name is too long', pyparser._max_field_size, size) + pyparser._on_header_field(at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_header_value(cparser.llhttp_t* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef Py_ssize_t size + try: + size = len(pyparser._raw_value) + length + if size > pyparser._max_field_size: + raise LineTooLong( + 'Header value is too long', pyparser._max_field_size, size) + pyparser._on_header_value(at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_headers_complete(cparser.llhttp_t* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_status_complete() + pyparser._on_headers_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + if ( + pyparser._cparser.upgrade or + pyparser._cparser.method == cparser.HTTP_CONNECT + ): + return 2 + else: + return 0 + + +cdef int cb_on_body(cparser.llhttp_t* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef bytes body = at[:length] + try: + pyparser._payload.feed_data(body, length) + except BaseException as exc: + if pyparser._payload_exception is not None: + pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + else: + pyparser._payload.set_exception(exc) + pyparser._payload_error = 1 + return -1 + else: + return 0 + + +cdef int cb_on_message_complete(cparser.llhttp_t* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._started = False + pyparser._on_message_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef int cb_on_chunk_header(cparser.llhttp_t* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_chunk_header() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef int cb_on_chunk_complete(cparser.llhttp_t* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_chunk_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer): + cdef cparser.llhttp_errno_t errno = cparser.llhttp_get_errno(parser) + cdef bytes desc = cparser.llhttp_get_error_reason(parser) + + err_msg = "{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer) + + if errno in {cparser.HPE_CB_MESSAGE_BEGIN, + cparser.HPE_CB_HEADERS_COMPLETE, + cparser.HPE_CB_MESSAGE_COMPLETE, + cparser.HPE_CB_CHUNK_HEADER, + cparser.HPE_CB_CHUNK_COMPLETE, + cparser.HPE_INVALID_CONSTANT, + cparser.HPE_INVALID_HEADER_TOKEN, + cparser.HPE_INVALID_CONTENT_LENGTH, + cparser.HPE_INVALID_CHUNK_SIZE, + cparser.HPE_INVALID_EOF_STATE, + cparser.HPE_INVALID_TRANSFER_ENCODING}: + return BadHttpMessage(err_msg) + elif errno in {cparser.HPE_INVALID_STATUS, + cparser.HPE_INVALID_METHOD, + cparser.HPE_INVALID_VERSION}: + return BadStatusLine(error=err_msg) + elif errno == cparser.HPE_INVALID_URL: + return InvalidURLError(err_msg) + + return BadHttpMessage(err_msg) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_http_writer.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/aiohttp/_http_writer.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..fb3d328a376d3183b257e6ed396cc025463fae57 GIT binary patch literal 94692 zcmeFae|*%{mH&U=GZQisVt6N+KnN%U1_&B()Tj}$Mgc`d9Uv$wZ4x0GDkL!p3a#4) zK}CfU6%~IV)2?l)Ww%sqYc004wOwj$m$q)#TDzNMm_pHRX|*l3RKCyGeZMD}jJVbP zJRbYcck|%Q{dMlS=bn4+x#ymH=l%ZV?70^@j$<-^K~rUvdZXN!8p4_tq(UaI#>C7p z%1$uH+wu&&!t#5(C(mX&wmiJanD8dYK7|zY&NkH7pJM|2?^5nkuICVGJt`0R&s&6< zr;@myOxe72*HV)2`cr+EXFlcG?H?vjkLs&$3Zpzho{KJDXrg0Y`D*CGFAQ&IKcKUPoh{hXu1h0NMt|?Kvg=g#5N18|P9{EF}@A|7R^Rj{_Vk6t{6$Z6cYEJi} zHZ3}TD?&g7Zh+L3U|FN9* zUiAjhR#DxNIqg55lm50C?EeYAGpGK~bKu8kwO0)MU0G?>e=-OD$*l4c%8$>%AIX8g zJ*WJeIsM&|Q(l}y|MNNJl{xk2=9IVP)W0T+9?@HrMZfxYM-KeI<&+oX;NO%ZA79Q% zpOuroJO@8haNtkvKb=!PC#U_Ba>~;={cp{I|4B~!Yje_n9%$W@#kaHgBYM7_1D}Q7 z#3=t$4nKaBL(k+Ke4ojo|LmOdKj)Ocl#||`)7}d?^&7GX6#f5^L;rO->5u2s-%6d# zpX&c0lOR<3pL6;*E(c#-4t;BL>d(n(@7Fo~`%(`4T{-aSoc@*O&~rG4o_xDZRqT3>gZ}{ zFbx;iU)Hd+xuf}pWu0Bk9rc&ZT;A5&T;Fuv@@B8>*d+~1Ry8$TzpS-s`Ld5So8`-{ zYwv35Xl`0Mt+Q=fTooSXYow|Hk>&jJAn>tpsT(7*-O=9(|WlOpmE^l7dMSONg zM?<1xS!>tqRiqZSE?d&Jw7Fqs+luz4j%IQ$>}Xoi+)%%|U5U$@S2SGKw0wEn64Q`a z-B91LvUx#Q$I2x_bXjv(OWV>6!)sJgJDZN-Ic9V?nLgj2h@ zy=z%p>t#({OIn&cZ9A94zyYd!IxcTh6+huOeesI+HpbxmrAsesTe=c{d(4>M+}YJe z*H<*JSkk^at973TmU#=ByDsi(UO_X@$wAS14T+r3j)hsUh@K-E>eI3nW$^}iG&3=b0W!a3ozG<15J5xh>dGjr^SG0Gj zCqDR`rp^{|%1?q_lqDFZ%y3gjEv)Wp?rad#y)K;Jx^#iW4L;r6w7fz8sRc{_ATEt} zPM1|l@{%n9ZLM>ct*||n1YWLDl`Id8sK{N=(AnB9*}PtD0(Mo$vaaTZtsPCvI_(U} zqQuInB}MGIvKb+3Yo(e$%H;VhrmH@-ix5M&pCdv8d|^DT?0RB9zuA*}FLhx@v+a@{ zQgBNc8ZK>ZyQS4KcTi-{?_5}aVeKFt9yx;ohxjj8&CFlnN&mpy6#wg2wl8mPNH7~z zzZLb+-qFne1441}EcFBw9@Y#BzsuQ8&27H9dAT=6ssbx#E^ltqfUEkIP0Lqirr#jx z^mwVHMi7!P5530m!lvb&gHudp4IVIsHZ`}c?Z%bu)SZh~lLQjYObOeO)x3bG8F{6uSHFqxQ$S5TBc|do}yl`df66uYB z(u@=|FzWRkO-q`u^Vt3_Kr5{1!M2X98Ff)}Yjel4C6MS#j74#Q^w=D9J2Z=l3%c6c z)xjpUOkRc~Guv9bnwGV8l9lPWhiG6LSvL9|wj$@pGZQ=u*&t&Fr|V#Mr3|F!eV&pW zA{2CfAe}AR1B8hD%*v4=e^#@W3{CKCowcwPg}mg(=A|%&2E8%!Btg8moK?jasD}2{ zs~T2V72L3_vtb3SXlPp2*3#A0-q6rsgIhH3B@0rHL-Q`0d+`M`8%~>6leMsCMYERg ztXyvqKX%!%bF(V{FGamQy8dsYMcFnnp6Ie=$7!cJ&$pXY-t3nX_~n6ta_#R&kzeSC z+UqL)tRL?3!^YZVq4GehBUY*2-T#>`TP#LQ8MV`Q#E{2vL0mB!R7#9m#baEdXD6`o;Cqrx+d zS*q|Xd@2ghHfFiP^Nnd&c%d;}3NJEdmBNdSxmDq%#&j#Z40~MRd}G!ttT$$Z!iC24 zD7?y;%?htEW{biP8}pdL2K+1v8;yBF;q}OGk7GtMZC!=f>`{f-_T>th3u6_AnIj5u z>r^U)A5{vAjHy;Q!kD;1CR2?<92m6<+33$uSPI`1Vy4ehI1;`oWWvlL7Np$g>MR{!8e7cz&C|)_@?kwW40?i&6phuPd8?#LUiRb3K`dD71kQF zOW|~5b}Kx`m=_ezFlLX!bB%dP;fIXbtMEKyURGF#ze?c+#=NF*CO$-kv)J<}oNdej zg>&##D!c?AqQbfO4HaIF&rjhM#vDZZw+H)pC@X#-E8d$Ge&%-;x#Y$%?Pfig#zlS7pW9v*ImT@y4w9qO5o#D?TSHUY8ZG&5Fmf;#FDk zSXR6|EAD2+!&z~Y6+e79i~m{i16lFjtoSQg@x58`Jz4SHS@CDH;ybhA+q2@ytoW9! zcu!V*eOA0XE50f#-kue2$%;2-#TRA86It;&#OK7frQ4aC!T6?L<0kt|9gn#`{nugU z_4w{>>B8OQCldWEc@>qwR=V5Lp;)pn7=LWP<5C9fPmdmbJQJ9z=_$yk?lAD@(eB^gIr_S#G5$c>iO=jeWU%}PP?oqDO1-QguH^QMR#4YFGQU~Yo0&Q1KrChSkH54=G5QJ{?E($LpRdj zleeXZHA3q-(A@sue#@&wvM)|MCiYNTG!%~Cm}dFo--13?h2V~WDR_DMw)D#tYX89j zUX8Id^roH&n1c@zfA*wp>6*HY{rT}E{n(h!bCancam$--kG2zmbK-OQgJyky5MG3K zC;Ob<*Y-KF-_!O-QY_OI@z@3Z5i>uPXUrokR|kvC{JsGBj!E>rdGu%nOWQ%lH#H-+ zu|LpDeQ<=_@1$qA8`F;aW_p^Lmtq`PVHc-ZehVt0I~3cPjzM224m@K$3px$(;+N># z1HL1SM+lmn81$QD>N^@Ac%!v@<6ISAm;RHFyV|TvU*?#C&36F{4dHIq z5omhEFR!5-KYfAnR6f=6JdwJPJmbrV6JOgexrry%rK|jMLq992d!FE8J?YvAG8wzA z-^A8J)27}}`uGKh#gMM`;i4HhUoxJKfew>z3k`Df~S~E6)#XGns%S1w&5l1sIQoc1(iM>^t0dz z%Ad&JmJY`x@6ub05##iOJo9?bWKRdh&3(47C>-RY$I6s+i=(;BSjFAj(wO$>m!5RC zZn@T{DUY%_v@>Va(77I?yf#B0{dY&S^(6z6oyPtr9CI*6S%#)OWL16m-rv0W^R1&t zpA7kZ{2n}>0}t-^+nWmyzIpU$LBie4@k27T#?P-OU*om+LXS6Jqux??9lAT2Dl+#T z2y5;#r=@2W#W$xHBa4mTxXG`72%I(KRa4g9yE)ypdvp3@%%3Xis9rhsg0W;ON?6Df z=3y?RT(gmNfjBU+-i_(8yMcq(!+;IY_D}sjy#oH)GqH2zqoY61Oy-@~SJlUslcFcqOdr4!x+j({p z_$rZI*L@&8rf6PjxG^Wakhd*8=EupD>KNcd(Eki|R6kSC(2p_HMK2yyJ+=u2o6n%$ zH0dYgi2jQ&>&RO-aa(#;_r`wlSY;XgC>`{)=!O?z`T#%rR{Q*58}y{~QT93}U7ov+ z8OCD}W?j0(5zJ<*hcohc9P*S4$M)!5aOn1fug&u0;}qoMWj|g`{3Sm=h4>48d=l|p zew=ma;4^+aMtp}KKc4u1UY?ZBPgM|?Odh8`b|?Dx!L#)>vLm)wzTC=KOBWdTKE`GZ z>&b1%&4zS$&;9A|`{T>Dw_uy%$d=@Q?Gy9Tu8niN|8rs%&h%A;FM0i6L?@#*eeG^(Aus1_d%2BS3TBO`Y=>xo`2`) zyJY6scaE|KB>Qf4H>WEN^W3MigSqm)+RJI-W3xEkDK>-$36NpT8~L%A8w7_%Zl#3-JVThjO zb3EVR`A?oc9!XZ_`(e9WN3F`^R^6ccE*N!&Fl#_Ql&$&FO z@|?p{#B&r}+9wq5y{z9fCi~`T{Cav*yXP^dyL(f43E8DR=}PiR#p{*ld@p^fq}h57`*d=ZKPas6t9yF zRL?$Qa~bod#KhN?VNX`fqOSH&vN?bFS7>ZUFEdYGRh+RNTwCr;59-f{()rZM=tSus z?7af%#l`9;I8K7LH`rgj!Cp@CX1WL0zRaHO6M|(KHTAS#Rb9bpFBv1PxM0hvABd~&0$aC~J?;kRThG%1jyiDE zf}=JYhdZ-ZIL|Nkbj_#7t?B)?yR+}T@XZ0&ES?znwt#Ogb>|My4NdW%L7#2ESnash zccA^Xw+E>rFKD*yAB$|g$i8YUY3&Vde`4QFyZ8u>eAF?$*E^;b{EaP+*+qJ(I@8S=55jQgXTl1t7U(+8ni-;|1lgZrqZKSAFU)?>`aHCTpsVws1DPrif7G`*F8ySFZDKs@hzIDi()WD@a2M+?m2Y+^9Q6$B(w54iC-CArZVyL<-Z)2 zkHW$hQs-IHV}T3BWYa&eznpl+Ha`Q}IV8=vlBT= z(w@0C^{B=J`+QKZu9N*zU>fg&esor1ecI}nP58pG8}h)P(X+pzPZ>HgdF;y$UamH} zX@mYC5vgC$#`a0*N%m92)YsTUo?nW+?3R(9?J4q+$alcldt;Vq-`bvneIGUsClaZ_z75@@sLemIhUCi0uhGMO^sy|bkBnjI zr)l>k_E*99L;DSOQkeDfW0t?zmYQSi)1@P7cRrAwk$fOs6T3ZK%QJ(=#E)&?Ym78^ zP5jZUF}er6rM^F!9-cKG#$4mWK9U7{w-5VBx*!X-96B9yb;{C;Jb#G&Yt+)dsrO;} zmurV|%u}$Bz0q4yPhY5>#!PeJA2e<`GK636UAzNt#eLx34xS8;9CK~oHI_$@4&{;i zNP0&5Bk<^Mcyu>Bx*HzdlV)v39_IP|yf>?#Yy5tam(@>h4W=%%<2clIINz?PL-ocC zXv>x7PuRTs2Ye~d+qB1b`4v*)?Nq&ZA(b)+NlH2aLJ$vhu&1*8QmOO!YZVpIKLe zz~=$4b?`5gZ?`rvV?;js)51?50zXgn2jFF62Ms#LoZp-A)9nCWeu0yHp7yZ^`yzX! zT%LaJ9m$k{(Ureu^sz@bpT*Y^Z(2_K~thDapC@KdJp3U(lgDWkY%X zsY4eH+EDLaqZg%q%Q(gDSUkL6u%Wl5JBRAyUotM)er(y@EsH(dQ~7h4OOgQtO|sSY z9X@(cHq}`6xDLDt8RkE8KiHG(n*!gGUz1I?C^dYiY^!7+rYkCLVd@;#zV*I;J(iU2 zy(WdpUr^q7pItNaVxHaT;6oXPjD6iPPv$jZ+jJ*W-Q(}>4aM%mZk*q@7GG!gnn(6~ ze9@WB`g9F=L&iIUl8jUWE8psH$qe@04BDw>tQJ`r`uqOAW302-0fV;7SnUU|c>aL+ zVPe<;1HL5R4j|9713X{S2eB{0G5js)f6pGlCpsWkw;}7YNA6=EGiV=b?e%1E=-OLO zpDmr(l;xk>mM%zc>J6Dkz@11j-K<|5VgMT6KR$$xlo7=r1`2p}mvGGFKKMr(+<6F~qE{ay-b}oue z;=*U=Bx$vqJ15bB@NV$DMtt*lJd|%9kB80?_05AFI$u55T-$h2>H^l0XDXQojV=B1 z`)B0+GtgDu?#cVGn78kmZG93~_0484s&UYm)a*pJpl38T8kfv?ECuJ%5PMH_bO>9> zo(ba{I9>cqCi<~W3Vx}$%UKC=%_;fDgBrseIfd`uzV2PJx+pcDy5h6=Exy+5L>_vO z3rm+r&->%?2eGTK_IdnpmdxMf%lyOamj-2i>C@6NS6UqtYkxHTj$M1MN^KT@dmc@T zxAM{FQ|GtZ)0(UMSX=w5ura#(?!=GqIJ#s(-;=^WohW_1|_Xym2@5 zYF-C9Ckw{!>?yL>jVAbdy7XjH`_yYvA!JLs@$jGMOFXlON~F%T z>xAxZ+?{S8zb)N@{dF06fkt!(dLRU>>P49onf*W%UC9~u!OXnTx-&p;&fMW_tKu`z z8%5sbO9&tzg{%`gyL=N`qLOviI(zOAdy&0=@5O7` z^WDxv`|n= z)Sth#k{#OmglLaHoZbT;Pm9m|j*I_I^V5xWbN>NDPA>}b48Ej0 zAAn~%pUc38W1fByojro1Og@WQ_*><# zy;yn3%MX!v%2KaVw!p$A`n4aCA2;S|tsA@xR8G0v@cq;Zit2-lV|W#i3gi$L+hM$ME>}7yQ^47L#FOK{EBw>Fn9(Z z_J!!H{3zbp>ssb+GR^+50>4{IYxNP~!~f&Pyz?x_y^S$lkaFGI8Rt9Fvhf16<>Frn z0k3;gxwfdS%UH?ZIShDwum=|{^yDcfJF>^?k8p*t=?n2|xe3M>el#L0jm6&iUAD|P zNqo%AWy#EG$V?$LiZ1OhB?INGUr|?U*aKyG@uX9jxV=PjRc6zGZ z*w@znWiJd}*c{9aXwm(fiZC#$FP}h$Ug_;FUxuDl+sM$rNQUZ?Dg0swcUgKonapla zxbi)@t&n|?AM@5g^{Gwwndl3$X!mz{eqY)9+kD+8=}LGq*FMYhnMN6xnya{rhHWjM za-6#Ksow)1BMjBupDt{C zI1e6|o(KIeU>9f0f1v#V5gHEA4;G@}@KuVr?nx z*_>za2Ooax=>c>W&2|>5dTd zTm8_SxAv6fb!NQacaLw+lP{QzjfCx+x>|S|lc~F*A%kPM?o`1GbPKjgz3zGz)Z@$4 z91IB;W5YgxviT{^Inkvy4w7f>QS}YolutkR3omVc%g@t#keQ>{+!ck~eUV?T5P8+P zjUg?1Jl}Rt`uo(Ay(wFY`%?Jyl6|-M^lc;mW$s~UP3`jW(+|#0lBq3}eL{JxcUn_- zViWHy(V9AVCO(t$PXQM~9wh@AzFb6JX1wqLQx0#F$-XzRla>f4>#5d#`4l_McT?T; z^-Hu7Go{>FO%@lL&3OUhp~QXZF8Y|E{S1Hp-9)`A=&7s256Jo}9#=QspI!`aE(QNv zxi(PNeCBA+%Bs?%8e`u<$v5yogObu+LNvS732 z4xf8PMwXL;r;nkS*Uw5zU$XDp&tp8SY4)zkE9Y_E%_AExLHNpLj@iQ@&@P@3 z&w&}9-FN8xZRtbsQTNY+@y)Coi9U)7dYj;X0=uPgQ}1K$gXw$xKFnnN@t3Dgh6lT; zC;6M3xIbOrt-I6M=E$MsgZ)*(cIqVGC5xK}))ru_JuZKmY~M2_-?aIN<jcLE$`3H6-kjUitFz>va&G*JU;Za>olu4!@Bh2_} zU$}Z(`h_W;Ef=cmNe8+g*#9i|>+St>SL@PkoawBywsEir9o?w8Qr}n4_-qDF{9F~& z{fqiOolVuVXLSN4DRf`KD$2t~c5}w=ncqkI1xsx`&n{%|hrNrP9#~NwTip$tHR!WKEY;W zF|IS*_GF6RHyqR+UUfZtsXP4(^1f&L;>p|3NZ+nB{+=tKS$-Dzss0riidAK7q^o4p z7ex6jL6p2gY&5N}g`}--%GJ8llm0L89Jygz`bKEWJ&&LrY?-0{PRahu1>Z#%5BmSF zf`)8A4%>x-9qb80?7=d&|MQG-A^sno9qZio>&ON__)CX-nfO%=J-Zuh038 z^x{=1)IIze$^&mtkvTu`ez%lsOM5Uw?HOa`_1)(Myot^F<1%)SaH(ybE8L~=VU1V6 zkA-tD`;-uPCBNbJjpj%06IeeA6y5pX))!9=pzk3GecZ|N-`3-*ydwT5rJ`VoW zgY&)k`md}t`Pn>02bnCMiihvD|E4eS^vV=_8hHBmefqK={#pJQ{04((EO(@r(2tD& zVg>U>e0yo>Ht$X_^Fs4JV-x&XzGcQ8|MS5v_A}bYWaLt^`bB7IwD&MP9eAJR(IW#q zVjw&o^}wU{NAkc``oiyzz8cmExaIE%A#$I?(x(39-@ zIQ{u&)x}oO9i;=<{|B(mRhDh9by)mE_jCA<;FBkV&o0?E;FA^4z6n2`AW!jc5PvM_ z*@^4?wl-oX^1GpfoBXu=lgnv)6>Vp?TTeM>&MEpkEA5YK9PS31M9j@&Bd8vawZs`%1F)c)wVa1ge8owQ6`X1T| zU^7tGpPB#1gG=)JjP$%@7kRuE{kr`+j~Cn2m#nrQ1-{2G<2N@4H>xa|?Bo8x!3(nB z-Xxvr)2WgZ51E~TfB9p?=JAo^7l$pRG)D@iSU5I(JNY77)LKXQj$d<9-IuV;FBO zJd1di;}2YJeSz54+yjuGP`{^@FY6g}z8n8ZnwJ2i<A; zfja~Jnsb`J@+Ce3FDua{(wSCq^_`N$YZMnaedJvrzAY6|xmo+Jm{b8A8 z;pxPEPI%t^498WePnw0nJb3p_epC7qzD4m>_d^0^q4O#7&OB#!e_;56)N*5{@60Lx z7s``4dDj_p_r!v?x-aI)Knb3K)!9J;^O!y3EY$5z)fu0xlD=l7yvA@;Eqz99I=k-MFJ;v^yyHc5U z!a42e_p6$xnRZ5HwNr7dcEBxrC``K{+MKk6b{dCq#yP*QyYUX@>t^lna z@Lt)c{ioJp>C6Mdi=Se%~58 zjfOGp`Q8xT%MUjZxsQ9!8-U_Y^uNV5fp6B=Hzmrjm*O$@j;Oh$$hVuGK^7vhd^*3$z`4oenC5p2q z-LEzzhv=_CJ5qAkTZ&u_*hr+UEvbD?wk&Ebz0apNAG}BY%fqYvNUNBmym|K-=y`mW!t$zOVkU$27lU;E|S@4ex#tCRimCn*09znuMK z#a_RBoXQz*-DUW>U;bUnGi&)Mzy24g|6{-W8yPluQ`8UAPuUDt(bvrQv*%_0 zZ{{3fWBMuTEB|BQ%D~Reg8g|G?B{*h9pDxJF7Wxs*_p++jdJeH4&a%dg$EmFpv?z- zJlu)2c;Y@D`eR`>QvN;4UcyK7lJ(KtH{hfBC(3rozf&ijv8nfEoiRa6M#nhB7XTv} zapS-EY~4FYpUjn!|AJQ;8#=Q;W84q6_zEBZJ6PE3d0d|DT(+y@IY7NGoNzOE#_}A&G4~qJE*{whd#ZU45YMeVTFXt{{QlY% z{9fo>?@WKWUE4XIMi&NS^iAt?jB`KM)y2dcd6u$%huiN>^WNMF){4}#$grEd7hlA^ z>HNOd)p|b_{jxoJ2g9jfbZ%Hd23k>*4CQCmn9}D}<7l0LCweQru8)r%~ zl>lx=-A4TB{8pWZcVwjNV;j>?@Lr8A!fpK!!aKjO5?JmAm{ zSIEnxACf+x-BN$-;Rn7O?nL7|bAlzQz0j+Da)5J{m+5a|J7?Ya<8+qi`QYv(?%4zK z#~EM;&y2dY?gu-QuhTwxsLndpx~Y27t98_~za2rI>)_q* z>GxIaJ5KQXIhDTDG1j?vQv&cz{m;m^@M)e1-@j|$;^T|Kmzksse0<|R06vYE&aCno zE8(rBf18=Z8i!Ske+XH-0ems^%N)kFhCQ3gj`Q2n8a1bVYkDr_L&t%4RkS0Y);GE~ zE!>}GeumrmT?y}ispNew0arG?WO`HYdb9C2QSyvoj=1a_c~?rIecuaqA-17>a>Hr! z$Y^}n_&Ja8o)Fdh7<&TgkSd+oCbTcz%Dmc|*7}?|cfBFsR4n(;U27;0b8e`$i#6`a zLY*tRYt^rG(BWPL{I+t=-I@mI&G4SR*uf37TU+P-E>rVkhpV%Id8xlKo<{!pZtlx= zZ_JZiAHiQNIz#w}2j{JRpE|F2ZIE$IFpuE%RPdezpKBz??b`R&>+Hez8*{gZHqcIe zb@V}J#D@NAtrY#W?nB&#dnjEKyOVpUcQOx=f9%sdD>vR*W{iGi`Vey&Bk1+ySN^@3 z*naY1z1MG3_?^6!^`Ykuo~#f3tyS(_fQR8hBC)Z*oHjKU-|~Myx*%kpdwJrI`V#bA zeJF(1TKunrHd=k(-9hF(b!6L~DjihE@63?#MT}hn{@1s&cZLta*bDoWr}0`8mrheT zJ~#B(CuqOm7%;jER|%ZyM)t(R?v3fyAy41!dV{v)Q>4twKuq`7Jzb}{CmHUs{!{J^ z5?}Afr8B$zc#JqJMCvxq`VW(rty^z^rUMqv(|=zTjr8;1)h=`SAJp$GefRCWL4EhV zybrGLSf;o);Q2x8+PyX4f1>x)?-}s*gX%r$%YX8J?=b^DzDfVMXVI5OpU*)aW@sEZ z(-@S)+tSHxtQ%H-bM9)x|BMda$NaG})Z@v}aP<>h&eyTgx%>GP?Z~##9hOgvw>^pe zJo2pk^dKiYH>Rgs+4#Y`>g1&na1qKkPO9rmCxTWN}uV52;VU zHUfJw{c_A4^kgD+Ptd%$7=6>2+=@=!n0^qN9>X`fwg=gKA9tZ<80lZ`eOR5Ubta>K zxyNZ`esHa~_Q3mu9ZNsP2EE^@W}lfY(OD^LqTQF8(#o_<~KbVx*EYzBfP6KbD_RZ zYqV(3M=l;iR3g72dS15jiNIGe54aoD_aWx+-1x?R*;TdJRf74N@Gy2#d-r08LxX<*S_2IU@QR*#Xi@vs?$-1j@`2D+B{a`y z->UcT98~=gj!!dW{{_c-4D0NfKi z6UcvJEboBe+04_!(-P&^k>LIr&+mAmrTCeP=@(C&C(3g!`NOGuA^;uj#W$xb~C+|lGCb&19vAgt+D-*vh zU5@O8h=+)eB_1XoCSD6{&F%-d7p^ylZ1)|6J0u4Eq-D(bw|K;F-f*o3(pm z`eyo5!<`=W|4H=k+-~+bNzKhg_V-m`*E=IR8#wXo)0_cj!=Us1-$AY~o3#`E(x&Vy z&J)Y>`0Wd88Sjm`hwFjYkoSlWdpBv`am8FRJJ+N`$u+z?XpOF)U>mU}@a{nG4nQ|^ zjeP=nZ%z17Upcz-RQz8r6W6^$L<4wirvdoe(s>r%vzug-mNRE{_plP3raoHxO?&Bq z-`pMh{Y`J3HZGko-r2RriH6-;RekrwG$#c=sCl z!r#@OVSazcGCo>AGkp?1;T4Tuzo2oTUu*q-`R|yrb?>!j%Ch-B$nX7X3^KCwc1yF~ zaZsB?9+JH4p!@dsC66D-c4o{2b{!phN8xXO(>glzj>2K|?rh0ejt!wX)?(M)p?9kJ z9Sy&g@Ob}z=FyxF06X^sz-n&RSU!q}@HT6X$;Z0oH{QINgU$IX;@LU~{exU3N<%q1 z=#`pr>GrarIw-S_Z39Px@HCH0Z}4@H&PU~Aam7E@^xg2>?gQPe>E*!Qbi^wU`{nYR zX3CdR{tmovC6pXbfX=6dAGylt$_$+*htBRZ#-*bp$EELsj?8+y1G=PNSAydV;nZGo zz{caw4CBf9>$}EZzSt?iTOR;0vcXv93fj*cXMJNCAHWXwJ@4`X!1o#L@Sfk048E&l z9eZH;j)vN6(rexx?tT1@S7$kz!|&rhNNzv9wuj1i_MRWzP%&rnxU_TipnbLhdq=i~ zeqT`|-Z7R}`g{IEvwzh0_xAh3xg`hZXR>gP^KpJM3+I4;09kSP?ZYD03hBLH9-w{B zbl709UmvOqv5y?&(V6nMqXpjsPWBS%zKO`uYpRDFZKjR!w0A5y+KFEvd(GVg{yF92 z(wnp7sP_g>j#A)T&O90pUlxge_OT1HQ@k%qKYQ#&rbleR>2MrK93 zWOfg@*7Iy>8JAw~&#hs|rP@B*Z=2sL49uMefIW}4j{v_3_zR$OA9=^>GxwQ>(6I|T z;-kln&mNav2i`4Nc*~c0czeJx8oWth zYP#R;!}}b2ff3p-B@_L1$&GnhkM~R&m)-+>$mO?E1HO09hxd=Pt^MpO-ZwQJ+~TQt z`4;Vc%IDu#kqI-M_8;N7TXUJ;kyngMuQ_jRzuv>D_dROwlYbNM+1j+ef6aM!_0QeO zejvHAU%oT>`m|22Id4t>SVGw~*fi+`&+s_5Nz9usnm1qY`E}(H_HOvY=OEKs8y(=b z(>Lw4@_~2IyPBV4xGyaKsNTz4PG3Xur+{COdfT3>c<+I60;Q>~)XneF*`@BM>Af8D z^$xLuQ0(jIHp$NX)W1njfM2-ZqJB#pA92scy^)@^z48ke#v^*KIlfeEir59cDi6dm zWq~y3W(PZc`eWEwUj?7&*InU!KYtH&%q5;JUy={>bMd4cIT(A+xOB^yap_00?mf?S!A9tKKipRn*h?NIzx9=R@F&e1I`{*2f|HAcJEnIArUMWgfJ! zHwnfs?lrFNec#qQ7hNK|zc3a|=QD>S|C(P%E<^v+ZR%Zf$~t_TSM_~Sb8iCY0RDWt z?TU3J_~`7pSZ02*b!08Q3faQ<#hibfw9Xzwyz?hh?+@DVoiHw4KaDY9tQHX;^t1G& zcS36&^KT=e=GhOKm+WWlywv@<_sh#2tsXD6zGe9E`mdQ|@Zp6IjZ42kyP6NV>(MLJ zJCU}fOTP%L&KT?5jr~{qzPYu``MUP4=}V9m)$hl@q50&tdHVNp>bzeX>!_pgmTYHe z{0=noPUQEEqua-!wI_q)%iy^61K`;0~agg4?Hq<$86LzlkrzXkk zPNsg&`)O(flWTKQ=l52p54Fei8;PCZ*4X|4`S>I8W9fm`96j&`caZJ-!NHq5W?uux zEj)Xhx23nz2id!SL@(<7;F87N_^0)L@Lgp?@7R|?_h*?~A@+{-$f-@Y=k~e|0)+5aW=@zX^ z*=v&e;>nq}E@}Q~9=J<2Uh-YsR%W0rz>^uzHT3I$g7dW{gE(JLAAS9|JQ-ds2j>LZ zkR5X(p~mLBhmTf>KGF0Hb>)YgsQ$30$-Em59mYG-IPd4(aKD3}+3&AAIqThUxDE?; z04MwA8RC`)ti${!{MAC%FWD`hKYWz?mpVVvd*SZi2fzA0L!QI$&GWE%WEZ{4oT(0a zV>H?4`L9@4<{(#km)W!QDMND@nm_H!LJj>p67cGcRy}n4KI-LlduPDRlhhag%=rfI zm*dV_L1FJ2&e-ow7sWIl@|i)Cd*42t1OJ0)f=>Bmpy@@`%_IIaec|0K`$E_pnnSWP zu+yH*yk8U-A={byz7^Ep!5s;eA17YmL(===}-`4K?_7!3mUZ=L$7s=1VFR1$P z5xyvX@Y_V@YO=4Jc65fyyP>fE=G%A0mE(7pt*rbv;n_Uid6hk8SJ?O3d1E%0_Or(f zH!Jjd?;IRUS!T>Eo%E~F_Iq%AI72MZokrgOY*q$QW z7#a8rbhYCz52A~*-%)oGeAXD?MlL8cj6t`~E8aZ@;PuB~kv9hIy63T|kGtZGLC=se zU@aaPgCg*14349IW(?F%`wlvIuW_(r-Fx4@BKQ|nJMdq;*H}C4cj{f!$Y-+eYGh6G zgfqm7-O9`A=Uaas?B{y!U*-05QqK7O=C6a}wHB5=*D(#>{mgbKSDR-^xY~TaXe4VqC50u(3>^8LUT~|JjYYZQg1-@0^ced~=Rxa;awp8C( z)n}^hcQ|eSjm@hK-``w86~p&j`8l@AmwBI01|oy-dhgTBW{FyC;47Y810PZ~{s%oz z$^M?_G(P+(Tz=WK>@wxkWs~)3TBDDidfyD?{G$05wGwOVh%IUApldfY$LP<>j@H7 zKZ7mAs;Q5d+V2({)7lJKd_=Z6*45I~8k_jBr7?zYW%I;or*_7=+F~nP+w}oj)791% zThY|I+AGZ}id8kQYWI3aWn5jxEa3~qe2zLcael0`rETT%rLmT#n=@>oIojbXvt3QC zOX&LbF?~RqPqBI*(5|)wPMj}1`n+=U^jLGIEVg8MQ)g#v#mdgE*mcdYsB`6YUREv^ z`h_&bCQn>AIn(E*&3vYu4_5PcOc_{W%*4)E)x^%}6V;2@EiKEIH#4SQSDIpp)qGaG z)n_E*zHshb2D%ebjoq@0qLp2-W_>tZV?6Nv+?o2gxS2e0+8OcAfk9|#(kR55G9L@J zWQs2DW4N)&+446T-XRUk^-=ZJ^tu_|S%Gg}IxRN8dFnDgM63DKX+P$h>1^l9c70PE z7~!3`blOC9d@r&IdIdF*EI!_+bQ4D-CN-a^QHCL`%xs1unH-y!mWm$t?TXQv2>do^mL{o4Rr=3Qt)4U+lg{GK_2lzb{rjsvp zYksxf(7d!7xnydzqA>VIdF(nqM&F^ddJ9voTeh63Gc7hdOG;zc^DXh%On=f<$8KOw zNb+rVX7D5r(_qj4PFqX7Iqi*Y%u4UX1@PvWvg+$AjeYDrlvdVfx_w3sYN4sjbu@uL z=(HSbYh5nkiY;$LB}+{)^U)oOWIpyCYe$i_ceE`*XCYOhP-EB7VC!^fM7@~uu1Czg zF>dQvcEhq(Oix3d0j0Y98=l<^l~TP17FetT85MFQzJ>o>f*G9&Zg^| z{WSzSR<BWct4o3K! zSFsceTpWeI5NxMAfAm}b>-l?rdrN8_g; zqtui9+C`J^v}Y7Fi=ftnTiQBMxPEP4(+srdmk+8`C`EB=@($odI##w0sQCB5ICPCa zf3P{rc~6IFMs{?tQg{kw~}FJ+Zw*|Mvn{WLm!xEw_dG|SiEGQ{NQU;$-u(#Zec-~Vyo|2XjfCk}L> zpLBPL?T=Z=qfn|qVH*$IBU8`mfNb#c+l(1a7~bR<&S?zyKsfjXhBW&{oBrcFN87j# zWb#PA#3cakR@mRCYTt1!X|`B~J-=Z;$!5&q_?q1!|8eceuqQQKS2CeeFFpgn64HAp zCyQ_H81v52qisjn^BpBr-9v;`q}e;S%^>}L|6FL!{58_Q|9k#E4>J7v-we0&ZE^iE z-u7?TX70PKHCAqvuhJLDTTk8uW$>rGcJiX+Y2U3s0llKC7niKX9z#8&)k|%lf@_7FfdE3cD{0H)GB`-;y zWZM3Lua~^dDu)tf8PH#I`Cigj)ADz3*3?Whe9b;jWaDksC$!{zl&zhoF1#1-_+TD z-7-wY+G(dxi%&iCOh*JA< z8SPXA#yS(6A40P?9wFy31gG$P8ofiBj=w+|D%5#p6uQ?0L;0nr0;_mlDCmT5N27(# zQb{0xb<6@30T6VC-APG+7uuM>#8DnV-qX`b{UZuGFnR1u>I@6zvDYzybyLZjGEztb z5xNoZ8jly%CqFW9X72#WY;u@CAO2qeBk)JRU!OKU?BXMEm>!1l< z5&kT}MUh{s3-d;Ng~Xglo)BDp+`j^rh!i0c!D~nDresm%n_|e~(LW@yIP%cxBtC4( zX^dPSC-IR8HO%u<)LAwcj26UnP(QlJkP{Cpv zJh^E2!<8B_t^)DD3JNt~qU$(-`O6P+<%#RPkd+_$hN9n~AV2hdq865)ig~b;$$g6& zA>{<32t?jxrN1Pj=uUmSw+7^`4&`q2%m@B1*dt9erW>nv%GjK zohdlS#seQ_Dh@9%U8HtCdmQo6(Hj-NV=D2A=qD7PK>NeTM7Jvb3p!F*Kl%;&8Y)FO z1dg(L6n;3WcrX+ynMe>0ZHD{BuTyedUeLA^E@Tpgi)zB1z(tywr$uK*ycu=Pi6qXl zi4a}76o3*z6{>TeB4P*DF-7yy`6IR!eS)l_pF-Y=X@v1WQvyQ&`(ejoaihOxa7djXoYCmjU~!uqcN#Ob zJZhMG?sd+HxunKMCCu&;r+5{qSX3XTaF;s8I|wVIm0)(8owAqFP*u@3#=yP7DbkBR zs-t`1wR@v8@>R;>(cg)d>EWCeU4gW?T~5h1Am>Dvz({wcQ}PO_xzW5BsZ~z&4R9u+E6yVIai{bW zsIQNHZ!)QW@Hnw3dM%5MyT&QG9ZoKePGg?C>zw0O(_Ulr3;ge{cZ#E6SsERudiQud zYl*t2kouHUTu0gR=oQmQZE{L3Bh??E!^*nK9AI@=wC$VW@ohS z?cW+56DRe6V+XK1`j6togU*N}jM%#9kA?Fgr{o%Nu8)pF?YUc=k{d{Eh+a=^_hFBg zp6E!`d&DW~qHJ^YIHslhs59c9NNtIJ5utJ)bB>apnCl9#PckqeiS(H@Q1<6du{ zh~^<(?l!OW?a>dZ4@obzBf3GO`Drh;Gg_iPe8x*X6aCLBQvc|so{c_(f^eVkq-R(3 ze3YpBd8b4wVs~`6sQ!Xi_5#yL@*FssiR-oo`Ej!;D|Fi<64!{8-J6Pb6E~5By4PW4 zHEaUSC=a(YsC`dy7)h;ad1iIqopyK5KiqN^~Q?6^+l^L^N{0Cha$e?-#O2w@SWMtY*eW9y*1@ZkvcjMoLb< zZ4;G|ai^2`j-{Xq+ST(wvqb*8*e=9xmLPp^gx=DbA3Dtcwr9nNvo|g_W_5LbNU!t^ zTqM2qefLBl@{BKb<3_y8eqjx&FZ;ZInLfw>slD6;~ zwmb`bQnK*d5%*ds9eY|_I|raFRts9z;~t899u7tL@se@>=t@LQSuFw%+eBgHTG9NrO}LRCYx@4h>PAd9O{2e#$Ol__s{9;H7G!HEJs8rD~%$Y2t;v z)Qsq>XOqfvEY7;XWkyq9j9S@7$5ngI(v@%A@^-?X-LsG-VUTS&tcqz0J zFV!A>Qdpv1sw=urEtGkwRncoCvm?FKtqH5OHnn^ty1za=Qybi6P=FOyW_n&p(sB&HSPqbL>eO; zjY?cj^iqXUNv&Jyan_AKrLu`mnN&wKdI5;tNnTlb^ed=(ce3M3{KrOb7L8N97Glv7 zrB3p2RCR@d8$1Vh3KQ7ZE zbcK(4y{2!%PfXJco#&KkF?7E#u=zeY4@piJ_=yrpO}$g5ohh51Ok*-XM#&HzY|*%D zCjh(9DSOVs?#{rzJOFE#y!?=)CO;%KiLq_tlEnOwWFh>Frc!ZjSmsq^6qaT2*(EY- zP2{sMyLfu>zr(Fi1a*H*nXam$of2B_lk8Ij^yA#wPeQVFVw{NyAOGi)Mc%G~IAdHVTl`HgWCtt-hF zNcoMYn&|m99yVps=&ZajD_7)2=#I`FrMQpfLW{*Ug)q>RlW%uoBUEQj-i(1d7yESp zGSN%?IwzDz&y1`AX57jpCR$r+qu00IY@+ApKMp~$KQP^+7v!r0v0orE(Tnm$Xza_U z5Wh5E&3O&qn`wBI37j*E!nr}UT~t4n_+=-kxafySWm$oh$D&DyUfFOjeij(Z3cdKJ z=tbFaUi>`zT2|!6Uq*z=MtJeh#!sr9&yz+~k{5|x|jqXJa zmS5r&StQ8!$DrEX6esgiCn&-zD$5g2H`2uAr;PVgQoP6(BM#L25*{F?|>d81RJlH+He zNTSIpi79c364yB;lSn|}F6hn=?X>?t!T%Li<%^xj0t!6>KkSSZwI=!kD@yqiC;ykE zumi4P4_Cg_304DHe1^v8246GXb_R(SFL7cCq{EjI()yDTR3&)muFb|vozbAX~7wF6h zC0@K5C3!-r7ym2pCq%vYO~}AFAAgPFUO&p**yxBp5MuistML0BMt)*rMyR0B6sjX{ z4$>Mp2u-o^!EcdO^jRc7R_V3jvQ)$-+IU%X{HVyBQ9j=Bsh5IjPZAqv*6BzaYa)1ZsaDGyb0q+sY-d|78;vSWvLts zVRw@mxKsdBf)9$YH%Ajc%_Hn4wC9A=z4+DWi3v4ce1eEM!;3$PmYi^=7k?R9n{bvF z|IkF@wO;&_z@Iq6i*Hce_2RFcMZDOHpQ(I*oEI?uC;H>;ppGj2v5hhXD~EgVyI|nN z*}fbiBNH$4^8W;fCSLBvTaoFBS9tOHv{hVW#8V zT60Bk!LzMw%(t8ZXsN&xFt9jk4Y$B3M5%aWSvAo4q0{)^R!+RTvS&L6WL*`XH&zxB ztHAY<&jV>kvG@jm6h|_pid#xl5RU8;ZOcj|JcW^Ovt$*2)F#}>57mPkZ6Zq3YB6x` z+2k$9`_3r-N6eT>KG*K2wMkXB=iza1EjsCBx0G$BZFo|3&~pU61Zk6|jwq)f92pHC zCQU0+w+kc3!SzX}949JVGf@FP1i%79HYpzbiDi^ULM9-%N#_MmQZrXGRcj_);`XV|uh0>bE{&c*+(h0+5+}_aA;U8oIRRBM=`x!r zkF?Z~xZF}UHd3#|6|R^Si@2weNQ@P-%E-@1^Zo;=F>ZNibIOpD3oHc=S)6c)qe z(Kg{mUWE9`6*du#e3zLqd5lezN48EUG1ex=Mi!q;;&_{gMM@Z|$tT!EWu$`XKY5%@ zR7Hj<5wnTv$WP$=o205Z_;Ywv z)Pu6D@+ay~n1od)d9D2g4ow+dq46tv6}(f%c=6MrZp!hV`SV8xZ%WLI-va4Vrg(LK zfK;92Ed+rdv&@~GXIJLHO{|~Q6=ho>JU{d}|J%9t6p>N(zgyrvCC`#EX*x1j>r5?n zpMrGT&8a26mM&v0n_3!GmBPrG@NsIi^mSys>9G7-dA1Rx9l19o9fjk_;c_v458|nO@tz~h*kA?n+Qi{C^4b*638r!{GL^# z`b4|yawGpVnS@7KG;*@QCfYjXkqu~v>Pa>+HnNPlUOm|+Vv&!+f$A!osEjyh-0CSd zQ5D%kr>niLRY%@})74(r;*qO`y4r%(M9!k0)l+SvHZn_frrE@d$eXBy>bNx!>msi+ zh}Easl39`2=a4vkgnB(EBKKu=jRl(LVu#>}-o*QRG66 z(R5p~IPz@l|7-8t!{e-~z27uRo5^Kznd!Yi3xyV#Ce5Wuo6>gLrlo;iLX&crmn1Vu zha@v;W|B0udO%SD5kZO~LMeAp#hY9uPT*N7N%Ca!?Vz-*2tG-+57EN(eAFa62o0mH_jeN%uloMg|Jc1G^WxiL|r0II^Sa-=Hr7rR<^UYKEOa zFa96NR6ha^7R^Y+oXA+kr%>gRz`v5VaRI6VMTm~Fa61@Qs^A2t+x zo{h3wDG2N!+D8Of82C9k_fY{NfrXTwbA&sK1E)bjMb0h#9*AiQ@TRB8`Q?armIgk7 zks|VGNpno#Ig)ds0MWqL&}k!|5uhzFO3A)Ra@!C<)tty@1=tuk3wkYbNoY4%&=KG+ zuE^&OX7fC^Uw>iZN zZp4rixl!WgA{~3l&0-NQEQXBD1-(bQnY6Pn@^lqjDew$)epXt{wB>W!e1T747>ztX zb33$UNnkk%|G811b154CF7>SnyhMq8L6lTD@EY0w3jwAE=CjFuDQGhSO;CoBR|S|8 zSWMv80?ZBk5)6&}rsfq;Ge6LQK{E2101E?OX8ZkC>H=-bp8Puj76;-~ZGRA;DR4Du zdtHE~fxF0!KMHV6;F4(o-kNqgst^ra#b*BN^dx|ez;rMo@{XW&1)hdBjl3)5oE$!f zfTN3Vr-vV5RdFJcs`AY6jTG;~0>O-hTQSB(iWGBu_}f%f2NjglOF9^Sm@434^%xI_ zpQr52)pVKg7S`lYO}8`5YtkZzY25DcUea~A#+@Dh9Z5byp>x9*ve_3ZbYA#LYU(2k zq-`%gihV7jz~yM?mq4gkJI{fuGNF4Hz5xouErpbUNsw|Ua%bi1h@MjP7XB}8(=d3W z2Cz4{stsE*1zf3$e7EXEU<9_4`%ek;oWQl@{!_DPAr=MhCikB@fl8SWDJZ=Paq!85*!c&;D!@f_L-;2$ zS|G;Il%fpcgOkDW+C$WiC`ZNW0^-dJ{uQWobM*V`7^CVA((v)1c(G0jf+xd5sxQ&+ zhoM^a0S$i~ow44S(jd)gFcZQXFxhEXrZ}fSx*A$d7&J5-qv5^ab3>|v4T>XM&QL~m&D2dHMv@mk!50)#he_zY;Z8Z&QtxENtGZ<+-Gt}*kb22{VML-995 z+16~;@Gmi|s7Yw}bad}VV|3nxmTWYW*)+OLqnXUQP!3JgbYIFxP~|0N9(N-IyZJRW z593JN@&%pKeGSdga=C_IKqXqP(C{-Q2w$n;PxAX!8os{*;k_EZ4BE8iY7PG#^=-LE z!{hvZt%et&nOd&XaBmU9*K7FCq~Qh)zYIpU+^FF+=xn)3!*_t)Ew^ZRG3oq@hF|0N zTQ&Rzbo7?5YWPvKTgz=4{vPudaEN^Pm4^QnqjAft8lDH;*z#))KgWFjQ^TjBU$p#2!^@#AT3*xePau;^jSBiC zXjocd`XIj>U&DP~~ju=hd$TkRb7c+5*$?HqO# z&Dm<_u+L$zZ=ENj#o_>su~svO4LpR}wl0+Y3QGfh=nAbznt^*R`b+Ck0z?B}K|{74 zEkK+2T3Z*1V_`#ptCg*_60_L$7b`5$+w%x(6Re zb1lCr^k3lCl%f~#|7pL*=L!hJbXkv-|H%Saa34|kPMwK3>>C7X@B#G4<@@G*c|OAT zK~9d@F4NhPUt*jnS+TRk1*)ugt(ediufQlQoE5vO>18Q$f@2_h#qL7}B*zx~KlpK! zvEpo@uY|XhmajOk3769q!7Z0-VB#=ld=C6BE9S8m_9C%kScCp6^2l zBODyU0Jv(_Jbn-U0gbe3wuG@0@Uzg5v%=9oO$ywO$fJfG1n1C4>Kv73_-Hb>=%^&a zs}4c+OTxc~hy&WpnDX#4$X4{tNps#rlB#eQMpQtJgsQ{mK)L{}CsgB9^+8Vo?AU;k zB6}cg(c22eM;6%wgy`)C;ObHI4g)-eszvWKz;e_+dY1wAp_fL#W`KsN0KRSjdcUG~ z>&C{&XVGb+_ZZ-l5R2%&g;Pm->?kfySJ@~)V&@;pY!}jtH67fJ`n7t+R8{|H$9N!w9Qw7X4$<MKp!Hpo(DQx zipA67gue_u9bHG*9>dWG;Prl2uDUp z-NnTrMnp1DqtQzg5cIf3FLa8w5#vQ-e6Bdeh{zE1NAywyJjR$k3P{>(Y}z8H=n|s; z2x=&LS#gLFg7IyO0fq22Vyq(@KVKYTMC9+x@Cycb5++*oas?#qdp2#cQ}hR-e}`$m zSR7)6V9Y}&k*ZF1imDNge7YPMR}_aBAsA~dMyXTONQ@I8KhZB0hZqrgh`^OT^bw0b z#VP6`#)m#wE^yiofF-sMM>Hp*|cR& z(YJ{HI;0_bO>u}3g7JpMsBwy3CPp#{jBATSjEL-pEJv?XK+xxbWm5kz>W^?F2~#Y3 zJt_o1FxFa(8K^%oo{#+J4NHf=%gOJsW`-l z2o-JgW+RNZEeCLm0Zyh~`LY2X!jK>RiUCrs0B$uvQw4yp8ej&RHhP-@)>Hzx-2gv@ zUXR{kfR9kO=G{9cA+PwyNjXnE5 z1H3?a{)PcgM|X|hZ-5a}{eS`9px8ZVfGO0X%E~m)-mk z1N@3S__hHWi8iM+%ypG={%q&!@VZ{=L?Xt0r!oXB*F&aU#AhvHkL zAq3!@^4VNiDCh8Zy2YFU_a*s!b@@RX@vZI=3P|U4(Kw&Phs7C!O$b&IxU_qRzySO9je`x(}R-! zT*OCLO%Dc|5Kv{wpwt;l%)iISnHGM`sk@aTKXv*nX1fmG7vs7Oept`BXCu7=0Jafu z>VD2K%2C4i09T`(=_>^HD%RYYegXj!UNBv}VD&Hv3Z{p+0@Y9tW|U43Np4Qv(a0kD z_B1K_-@KyVp0-J{tFD&V(*@ur9iZ-zym3E>6aC9H9Tn?7%C`TB=CS~0!{Tm&OF2?3 z?qRTMG)}D>FiA}gd;Qz8jqvKe<9pTem1^Kjq_r7z5oe|{EOjbM2nouZt@FV zu!!^#cqtraZjqHO0Dc(`(-w`)p@x4sEY@(O0a*eN2SViVDgow_BTIU^V@~wFa6xl` zIUGT;{;#mC^EE_HU6zF~x*hFd{2>R!K)~4KVZ5G$VIW{|eML)grWTU`Q;LBI3k?N1 zu?9jVrWDaKsoMZUJ9=Gs8W(L=pw`OB>%%j%jJ!U)Aj`-bbbC&tF!F}*5m`pwXc!r0 zOWdUFQl|V2OgR{ND?v|({p1?RBlp>ySOc-OZ(}PAg)1H)kz(=;g^v=t#2Ok3uVoeL z#iC1wMJ_2}$#9TJ5ixI4VKHx-zk)pKGefYR&k0XwGQ+!%hXdp!;rZ<8p9)tnG1wHv z=cub}dK0OY0ykVQnF|GHYWD^W)D@USe&HNS-XBj1HJ9IXupxETUobp?cL4UyYg z05*lIed5?+S?bh1#!>d&kQjyQ&>06cMVD0qY0125Uxb* z2^}d3ODVg1Ldyi0Le}mHZ4l-aqvJ;}(_A7_*yj!KDU$L9159F-E;m3WbNiwK+7rGX zDrjDaQne@iFy!wE2J(8sk8)xS#3sKPx+{80NbK^Px~F2dqedqv9DM8AP-Sp9vKh&2mu= zfd&GBO$8t-x-vBTn@FtkxH1$KdAy&EyfU;^D3yj;8R{XhID=tgWhl*XxNl&c*%WEltwbDxKCLJo$3Jic$ui8TuJ3JhUoXt@6-Tiff}(t6XJQs#P8u6*-n_Rrsq_;jdPOzgm@AEvN1+ z8d8tci2itGg)R7zn!0SkkJPNm7W_y}Cjlw=k(#&^{A~)%V>LQ}{TD~^$7<#Xr@uiF zf2`)HEZZM9Xu|f#YkX{fyhhlrQh=?t%`bxwk)vpiyi_BC>@@$``}9lusRTqT*30(O zY<`l~`%TSkE*m+`EBHyqtG_6g(Z~h@hU;PcH3!2$z&OXl_*)K!fq-$Hhf$Q%$OZz& zcRY;Z91H__LNYlg)<6`Jn<%?i)y(dK(G6p)Q)16}*u#Wjm5AIjvPE2!@zB? z5nJ#0Rlt3f)AZwN#1?F9Q=pYrSmPnksfda5FjV8-5P;)r!Xjm203Ba*xB!2hBQZ+_ zmkNcIJ=oT$ZmGYLFnPfmiM6A}6YjjD>X)kK7#&$H7_s)-7puA}``SR)EHvY8na8F>jZgQA*4n6(mDR8uFwR_N?# zag7||)b1FrDQKZLB3fNj(7Y>(1Y&WPD1)8m&v>6IY$v>(pQOi4&FL)$LSOi?hcPV& z!$83JlZP=q2g5+*s+2IpHndP>AP4-M!P@_(S|suukDsqqt3(PvU#nJ86Mnu{y-fHi zEPSncy|7TY_SSJUA zvUE4?r01(=*PYHW|EX%xy}u=OAI5A19~vc5@*n}$%cM&A{X?&$4V)P~Ry}+28YC0U z$Ew>T`=(D8AnIGyv*$5NO8!>$I*F<);n;mgwOB}3BYH6pIO2m^NFvC0RLi6=at0@b zcbZCzg>VoFaB0DAWZbPKu&i&P@yPY~*+>0xpwYuL~YfJB_ z7NJu+siRsun3Ud8y@ibtc@HfaJwZvS&%mhetPXL87Ww7^M0A-5IAOO{%L(Dg3aF;& ziPd6MMyAgdKnI#FR68dr?JXV1BYF*JKOV#=?PJwqTRP2Wc%ROxmN}Nwd^SIcxP44N znF<;R;(Do<=o5wq%{O|VKI5_FS5&Fjs|=bvZnO>S)H&?R%d186yn@t?v)E~uSFfc| zICVVL7@e*X{V#2xNVNORYSr#Cm7k>?X^3!zKYCEL&LzJ|)99e;!#snVvY?O`EOM-C6be6 zlHGJDt^13rDt^OybK7b3vr2Yj^Wgw4RP-)Vp^an?9t>UtIx&4&%Jk-%=v&1w4GTtI=UiqnrpLDGVODv=B!! zRJDoP`VnG*55bpt9>Y?sWTZ-@ z*L0JXD(#C%@g7q=!Lr&l4+u4g)b0?gnjz+inDcRsH$z22voIMN2y$nllU4pHlYuCf z7mcUM~Nc_hW{3MF9i21~#dm7*6k(<>@FCDVt9`X!U8=P`F}+7Zzs)$n@Q&4fpKDfNJthgoMlM9mnvqUQjUu|bt^dvS88juA7^u{tZbEvOI<4~ zj~BIa6Q-;{J)NUz<73ncm6bz8tM7&5v8qxQ%pwWu_i9ttx2eu+48Wt2(U1ZDM7wdS z0p^gu(-o*6U~m>otcNRRMx_j7^>oY3tTgUcpv=;+iqLFLsts@^8sI3@L{-|7O7(%l zS+%5crWgW7*j?qa;kkh*?0+Fk-Ux~SKaY$SvwCj?SJIW$C>(hsxQX;FPIfcm3}J}W z`%gjPTRn#3H-kQB=bwW*LcKs1ycN_cfu#Qqs%a_>^tNtjHw2YhA*ickqyIcOkE~vQ zJZRX&srk=?>c19(ejYq6+eAMP4w9mX^wED0&S09z%?ps`g`miOM7qd}T3qA?w!|-V zofWG1t8lB-P35;If?_#-jzvC4XUq3BMI(>O0hljlK97t6XcROa&;ziNHb3%$LFY7m zmHljAu;PM^$VWz&eZe|$nOw#ZV_)#taiBH+hC2S5;1U7E|9MUDBtheAtL$IK zcKEfycA`aoNrUD(Q;!|gJJ$teIE!#`9)M`;`rgb=m>dReX$xX*2o{Tq(fUG~#1@6*@JC(~dL8_;Q59zm{`1!sRBs5)c3Ea>ylTox23 zf({~=1!E#goU&dP9AnsNn#ro1ADn&JCY!;s9xs$+E29TW*dn=}hD4jJIF;`c}$sOG$u}@=K ze#Y$A1`Atmpm1*v7B+umGx)|0;L+DBWM1SnU(8RU%clkl*#>Zjc%Nq4PxpAAX4y|a z<0tX@9u_Q|!fq>GUjUlR+lW_Z`VsocNSlFBP8q7KMK{?*2Ya7Z+D}n_5(Bp_Cm#bL zpB@imT@HqU*wzoRyBwF()&@d_>v~Y_=-CzXNqDdW?QklU#@Q9C`C&1x(I?Qu7AF8M#;4HiJFhJWX#7t@3LrvIR zA#;G%Pg2Zk6{vfOoC+z>djfJ1;hyT3=V^XBp2=p4@>zp>k3?TgNGk_?M{!-c86!~ct(6$@k zan>X)k|gI|Cu>5nw3si^`@@WK4JPASu>Bq~$s< zL0wJ)50V51VuE`-vX0RNPV?j5r%UapfA>DUq?9_%@A8unKd;*&|@HAba@y{axe_!F`zjo)6N@5Fj??I(9xodoh zO6{Q1kBG()U2?GLN1{s(@pr1Z{!TT|->D8YF``Qj(=;ugqSd^qw6LX-Wo$v^A@bUxh+9xPo%BY;yR)#gl2gfs$X7UtII6TpjQjxtN0-i^!HZux z4ajLoBQwTHPSXw0cF{)z70(ht=|1)4J7A!4n{s!wKa`@*!&PZOKqf!jS)*GFQJW2wh z?+Z>vE#|ezhqcm1lc@XyfogGy3cpJYt)jcj4XskY3Ij;}f(A|MS7`vz-Btd|R{JZ9 zgDkWN)IJQE%1WEvjXFvz-X17yzV&3=^BS~{Mo$_DBK-poV`~nEfq?NIF~lSB;edFF zu(OCRwT}kGzA!l&2yAMecZx0aV>wwG2pCPo5Y~Ufu)g_N@6&nq)2ZI43+$)eUe$$H7zP5y%O1vEIT!}=y7@ghu?C``%ww0ir9>vJk<%b3 zGUDG-k`X|p=9ZF+L~4$y2kMtg%6J({M5N{`CE5{0YQ9?Hn=af|;v4aAH-JdZ9VK!_ za73i$PLqL*_;(pVM*OdtG&16U-Nfj&Yy(J7x~Ie^T=!~>%G7_Cm=5%}lEUV{q6=s% zzE~n^-D$2sW%bi*CBl6>a=opf5f%f1Ra1&+1l2uHE*v&R81^NPVTVl_6^3mIOYCQa zN9VDd&7V>}1!_hacK8$@!xk7oy4gYnRGD2_0+a2cnMmC{SqeJtblWn`leHjejONLo z;q5<>ztQSwnXETP_s<5fbh7eanrYc&U#ZItAf+BN*{7mbm>6N~%E>;)uF@D~Y-oyM z>@)=4o{PeMJh|9u>ZjH!m^^#LBeh`iF7iZmW}#-`G+n`Q~k&hjgZ z5%uvRsd3{p1y;#$vy0aK$BSeJzc{{w;WNgOL?^@N7K!s3`_iim4iARP3WKwQRnxIS zeVS7kY%N<}wydljGFvzwmqxEdERG`_;qVJ?e=EZPGucFxppp57Q6-^*!eCjMrY^vT zK!q=}rASqp%^f$Cg%EoTTCBXFpglxL{dT?DTrg%VMB_bl9Z{T0zawKrWP!isZ>lamMmrJb&7{#S;kfX z!RF)qh2Yg3ARj&zcX5y@M+j4jv+c9MU)WLz&q837l=(1@ln=fpJ<5=aMlE#5a=$=fY||U;$)mS*^2brj1n|wfZqw$Z~%n{NVfqs;S6%68|qK zD0u6Q3jPD)aQfCMFpomPm`IP*;XSFr(O5hOsOugXT7DJqa8+ z_a`|ZRvn+5`zLVI6M0C(^3q*nZOf1rG??hA>+kK|Z$V2v%JDE}4E~hb?GDtk6pbLX zrv&Tp7T0KR#$DgOah?Bj7Dnns3Q;g+K#+^=(0B$gqqqQ)HV$aX3?2&1BsC6Cr6H*% z#C3?N;f#xyx#AkhOo2U`MIWBvQ-X+vBLvR@Zr6nSV>GC!0c^1z9X)u+< zi*%Wh`0$A4#1DRio>Xek5BK3+yNv$>UltsU@AQ8f;ZubE4?}T0s+mJuW)zA1C~Pf1 z%xB5`a4P>pJUKe#N5J)!eo)`f^MC0Z#hYtAXW`8?t!Xdc&-8!bJAHn5c%rv^7;jp# z35DUA?Rl}0YHCJ?~PSOP7fw}bK-mBgE?H~D{KDr{qdw99FKPojKur= zpR_}y<2$qjzCf79qk_4mq+;>jw51olAT?s3-W1+4+-c=F6*Es{Dk`52w2Ao4C!VY{ z5pleRszH64QNula<5Kx;ll8LKD&T*=v$mI-%b^gby9YB)$HcMmq}#=pFZJy&3@H#0U1(la@ond)~75MskEt}FA??$g4)>jc-U!Ql}(d1}49&2#q<;7&m$$d)^ z?_h3EJLa`n2X}x=Zg`S$Vy7F+d#2N+)S+0s$m(uN#UKltQ5OOEs5F#~u1jUL)XkVmr|~8ucp8iEbh^{MiG-8t zaUn^)$lY~2kk?ke+_xF;-fn`{lXrd7N>Il{7yGDY3+m8Wl)@|xS?W6`_-^eM>0Oo( z=5C)4bwTJRQFf-{tJ8SBkZqT(eR6mZ@(b#Q?&0Bh zObFG2z!@mwk;G2dJo-36W(}sdC;Bqr=13g+JlU7%cgSH=2EO1uO(<}eg2J*AX}7W=YL^#gMMzz|;5(Ax@lZa zxam7g%{N_^W1*E3G3h|kK?SirIXs%#kV*|ee5k?9ldZko z;EtiAeT(f=w!`*O=*SJ|3^&!+hYpKJU-iXN2SVw}bKNF+S9g!5hm_i-PDL{U*HD0e1Y4Q7r2dxX|IQ3fjVoar1cCMJ!IQ^n?51yuEj{vjVFw| z*0Xnj`Dv)Rj*0iRHdON#DB~ft_WD5()G@K1mV!zq6&X4lq`6~aBMgkKG!R&>Mq}uv zPE3g+?o+`-tM?8#=rHb1*tQTBm#!kE4vg&`aMO?#=qG6vNE6!zJdMSrFvF1H3F$EM ze(qp;cn}Y-gV`vLI%N&)qt!H;-1yLNW`Zx@Qv9S>>rl(S4TA^Fj3verB34>))pU%u zD#a)q%f1747g4H)x-k}I+8BIJ!Zd-PZH@O)E14Egq8mcwpzis2t!f;VX1w4XLxaTP zt|7LMU8Q#bHmp~B^bZ%zgQ3FK8$$=9o!|)1k{%VKnLZOv#|Qh~N6_jXc|F^Tu$7GZ zHK%l~bB}M|+@`~zyxA;zhXTS8b4#a9<8DrEgTn8GLTF3y*;|-{D3aQaVz3@v586RL z=p*Z{ScnZ!7I<;?eI#kVioaIsw-$`hR#~4K>GGbqS3=f|qz2;2j)Wa-^{dr45LMI1 z{msfD6Y?~Y=-n=lXOF}wGwxc--d4UrpGI44gurK&CDJYSxnJuJ2A~i0$;cR8fxGzQxrSn0eF-Bexi; zo#<7FlR;;IT7dF85+6c$j-j)RCGeoK(RW&`_C{kZ$(z=!ao5Obyi=xM9wo{rS4i;n z0dD{nMV#sGAt^K>3|~=LKP+W@UCZaldoxCqOf)3a7`mJc0LwiwKGKs)t3rXfkAZ$C zjJlE3E+}-4<)9)HnET z6}KKk>qr9XaF>1RoQkFm){?2FVZU~mZo>$ zfpA!n2JAZ^32I?TSA)IRF|ip#sJ2FbVi4LlLu(U_i0;+r8+1&*wA+b( z+F`oz)q9AB8{?D)*i_SN@J(5$RaEtZ85L@l5?e#0O5|3HgJNh;riU?#h@}BlJOZ=M z#fevNa5c5B&Jw&Sk#KH5!qeRcTo+A05Fbgq!`;lrFj~5`m~b&;2&?HSwh;8XQt1q1 zQbwDhUkutYhelQ+NjWn%4Qk1e$yQJXJa0asgGndlS!bodPt2z9%dSesp z*3~f4Fb<$>)&l?2hL%ylD9qSdJv$p4yHRP3bHkY6Vf5e>X^4|Kh$<}H-jT$x9nag- zt37MLFaQG?^#{amIIDP7>b50&IPu=dnU|kkV#{`=QqXV{Cw32x#?1s4JYg$Zd(U)q z(xa(0SIjAOqP1=(MsoD%QH~cn9zy@I?WC`AB%!m8suelI_!30~QQ)+}G)Ts6L>81+ z+5s|W%^CwRGi2n#gk8A;{UZZPgJVPW9jW7~yUD(5|4J$hGpO^HEy_yCA9LwL&@h!U{Iufn5K)3x#~KIQHXHLm zQ9acNQ{*iC2hA$>8}zRk{;h4^khRTy*>!fU?pkMx#e`=#?zZ%*v)*kIkpFXrF;r5- z*?D}HCHf=3!s;4=3x-WG02{TRHC1y{WLbKzW0arh8F8qioyKpY18%z~-nmVd8bEk*ufzBuxbhO!arG|PEapNGOrbIq4`FE<1)MRmB(!vM z-@APUf@94`6R+R?x20k3qP}rB@W${j?4aI(MG)VN%mx=>aD!t25rdf&{*M_jm##1{ zFT$)HOBDFl*PU5}*hP?hq)FpTNBdd_JRo;P*1+(!sgYEUBE&aW+|h0ZD;f0DrP)~^ zjglk{u@L<$)*Ew+(Ta=XIvs7ltr#BQBF$<>NSpW~WT^&{t|f~MvM-C{27`ic;=q=c zt_7PAc3r~coHK$ptk%9{X!rTiq#V#?Yv^u(C#^G%X?+I6BU!QSugT{I!vXT0|D3b#7D;94b7@0&J+!;C&A>4Z%dLD)bkF6H5MO)(}j{p z4QY~%x!W-%fjK3bBi%g~SJMy;&8eRfsEp02{^k_wFM}!P-Kr6Ex@IRs9TQf$bx}*f zo#+lEQ{!McTGP>S#}yuNF-ro_Ht<~JN`tf$3C2tS8pIJTKcqe*=vP&Gf~37o7SXIr zG;5N8wJ=dd&9`wG&iK6CZEHK}@@2lw5^$omGXZU94aWteSWZLD>DyEW^>3U~;$7nnWZM!YW>|*N^@j-v{{GPGDU%1YUX`LaZ|C%#Bo$DR3`-$2fZ;4VWN%MFH``szhVZ)RCz<9Z z2~mgB(h|QrCm-_N3JJ&Mo#H=4M}%)Sof;kKja%73WHR25srDG^qrgmf6!N4mxIV`H#H--?Jfm8=n_ondIvA=s8&0vSc8hTc|b5}Prrd5H!|6F;}e zD|y_TibLjI`208pin~<(SmwhD7aY`s@iYroA%$h_c4GD{;t=1-sWSSaZxn!jh+Chw zmYQ*!*}EZ*n7d$TrkEMNX53{C1|iWY(gi&)1=Mbi%MSY`IB;Spfn9G}R4bvDoL#c8 z)-?$BWor&pJ z=w6-JfX>0e#BdtRH=+QQ;~Sf;rjX%g?0`R}V^X7*tL+$B!~~9^5-b{? z63QyA8PlM$dh0ehu>bHMyq#vu(T>)h?i}q=qXaUG!Q8B1gGNk1#hO4J;kT#H-ZyoD zs>CWd*Gp*~WW5hLn$vR|igMCf1GXy2Xyk}B)MMrn#(X87PB@^hr4l}2rEgK|Gz2ma z$fo_d2Q``J1{2wt>v=xVvrxxl*SZ^EvvAvxjQ;8zM7!%+Fk2kF?;f#B>UM#T`v|yZ zn#=D-EPw$+VQtSFmk-?3 zX0d}*LI$zOk9xy&z-R6bfaQ*U4#`66$l^YXXIWo#dSG}YV}rmDmWySg&|0?ny#V> zjUqi>Jvu%ifCaY`3+i_5mr5M-43bMxKgosi{aw2gY+O z{+Kpl#}-M$;L0s8(r!l8pe@7#W6zM$)<18_b(i;YITPJ)$7ljR7*XKTKBBmhe}*d{ z)}9}RxM0QJxAp-Gi*63~R3_^kgL)m*3c>{{);$LqBb*c+Zfx19l`<}xI={GLZyBwL z9a#aQip3>hbUe`*_Vn;-v)t9LYwOs{1IGi#R?cg))~`yf`mJbLk%Vkd()tdj(%36w zhB6cf&#}{o8NL{3Ow@@QCwl!x0h)vR4${VAk&)HR6ckOyajt{Pj!3gvK`eyf327T0 zfswg2Yn!spJ~OuOZ-t?~KMA2T%3@%DZVKZhGo}+-g9-?i-xw!QaaeWTShpFRpe@*| zdo8l^L(7iNlk7eYLyBjotkG#KY~Ts?s0#~CWng0yR59`|0*h5*l{RKsI&(~8zZw`o z4=}W5w#D--WZiD$?KHCUVasP2RN~*DaME*QW)GHds!l66$Hp^;{>`+oJnx4KXHmD| zsbnDo=dc*XGOf2Gkqmum>?D$X+*)Q!HH(RuUx@*UhQT08odD6rlnFCh7!=)Rq~yF= z7-d*3VU{7|D~G#m#$51MvBi#(IM%j$%{1LsFp)V{woRqcQ+pt?1E7F=Zjc@KRhz7^ zUCj%@5sAog?1b@GJOd+Bi_N%8Op(yP?_1lEDrejl4|%CU-p@)o)GvnUY|ARm9q_Ej zx5%E)?m=om1h<%vMb>Od{ZZ>=2 z=!}NTmU|8`PJ<#)>}?y$QkRAk*4xZxx}}|xU@yRsx*TCkKoyDBRo{|Nxp_NEjMmO- zt2R+gwz3)xVyVG79pdIMW2#F>4algR z+n!Dh!g7p>V#0n4V9Cr$hs88q`!tBrsm2m1EMzA*PvjoO@orf^qX&#G2L5Zsf;~g_ zhWIMHPB$Bp!CEKCAf<0$T(%;ZCX=-sv3SI#Z@VK>tdC>&pTX88v+)UtF|FCRrl}VBICQ%S%2si^f z6E0Z)#G5`W%ks8Fe?rG`l5J;Q&^a=M>TX#7&e9&Zq2WVgvzaYl;*4TrgE3(F1_-b^ zh9yI5^+IH^qNU>**QZoz$O3<311xtG=k46#nAyk01H*)WWbJnM*?ky5j&)BACi=Hy z6jz5YGW9zdAX5okq=R}w3?V~E!SQ%?EY{`i)v`M#OwrcwNh?c5M7<_rP#LMUGbr-f zx0d7|VIhm~F=YEH%4HLYe?fVo+ClvGa6V$4-v|pZJr5q1xZp{U;^2$$Z^>hwWJF}m zDER6v^i7$e^6Z*Y-i{XWs>@I+!lHz*w^)3?fn!)^O*D9n60+n9{|>y|+M9in1Cuhl zZxLNy-0wa=is%T{X2y)9c0^5_WD1*EP!letXq8a}H^*ephB(>19DUs|w>cWqDg~RZ zbJB1X!V10TVqnk~XLre(QDCuXAM781;0z6tnKD$OA|twm+b+b?mSq3uxT)$>6$PbP zrWsze8=e2qOk3T#w!PihJ#pB1GDM>(x5szJ*h$&XxV1M< zH#f%Geol}lxB@qVMG)8t#*Lw+m;peG@p}_=%Yd}ExNg<*6!SC3Cz17<#;_WXeUWgY zqJ0NPhpcWI!$uPrWWKURse6quA~OJOJnXm;AAp_9abTt3bkLhB677?k?DjzA^hRt& zR2$9j_HfM3Gj6#tT$d$m1^$7~&}l69E;!nTVkE(*V7B_K1)EJf7<~pWTP%fL#p3)k zor;X}IE|4Q+GsRxZ8RzmZv{@8<{z|%5g_Zy77sQ%j9RXe8vD1n z9m0kGHU&MW`?km?BjnKD$utR3X{Y+z@BR*rXJ2#MFyj=(M=i~MC9T@$Cd3By4}Kgg zg<}cqjUGV=h3x+jLIbsjnO)0SAmC%duS*}$DO?gX?aOUUi5^IRQjADl2-Md1?;3<# z024>gzmM4mdm*hMG1jp+l&f1fc3|cwQaihjV>D}a+(FH^b**2z2^Dr+ZpbnlleF9| zu;;jBrbPKWq-sI!4g2RU{c>haN4mY|Wu~xoipk3p1hQ8GlLE*K&`taK>Eotcoa8fu zB1+8liyQ zbnQTR4oTM~8DNTJj>(QTnHzC8ik;LU8>{Fr?GZv?S=za$O$r0fh}QdtQ@_VUE2*bb zlv-r(I~&r)`MsT945-^wi(o&L5muEa&YOwHQCuJ}qPZ-gA5@^c_Hd6EZEb2OE`(8d zG)?Vjbupl%1_8rmFg_917tlBTGWUkWErL{jB?q=&jwKnaYhRcPp$`2OxJG2 z@V?%^b6>yP=E*RfxId^dP+!^4qdD0gYGe{_F7G4-EKRK>y0SEf=BhOlT4Z48E zHPRJrvSNS3<~JO9(Okr@qkF$eG+n0JzpP=h|5H|MHj|@pnxl%{;zY5xt3zfK8RpIP zn7hF7Ndd?^EaPixgHOe0jrQRQ7^9xc)X1{9B*lWkd<`_~9%?x6%qS_Nj*3S|d}JsA z9cG0CydA_G2wP5J-Ez25G;88;h07>X4&kc2p(CK)U`ILFAc$RZtfJk4Gphc1Y4fZ* z4eR-^ogt}eNE5)$4y+_tuZWShjg8)t8ToI8gY=8H(r*f*P-B&4d!(qxtkla?-!~D} zfr$1bU6Z;^L;Ej#>_}#AR*|hA#hEH^|A9LO4q;U+cdsdSZuv*E{8NgkE==7-uPiwG zG``nc$hY;~gK4W0v-O|~heVG#z20szuG_&JK|VOD1fsbVFod)Ju*=4|yD%j?2E|Hr zUAVrnO5>PCBH70_noMAQPMzp>*5lVYG86wFCd6DsfQ+a=UR5Jb`|juWrukMV$AKMZ z22Ta!SIFc0_#NZHxBvjZCvhbJe|W4>{#{rp{{Y5S5BR;~!8oUl-!Ztzj=w_QC4gTM z?^3|85bsp-*M;ks_$zb*^6!}*jQjNP``rxr2l2Q+0>2p_voLN)!Edeyd@GJSOR-n*P!pc2Z39ItpYE5{t#m7xC_}zSog_ZCbdn}CmYka>##}ID56*|*= zv8*4iS@Hb}c@@3ySLono3g55LnPpl;KNdNEd=J-iIb91aQkiqS51s`6;7%uJ*cUJO z9$5j0u;m}_UvYSqjQ!dCPtU`jWB5ya|Igy@#HEA!D|4Bg~d!{>;zHBQCOWVu&Yvrio|$cxjFP%A5(rS1myvKKh`U%{%`x@nY3t@rY8Rm2R`A25G{*8(O(vFyo^OvoPa3@?fhUam|ub4;4-rAw&7T)-STnE&&DF9ghy zh48C@_W&+4@Sg$i16*R@VpQa2z_xy2z;^()^wt4>6fi}S`E>w(2{2V2;UU0p1D<5y zoq*o~Y|HyJ;F6DL>vI+0FyM^A|1RM303T}L-vhoCu+5L{bB7sENYz`2C#>{`M1RjU z;|p?js!(ylKm&bYX9nQ;K6nw}g@84E*jW#Fu`fObxXA~f19&N5ZO^dtIlyhc_$vT! z@WJ;3-spp$1l-|+p9b9JgI@)FvJd_<;M09@5gPVPA3Ota%m*(9yxj+{13c)1&j38^ zgD(J_@xfmNyweAN8Sri&{2<`7eeh2JpX-BP0(_ni{x856`rvl}U+jZtK+yL1;9~$^ z?t^;(U+IH)0N&?=KLPk=z_$JN0=~l+{~+M6`{17gzRw502KYfA{1)JE`QRdC{HPDE z1^hi9ybAD>K6ne@9|5LiM0xuV;Fo;yl;8V&@|#3F;Wwe;3Lww_0{GTTZTgUN58wv@ ztGtDrrvQHsFosmYe*y42fM*z(`Jes?{7-%r&Yuu(f1bUu(0(a%-bMUQ16%!ht1o^7 zP#^TcRBRTu`0x1QS-!RR*gu)R9QKR;%A63=TiB*Q(-(gv;%9(gV2ALJ`B{4tmVmR2 z>5aWfE;0X%Fa4Q_x3JCM+ON0@&lyC#g$n>Pf0n1e@ca11cxw;ic0K3QNN?c+V;`Hu z&@q2}&xZBiTzl2YvtK`eKj6;?^5W;f2lC+O#s~W019|vB9{e2mKpy;1v^+ourX2Ac>-z0buuLf-WbM!af z3fQjS76AWl`nQZfjPVZxcFcM%C8E(XZ2RQ+>4_yy)? ze)N&Pkq7@h4-RtS!~BRpHxK5k(e}sq)p_u#KA39?86QmikNM!afcN@f#(yOb{ze}B zOdkAd9{ffg{CB{wJgw^y)$k85CWGMFzGKhduMEY=H$T(^5DiicvT*JLLS_c2dDDjbMxRY=D}aigTIppKbr@?ng{<4 zFxRWYs9+6NRV!I(^JDO^Jh(m&j^@E9mU%c?voS%mJTwiVdlRZ7|f2f8@PAB(-H*)7ul;4DHq=QJ5M%(@3gHdobY zF$YHT-4daw2fp#bT(M#Z|KD9ftckq)fGo&8nl|h^9Fuzr-Xa|6<_NvE+hUm=%w&%L z@-`c7u4~h1-Qlib-J)&L`~a%g|INz~T2G%jv3blEF+^Y3|(9r--gY7gWh z)zXG#CY40U@e*^3Fk>6pu~;n62<+#!K#k0PE*=@oHV9~ zw-5Lz@JWq#Xdz2qKI`9qC^L)uzLvAd?~C}~T+u40{9IhDn=MFAk>Nau$HiQ+Wi@bo z#JgrYi^n7JSt#2>nIhX^B>jG_$re$;LEZhH&Lk}+?*pru{1YO+uE;{OXQY+LJh^IY zvXZkuxoT|kp8?xncl1@=uaJ19xQUW>$@WFY{102cv)s&46|9Y4>v(6gye8A538q}^ zT*na}-_6$lmlr(^dl&7Xqt$!t(mnjRJIWO2!RFi{ES7WzNBD7tNDL=NdAbuvZZf>7 z2nXKSSz;;s#7qqLazg?}alf`4m%>4g+WN)l)%(ZdMbQb|Kq9Y<$O$Ytlkb|75qd&j zAwAyWM|IuxTUT#d=dRn_=Awz16-!B{%!xC{Z98T2>P@%=)pffzt+jZ^ZrrkF^+tEg z`t_aby4un1e_sJuM^CD%a9C69W> z)YUW9LwfuLS+r3H$~hWIqPIvBD|^1%b$fT>nmluJb~JkI#`ZO9-3C0>h*Mm0c+VU- zXz$vDlOVPsP%}0IjGZP6m#^AJNh9zn!W$13R|tcjVUoM zxN=jpTp2AVx4<5`I8@mQX+iIhOWTxAk3*ZhH?eR^FrCy3I+3Sz0(t3R1LPVXOtayH zC1ZKG&FgO{YpvXn27%6bZe}b_<6MqY$*DE(&JcZthUmG+h5Co&z6xAj2lZhtSu<^9 z%0E_bH#7oEob1anWJs1$BVhPI=5OhhR~L8;)U>w#V?-FFh&~`oaXipHo)`7SxN#$_MV%1ONN|J-N2GwtMN4 zCC!Wba5D|c?aID)lYgYuP_JSx6(L!+Ql?w*-XK%FiM7SAPV)pX(0zv&QKHut8D`lb z-N`1Qn)bMqMPxTbJ{C)kT_tmHDgW9gXfL_7Q|LuAvPF=V2zh6r_jd`LBIZ78x^;X?krAT&f#CqdLY6nI6bkjOZ?j{C z4l!-nw-QzFZ?YX(2NvFyhSV(cM7?5%c^T!lj_-t-3gtNf@Riq5X<<$+?xN?R$=Y;g zME~7xLpV(tuf=ugwX}|7i*SX4Kyvv|ZEPZml#cw1T1bq!=_d!k?K8DFy-z$14CB7l zS{dSNd8MgSE5<_YNJ=iKs*U4-D7Bg5s6C=MHjJFQhj7nnZ9h~}t)}Y1MO1JW49P7> zwX3&os_nLi=Mf>#&%&(0ZB{1S-P40>fh@!eJ8T%0r$6eS{o#ppIZwee3~!ph`M$(F zo4{W!{@!};y%h0yhLC^6E5sjv#N*#m{Lw8>Jf1D&-^JKh&p6`pU%Jtv_#;d_o;l>- zY5220B$FT4aNaZJ@+>0%eu8hdT&CwAj_Ek>8a$p+D0<#G*;f27;~EZ%weKs=BxXM^Sf?@b?~#k<&t$35iy zvvG*>!dDC-VUiFgCX5;Y5tH+H9qX`6$d*aIvfOi*g$UEl8wZ1Cgy^gRgoBxvB z2k^&w2+O$U2ZC?r2lFEy|GtGki^sLZn=io`6IR~*Y}LODm|^C}J@(-}I2#cKV15?w z`+%9>V)LDNhnX<{VI2RS#vk$;#y|3F0p21D;9uhK_X_@Om~aeuKlILwW#h;LKVIV> z9j8Gm&s5pCcYR@gkH6_SKO-Z|&*o8z0K>K(%m3myzg=#zG>-B7^RdfWxTL_j<8Z8{ q;rpA2WY$&qW8d(R<2-k2fz#&mZ!;hM_{onqXRyGTY9kS6gZ~HrV#O5z literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_http_writer.pyx b/.venv/lib/python3.7/site-packages/aiohttp/_http_writer.pyx new file mode 100644 index 0000000..eff8521 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/_http_writer.pyx @@ -0,0 +1,163 @@ +from cpython.bytes cimport PyBytes_FromStringAndSize +from cpython.exc cimport PyErr_NoMemory +from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc +from cpython.object cimport PyObject_Str +from libc.stdint cimport uint8_t, uint64_t +from libc.string cimport memcpy + +from multidict import istr + +DEF BUF_SIZE = 16 * 1024 # 16KiB +cdef char BUFFER[BUF_SIZE] + +cdef object _istr = istr + + +# ----------------- writer --------------------------- + +cdef struct Writer: + char *buf + Py_ssize_t size + Py_ssize_t pos + + +cdef inline void _init_writer(Writer* writer): + writer.buf = &BUFFER[0] + writer.size = BUF_SIZE + writer.pos = 0 + + +cdef inline void _release_writer(Writer* writer): + if writer.buf != BUFFER: + PyMem_Free(writer.buf) + + +cdef inline int _write_byte(Writer* writer, uint8_t ch): + cdef char * buf + cdef Py_ssize_t size + + if writer.pos == writer.size: + # reallocate + size = writer.size + BUF_SIZE + if writer.buf == BUFFER: + buf = PyMem_Malloc(size) + if buf == NULL: + PyErr_NoMemory() + return -1 + memcpy(buf, writer.buf, writer.size) + else: + buf = PyMem_Realloc(writer.buf, size) + if buf == NULL: + PyErr_NoMemory() + return -1 + writer.buf = buf + writer.size = size + writer.buf[writer.pos] = ch + writer.pos += 1 + return 0 + + +cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): + cdef uint64_t utf = symbol + + if utf < 0x80: + return _write_byte(writer, utf) + elif utf < 0x800: + if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + elif 0xD800 <= utf <= 0xDFFF: + # surogate pair, ignored + return 0 + elif utf < 0x10000: + if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + return -1 + if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + elif utf > 0x10FFFF: + # symbol is too large + return 0 + else: + if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + return -1 + if _write_byte(writer, + (0x80 | ((utf >> 12) & 0x3f))) < 0: + return -1 + if _write_byte(writer, + (0x80 | ((utf >> 6) & 0x3f))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + + +cdef inline int _write_str(Writer* writer, str s): + cdef Py_UCS4 ch + for ch in s: + if _write_utf8(writer, ch) < 0: + return -1 + + +# --------------- _serialize_headers ---------------------- + +cdef str to_str(object s): + typ = type(s) + if typ is str: + return s + elif typ is _istr: + return PyObject_Str(s) + elif not isinstance(s, str): + raise TypeError("Cannot serialize non-str key {!r}".format(s)) + else: + return str(s) + + +cdef void _safe_header(str string) except *: + if "\r" in string or "\n" in string: + raise ValueError( + "Newline or carriage return character detected in HTTP status message or " + "header. This is a potential security issue." + ) + + +def _serialize_headers(str status_line, headers): + cdef Writer writer + cdef object key + cdef object val + cdef bytes ret + + _init_writer(&writer) + + for key, val in headers.items(): + _safe_header(to_str(key)) + _safe_header(to_str(val)) + + try: + if _write_str(&writer, status_line) < 0: + raise + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + for key, val in headers.items(): + if _write_str(&writer, to_str(key)) < 0: + raise + if _write_byte(&writer, b':') < 0: + raise + if _write_byte(&writer, b' ') < 0: + raise + if _write_str(&writer, to_str(val)) < 0: + raise + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + return PyBytes_FromStringAndSize(writer.buf, writer.pos) + finally: + _release_writer(&writer) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/_websocket.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/aiohttp/_websocket.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..df5bbe46ba15f620c7f1bb28ac4238c207504046 GIT binary patch literal 64796 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 + else: + data = bytearray(data) + + data_len = len(data) + in_buf = PyByteArray_AsString(data) + mask_buf = PyBytes_AsString(mask) + uint32_msk = (mask_buf)[0] + + # TODO: align in_data ptr to achieve even faster speeds + # does it need in python ?! malloc() always aligns to sizeof(long) bytes + + if sizeof(size_t) >= 8: + uint64_msk = uint32_msk + uint64_msk = (uint64_msk << 32) | uint32_msk + + while data_len >= 8: + (in_buf)[0] ^= uint64_msk + in_buf += 8 + data_len -= 8 + + + while data_len >= 4: + (in_buf)[0] ^= uint32_msk + in_buf += 4 + data_len -= 4 + + for i in range(0, data_len): + in_buf[i] ^= mask_buf[i] diff --git a/.venv/lib/python3.7/site-packages/aiohttp/abc.py b/.venv/lib/python3.7/site-packages/aiohttp/abc.py new file mode 100644 index 0000000..44a3bda --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/abc.py @@ -0,0 +1,207 @@ +import asyncio +import logging +from abc import ABC, abstractmethod +from collections.abc import Sized +from http.cookies import BaseCookie, Morsel +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Dict, + Generator, + Iterable, + List, + Optional, + Tuple, +) + +from multidict import CIMultiDict +from yarl import URL + +from .helpers import get_running_loop +from .typedefs import LooseCookies + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + from .web_exceptions import HTTPException + from .web_request import BaseRequest, Request + from .web_response import StreamResponse +else: + BaseRequest = Request = Application = StreamResponse = None + HTTPException = None + + +class AbstractRouter(ABC): + def __init__(self) -> None: + self._frozen = False + + def post_init(self, app: Application) -> None: + """Post init stage. + + Not an abstract method for sake of backward compatibility, + but if the router wants to be aware of the application + it can override this. + """ + + @property + def frozen(self) -> bool: + return self._frozen + + def freeze(self) -> None: + """Freeze router.""" + self._frozen = True + + @abstractmethod + async def resolve(self, request: Request) -> "AbstractMatchInfo": + """Return MATCH_INFO for given request""" + + +class AbstractMatchInfo(ABC): + @property # pragma: no branch + @abstractmethod + def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]: + """Execute matched request handler""" + + @property + @abstractmethod + def expect_handler(self) -> Callable[[Request], Awaitable[None]]: + """Expect handler for 100-continue processing""" + + @property # pragma: no branch + @abstractmethod + def http_exception(self) -> Optional[HTTPException]: + """HTTPException instance raised on router's resolving, or None""" + + @abstractmethod # pragma: no branch + def get_info(self) -> Dict[str, Any]: + """Return a dict with additional info useful for introspection""" + + @property # pragma: no branch + @abstractmethod + def apps(self) -> Tuple[Application, ...]: + """Stack of nested applications. + + Top level application is left-most element. + + """ + + @abstractmethod + def add_app(self, app: Application) -> None: + """Add application to the nested apps stack.""" + + @abstractmethod + def freeze(self) -> None: + """Freeze the match info. + + The method is called after route resolution. + + After the call .add_app() is forbidden. + + """ + + +class AbstractView(ABC): + """Abstract class based view.""" + + def __init__(self, request: Request) -> None: + self._request = request + + @property + def request(self) -> Request: + """Request instance.""" + return self._request + + @abstractmethod + def __await__(self) -> Generator[Any, None, StreamResponse]: + """Execute the view handler.""" + + +class AbstractResolver(ABC): + """Abstract DNS resolver.""" + + @abstractmethod + async def resolve(self, host: str, port: int, family: int) -> List[Dict[str, Any]]: + """Return IP address for given hostname""" + + @abstractmethod + async def close(self) -> None: + """Release resolver""" + + +if TYPE_CHECKING: # pragma: no cover + IterableBase = Iterable[Morsel[str]] +else: + IterableBase = Iterable + + +ClearCookiePredicate = Callable[["Morsel[str]"], bool] + + +class AbstractCookieJar(Sized, IterableBase): + """Abstract Cookie Jar.""" + + def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + self._loop = get_running_loop(loop) + + @abstractmethod + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + """Clear all cookies if no predicate is passed.""" + + @abstractmethod + def clear_domain(self, domain: str) -> None: + """Clear all cookies for domain and all subdomains.""" + + @abstractmethod + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + """Update cookies.""" + + @abstractmethod + def filter_cookies(self, request_url: URL) -> "BaseCookie[str]": + """Return the jar's cookies filtered by their attributes.""" + + +class AbstractStreamWriter(ABC): + """Abstract stream writer.""" + + buffer_size = 0 + output_size = 0 + length: Optional[int] = 0 + + @abstractmethod + async def write(self, chunk: bytes) -> None: + """Write chunk into stream.""" + + @abstractmethod + async def write_eof(self, chunk: bytes = b"") -> None: + """Write last chunk.""" + + @abstractmethod + async def drain(self) -> None: + """Flush the write buffer.""" + + @abstractmethod + def enable_compression(self, encoding: str = "deflate") -> None: + """Enable HTTP body compression""" + + @abstractmethod + def enable_chunking(self) -> None: + """Enable HTTP chunked mode""" + + @abstractmethod + async def write_headers( + self, status_line: str, headers: "CIMultiDict[str]" + ) -> None: + """Write HTTP headers""" + + +class AbstractAccessLogger(ABC): + """Abstract writer to access log.""" + + def __init__(self, logger: logging.Logger, log_format: str) -> None: + self.logger = logger + self.log_format = log_format + + @abstractmethod + def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None: + """Emit log to logger.""" diff --git a/.venv/lib/python3.7/site-packages/aiohttp/base_protocol.py b/.venv/lib/python3.7/site-packages/aiohttp/base_protocol.py new file mode 100644 index 0000000..4c9f0a7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/base_protocol.py @@ -0,0 +1,90 @@ +import asyncio +from typing import Optional, cast + +from .tcp_helpers import tcp_nodelay + + +class BaseProtocol(asyncio.Protocol): + __slots__ = ( + "_loop", + "_paused", + "_drain_waiter", + "_connection_lost", + "_reading_paused", + "transport", + ) + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop: asyncio.AbstractEventLoop = loop + self._paused = False + self._drain_waiter: Optional[asyncio.Future[None]] = None + self._reading_paused = False + + self.transport: Optional[asyncio.Transport] = None + + @property + def connected(self) -> bool: + """Return True if the connection is open.""" + return self.transport is not None + + def pause_writing(self) -> None: + assert not self._paused + self._paused = True + + def resume_writing(self) -> None: + assert self._paused + self._paused = False + + waiter = self._drain_waiter + if waiter is not None: + self._drain_waiter = None + if not waiter.done(): + waiter.set_result(None) + + def pause_reading(self) -> None: + if not self._reading_paused and self.transport is not None: + try: + self.transport.pause_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = True + + def resume_reading(self) -> None: + if self._reading_paused and self.transport is not None: + try: + self.transport.resume_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = False + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + tr = cast(asyncio.Transport, transport) + tcp_nodelay(tr, True) + self.transport = tr + + def connection_lost(self, exc: Optional[BaseException]) -> None: + # Wake up the writer if currently paused. + self.transport = None + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + return + self._drain_waiter = None + if waiter.done(): + return + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + async def _drain_helper(self) -> None: + if not self.connected: + raise ConnectionResetError("Connection lost") + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + waiter = self._loop.create_future() + self._drain_waiter = waiter + await asyncio.shield(waiter) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/client.py b/.venv/lib/python3.7/site-packages/aiohttp/client.py new file mode 100644 index 0000000..4f56f61 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/client.py @@ -0,0 +1,1331 @@ +"""HTTP Client for asyncio.""" + +import asyncio +import base64 +import hashlib +import json +import os +import sys +import traceback +import warnings +from contextlib import suppress +from types import SimpleNamespace, TracebackType +from typing import ( + Any, + Awaitable, + Callable, + Coroutine, + FrozenSet, + Generator, + Generic, + Iterable, + List, + Mapping, + Optional, + Set, + Tuple, + Type, + TypeVar, + Union, +) + +import attr +from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr +from yarl import URL + +from . import hdrs, http, payload +from .abc import AbstractCookieJar +from .client_exceptions import ( + ClientConnectionError as ClientConnectionError, + ClientConnectorCertificateError as ClientConnectorCertificateError, + ClientConnectorError as ClientConnectorError, + ClientConnectorSSLError as ClientConnectorSSLError, + ClientError as ClientError, + ClientHttpProxyError as ClientHttpProxyError, + ClientOSError as ClientOSError, + ClientPayloadError as ClientPayloadError, + ClientProxyConnectionError as ClientProxyConnectionError, + ClientResponseError as ClientResponseError, + ClientSSLError as ClientSSLError, + ContentTypeError as ContentTypeError, + InvalidURL as InvalidURL, + ServerConnectionError as ServerConnectionError, + ServerDisconnectedError as ServerDisconnectedError, + ServerFingerprintMismatch as ServerFingerprintMismatch, + ServerTimeoutError as ServerTimeoutError, + TooManyRedirects as TooManyRedirects, + WSServerHandshakeError as WSServerHandshakeError, +) +from .client_reqrep import ( + ClientRequest as ClientRequest, + ClientResponse as ClientResponse, + Fingerprint as Fingerprint, + RequestInfo as RequestInfo, + _merge_ssl_params, +) +from .client_ws import ClientWebSocketResponse as ClientWebSocketResponse +from .connector import ( + BaseConnector as BaseConnector, + NamedPipeConnector as NamedPipeConnector, + TCPConnector as TCPConnector, + UnixConnector as UnixConnector, +) +from .cookiejar import CookieJar +from .helpers import ( + DEBUG, + PY_36, + BasicAuth, + TimeoutHandle, + ceil_timeout, + get_env_proxy_for_url, + get_running_loop, + sentinel, + strip_auth_from_url, +) +from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter +from .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse +from .streams import FlowControlDataQueue +from .tracing import Trace, TraceConfig +from .typedefs import Final, JSONEncoder, LooseCookies, LooseHeaders, StrOrURL + +try: + import cchardet as chardet +except ImportError: # pragma: no cover + import charset_normalizer as chardet # type: ignore[no-redef] + +__all__ = ( + # client_exceptions + "ClientConnectionError", + "ClientConnectorCertificateError", + "ClientConnectorError", + "ClientConnectorSSLError", + "ClientError", + "ClientHttpProxyError", + "ClientOSError", + "ClientPayloadError", + "ClientProxyConnectionError", + "ClientResponseError", + "ClientSSLError", + "ContentTypeError", + "InvalidURL", + "ServerConnectionError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ServerTimeoutError", + "TooManyRedirects", + "WSServerHandshakeError", + # client_reqrep + "ClientRequest", + "ClientResponse", + "Fingerprint", + "RequestInfo", + # connector + "BaseConnector", + "TCPConnector", + "UnixConnector", + "NamedPipeConnector", + # client_ws + "ClientWebSocketResponse", + # client + "ClientSession", + "ClientTimeout", + "request", +) + + +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = object # type: ignore[misc,assignment] + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ClientTimeout: + total: Optional[float] = None + connect: Optional[float] = None + sock_read: Optional[float] = None + sock_connect: Optional[float] = None + + # pool_queue_timeout: Optional[float] = None + # dns_resolution_timeout: Optional[float] = None + # socket_connect_timeout: Optional[float] = None + # connection_acquiring_timeout: Optional[float] = None + # new_connection_timeout: Optional[float] = None + # http_header_timeout: Optional[float] = None + # response_body_timeout: Optional[float] = None + + # to create a timeout specific for a single request, either + # - create a completely new one to overwrite the default + # - or use http://www.attrs.org/en/stable/api.html#attr.evolve + # to overwrite the defaults + + +# 5 Minute default read timeout +DEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60) + +_RetType = TypeVar("_RetType") +_CharsetResolver = Callable[[ClientResponse, bytes], str] + + +def _default_fallback_charset_resolver(response: ClientResponse, body: bytes) -> str: + + ret: str = chardet.detect(body)["encoding"] or "utf-8" + + if ret != "utf-8": + warnings.warn( + "Automatic charset detection will be removed in 3.9, see: " + "https://docs.aiohttp.org/en/stable/client_advanced.html#character-set-detection", # noqa: E501 + DeprecationWarning, + stacklevel=3, + ) + + return ret + + +class ClientSession: + """First-class interface for making HTTP requests.""" + + ATTRS = frozenset( + [ + "_base_url", + "_source_traceback", + "_connector", + "requote_redirect_url", + "_loop", + "_cookie_jar", + "_connector_owner", + "_default_auth", + "_version", + "_json_serialize", + "_requote_redirect_url", + "_timeout", + "_raise_for_status", + "_auto_decompress", + "_trust_env", + "_default_headers", + "_skip_auto_headers", + "_request_class", + "_response_class", + "_ws_response_class", + "_trace_configs", + "_read_bufsize", + ] + ) + + _source_traceback = None # type: Optional[traceback.StackSummary] + _connector = None # type: Optional[BaseConnector] + + def __init__( + self, + base_url: Optional[StrOrURL] = None, + *, + connector: Optional[BaseConnector] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + cookies: Optional[LooseCookies] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + json_serialize: JSONEncoder = json.dumps, + request_class: Type[ClientRequest] = ClientRequest, + response_class: Type[ClientResponse] = ClientResponse, + ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse, + version: HttpVersion = http.HttpVersion11, + cookie_jar: Optional[AbstractCookieJar] = None, + connector_owner: bool = True, + raise_for_status: bool = False, + read_timeout: Union[float, object] = sentinel, + conn_timeout: Optional[float] = None, + timeout: Union[object, ClientTimeout] = sentinel, + auto_decompress: bool = True, + trust_env: bool = False, + requote_redirect_url: bool = True, + trace_configs: Optional[List[TraceConfig]] = None, + read_bufsize: int = 2**16, + fallback_charset_resolver: _CharsetResolver = ( + _default_fallback_charset_resolver + ), + ) -> None: + if loop is None: + if connector is not None: + loop = connector._loop + + loop = get_running_loop(loop) + + if base_url is None or isinstance(base_url, URL): + self._base_url: Optional[URL] = base_url + else: + self._base_url = URL(base_url) + assert ( + self._base_url.origin() == self._base_url + ), "Only absolute URLs without path part are supported" + + if connector is None: + connector = TCPConnector(loop=loop) + + if connector._loop is not loop: + raise RuntimeError("Session and connector has to use same event loop") + + self._loop = loop + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + if cookie_jar is None: + cookie_jar = CookieJar(loop=loop) + self._cookie_jar = cookie_jar + + if cookies is not None: + self._cookie_jar.update_cookies(cookies) + + self._connector = connector + self._connector_owner = connector_owner + self._default_auth = auth + self._version = version + self._json_serialize = json_serialize + if timeout is sentinel: + self._timeout = DEFAULT_TIMEOUT + if read_timeout is not sentinel: + warnings.warn( + "read_timeout is deprecated, " "use timeout argument instead", + DeprecationWarning, + stacklevel=2, + ) + self._timeout = attr.evolve(self._timeout, total=read_timeout) + if conn_timeout is not None: + self._timeout = attr.evolve(self._timeout, connect=conn_timeout) + warnings.warn( + "conn_timeout is deprecated, " "use timeout argument instead", + DeprecationWarning, + stacklevel=2, + ) + else: + self._timeout = timeout # type: ignore[assignment] + if read_timeout is not sentinel: + raise ValueError( + "read_timeout and timeout parameters " + "conflict, please setup " + "timeout.read" + ) + if conn_timeout is not None: + raise ValueError( + "conn_timeout and timeout parameters " + "conflict, please setup " + "timeout.connect" + ) + self._raise_for_status = raise_for_status + self._auto_decompress = auto_decompress + self._trust_env = trust_env + self._requote_redirect_url = requote_redirect_url + self._read_bufsize = read_bufsize + + # Convert to list of tuples + if headers: + real_headers: CIMultiDict[str] = CIMultiDict(headers) + else: + real_headers = CIMultiDict() + self._default_headers: CIMultiDict[str] = real_headers + if skip_auto_headers is not None: + self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers) + else: + self._skip_auto_headers = frozenset() + + self._request_class = request_class + self._response_class = response_class + self._ws_response_class = ws_response_class + + self._trace_configs = trace_configs or [] + for trace_config in self._trace_configs: + trace_config.freeze() + + self._resolve_charset = fallback_charset_resolver + + def __init_subclass__(cls: Type["ClientSession"]) -> None: + warnings.warn( + "Inheritance class {} from ClientSession " + "is discouraged".format(cls.__name__), + DeprecationWarning, + stacklevel=2, + ) + + if DEBUG: + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom ClientSession.{} attribute " + "is discouraged".format(name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + def __del__(self, _warnings: Any = warnings) -> None: + if not self.closed: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn( + f"Unclosed client session {self!r}", ResourceWarning, **kwargs + ) + context = {"client_session": self, "message": "Unclosed client session"} + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def request( + self, method: str, url: StrOrURL, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP request.""" + return _RequestContextManager(self._request(method, url, **kwargs)) + + def _build_url(self, str_or_url: StrOrURL) -> URL: + url = URL(str_or_url) + if self._base_url is None: + return url + else: + assert not url.is_absolute() and url.path.startswith("/") + return self._base_url.join(url) + + async def _request( + self, + method: str, + str_or_url: StrOrURL, + *, + params: Optional[Mapping[str, str]] = None, + data: Any = None, + json: Any = None, + cookies: Optional[LooseCookies] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + allow_redirects: bool = True, + max_redirects: int = 10, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + raise_for_status: Optional[bool] = None, + read_until_eof: bool = True, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + timeout: Union[ClientTimeout, object] = sentinel, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None, + proxy_headers: Optional[LooseHeaders] = None, + trace_request_ctx: Optional[SimpleNamespace] = None, + read_bufsize: Optional[int] = None, + ) -> ClientResponse: + + # NOTE: timeout clamps existing connect and read timeouts. We cannot + # set the default to None because we need to detect if the user wants + # to use the existing timeouts by setting timeout to None. + + if self.closed: + raise RuntimeError("Session is closed") + + ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + + if data is not None and json is not None: + raise ValueError( + "data and json parameters can not be used at the same time" + ) + elif json is not None: + data = payload.JsonPayload(json, dumps=self._json_serialize) + + if not isinstance(chunked, bool) and chunked is not None: + warnings.warn("Chunk size is deprecated #1615", DeprecationWarning) + + redirects = 0 + history = [] + version = self._version + + # Merge with default headers and transform to CIMultiDict + headers = self._prepare_headers(headers) + proxy_headers = self._prepare_headers(proxy_headers) + + try: + url = self._build_url(str_or_url) + except ValueError as e: + raise InvalidURL(str_or_url) from e + + skip_headers = set(self._skip_auto_headers) + if skip_auto_headers is not None: + for i in skip_auto_headers: + skip_headers.add(istr(i)) + + if proxy is not None: + try: + proxy = URL(proxy) + except ValueError as e: + raise InvalidURL(proxy) from e + + if timeout is sentinel: + real_timeout: ClientTimeout = self._timeout + else: + if not isinstance(timeout, ClientTimeout): + real_timeout = ClientTimeout(total=timeout) # type: ignore[arg-type] + else: + real_timeout = timeout + # timeout is cumulative for all request operations + # (request, redirects, responses, data consuming) + tm = TimeoutHandle(self._loop, real_timeout.total) + handle = tm.start() + + if read_bufsize is None: + read_bufsize = self._read_bufsize + + traces = [ + Trace( + self, + trace_config, + trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx), + ) + for trace_config in self._trace_configs + ] + + for trace in traces: + await trace.send_request_start(method, url.update_query(params), headers) + + timer = tm.timer() + try: + with timer: + while True: + url, auth_from_url = strip_auth_from_url(url) + if auth and auth_from_url: + raise ValueError( + "Cannot combine AUTH argument with " + "credentials encoded in URL" + ) + + if auth is None: + auth = auth_from_url + if auth is None: + auth = self._default_auth + # It would be confusing if we support explicit + # Authorization header with auth argument + if ( + headers is not None + and auth is not None + and hdrs.AUTHORIZATION in headers + ): + raise ValueError( + "Cannot combine AUTHORIZATION header " + "with AUTH argument or credentials " + "encoded in URL" + ) + + all_cookies = self._cookie_jar.filter_cookies(url) + + if cookies is not None: + tmp_cookie_jar = CookieJar() + tmp_cookie_jar.update_cookies(cookies) + req_cookies = tmp_cookie_jar.filter_cookies(url) + if req_cookies: + all_cookies.load(req_cookies) + + if proxy is not None: + proxy = URL(proxy) + elif self._trust_env: + with suppress(LookupError): + proxy, proxy_auth = get_env_proxy_for_url(url) + + req = self._request_class( + method, + url, + params=params, + headers=headers, + skip_auto_headers=skip_headers, + data=data, + cookies=all_cookies, + auth=auth, + version=version, + compress=compress, + chunked=chunked, + expect100=expect100, + loop=self._loop, + response_class=self._response_class, + proxy=proxy, + proxy_auth=proxy_auth, + timer=timer, + session=self, + ssl=ssl, + proxy_headers=proxy_headers, + traces=traces, + ) + + # connection timeout + try: + async with ceil_timeout(real_timeout.connect): + assert self._connector is not None + conn = await self._connector.connect( + req, traces=traces, timeout=real_timeout + ) + except asyncio.TimeoutError as exc: + raise ServerTimeoutError( + "Connection timeout " "to host {}".format(url) + ) from exc + + assert conn.transport is not None + + assert conn.protocol is not None + conn.protocol.set_response_params( + timer=timer, + skip_payload=method.upper() == "HEAD", + read_until_eof=read_until_eof, + auto_decompress=self._auto_decompress, + read_timeout=real_timeout.sock_read, + read_bufsize=read_bufsize, + ) + + try: + try: + resp = await req.send(conn) + try: + await resp.start(conn) + except BaseException: + resp.close() + raise + except BaseException: + conn.close() + raise + except ClientError: + raise + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise ClientOSError(*exc.args) from exc + + self._cookie_jar.update_cookies(resp.cookies, resp.url) + + # redirects + if resp.status in (301, 302, 303, 307, 308) and allow_redirects: + + for trace in traces: + await trace.send_request_redirect( + method, url.update_query(params), headers, resp + ) + + redirects += 1 + history.append(resp) + if max_redirects and redirects >= max_redirects: + resp.close() + raise TooManyRedirects( + history[0].request_info, tuple(history) + ) + + # For 301 and 302, mimic IE, now changed in RFC + # https://github.com/kennethreitz/requests/pull/269 + if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or ( + resp.status in (301, 302) and resp.method == hdrs.METH_POST + ): + method = hdrs.METH_GET + data = None + if headers.get(hdrs.CONTENT_LENGTH): + headers.pop(hdrs.CONTENT_LENGTH) + + r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get( + hdrs.URI + ) + if r_url is None: + # see github.com/aio-libs/aiohttp/issues/2022 + break + else: + # reading from correct redirection + # response is forbidden + resp.release() + + try: + parsed_url = URL( + r_url, encoded=not self._requote_redirect_url + ) + + except ValueError as e: + raise InvalidURL(r_url) from e + + scheme = parsed_url.scheme + if scheme not in ("http", "https", ""): + resp.close() + raise ValueError("Can redirect only to http or https") + elif not scheme: + parsed_url = url.join(parsed_url) + + if url.origin() != parsed_url.origin(): + auth = None + headers.pop(hdrs.AUTHORIZATION, None) + + url = parsed_url + params = None + resp.release() + continue + + break + + # check response status + if raise_for_status is None: + raise_for_status = self._raise_for_status + if raise_for_status: + resp.raise_for_status() + + # register connection + if handle is not None: + if resp.connection is not None: + resp.connection.add_callback(handle.cancel) + else: + handle.cancel() + + resp._history = tuple(history) + + for trace in traces: + await trace.send_request_end( + method, url.update_query(params), headers, resp + ) + return resp + + except BaseException as e: + # cleanup timer + tm.close() + if handle: + handle.cancel() + handle = None + + for trace in traces: + await trace.send_request_exception( + method, url.update_query(params), headers, e + ) + raise + + def ws_connect( + self, + url: StrOrURL, + *, + method: str = hdrs.METH_GET, + protocols: Iterable[str] = (), + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + auth: Optional[BasicAuth] = None, + origin: Optional[str] = None, + params: Optional[Mapping[str, str]] = None, + headers: Optional[LooseHeaders] = None, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + ssl: Union[SSLContext, bool, None, Fingerprint] = None, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + proxy_headers: Optional[LooseHeaders] = None, + compress: int = 0, + max_msg_size: int = 4 * 1024 * 1024, + ) -> "_WSRequestContextManager": + """Initiate websocket connection.""" + return _WSRequestContextManager( + self._ws_connect( + url, + method=method, + protocols=protocols, + timeout=timeout, + receive_timeout=receive_timeout, + autoclose=autoclose, + autoping=autoping, + heartbeat=heartbeat, + auth=auth, + origin=origin, + params=params, + headers=headers, + proxy=proxy, + proxy_auth=proxy_auth, + ssl=ssl, + verify_ssl=verify_ssl, + fingerprint=fingerprint, + ssl_context=ssl_context, + proxy_headers=proxy_headers, + compress=compress, + max_msg_size=max_msg_size, + ) + ) + + async def _ws_connect( + self, + url: StrOrURL, + *, + method: str = hdrs.METH_GET, + protocols: Iterable[str] = (), + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + auth: Optional[BasicAuth] = None, + origin: Optional[str] = None, + params: Optional[Mapping[str, str]] = None, + headers: Optional[LooseHeaders] = None, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + ssl: Union[SSLContext, bool, None, Fingerprint] = None, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + proxy_headers: Optional[LooseHeaders] = None, + compress: int = 0, + max_msg_size: int = 4 * 1024 * 1024, + ) -> ClientWebSocketResponse: + + if headers is None: + real_headers: CIMultiDict[str] = CIMultiDict() + else: + real_headers = CIMultiDict(headers) + + default_headers = { + hdrs.UPGRADE: "websocket", + hdrs.CONNECTION: "upgrade", + hdrs.SEC_WEBSOCKET_VERSION: "13", + } + + for key, value in default_headers.items(): + real_headers.setdefault(key, value) + + sec_key = base64.b64encode(os.urandom(16)) + real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode() + + if protocols: + real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ",".join(protocols) + if origin is not None: + real_headers[hdrs.ORIGIN] = origin + if compress: + extstr = ws_ext_gen(compress=compress) + real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr + + ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + + # send request + resp = await self.request( + method, + url, + params=params, + headers=real_headers, + read_until_eof=False, + auth=auth, + proxy=proxy, + proxy_auth=proxy_auth, + ssl=ssl, + proxy_headers=proxy_headers, + ) + + try: + # check handshake + if resp.status != 101: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid response status", + status=resp.status, + headers=resp.headers, + ) + + if resp.headers.get(hdrs.UPGRADE, "").lower() != "websocket": + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid upgrade header", + status=resp.status, + headers=resp.headers, + ) + + if resp.headers.get(hdrs.CONNECTION, "").lower() != "upgrade": + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid connection header", + status=resp.status, + headers=resp.headers, + ) + + # key calculation + r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, "") + match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode() + if r_key != match: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid challenge response", + status=resp.status, + headers=resp.headers, + ) + + # websocket protocol + protocol = None + if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers: + resp_protocols = [ + proto.strip() + for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",") + ] + + for proto in resp_protocols: + if proto in protocols: + protocol = proto + break + + # websocket compress + notakeover = False + if compress: + compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS) + if compress_hdrs: + try: + compress, notakeover = ws_ext_parse(compress_hdrs) + except WSHandshakeError as exc: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message=exc.args[0], + status=resp.status, + headers=resp.headers, + ) from exc + else: + compress = 0 + notakeover = False + + conn = resp.connection + assert conn is not None + conn_proto = conn.protocol + assert conn_proto is not None + transport = conn.transport + assert transport is not None + reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue( + conn_proto, 2**16, loop=self._loop + ) + conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader) + writer = WebSocketWriter( + conn_proto, + transport, + use_mask=True, + compress=compress, + notakeover=notakeover, + ) + except BaseException: + resp.close() + raise + else: + return self._ws_response_class( + reader, + writer, + protocol, + resp, + timeout, + autoclose, + autoping, + self._loop, + receive_timeout=receive_timeout, + heartbeat=heartbeat, + compress=compress, + client_notakeover=notakeover, + ) + + def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str]": + """Add default headers and transform it to CIMultiDict""" + # Convert headers to MultiDict + result = CIMultiDict(self._default_headers) + if headers: + if not isinstance(headers, (MultiDictProxy, MultiDict)): + headers = CIMultiDict(headers) + added_names: Set[str] = set() + for key, value in headers.items(): + if key in added_names: + result.add(key, value) + else: + result[key] = value + added_names.add(key) + return result + + def get( + self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP GET request.""" + return _RequestContextManager( + self._request(hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs) + ) + + def options( + self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP OPTIONS request.""" + return _RequestContextManager( + self._request( + hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs + ) + ) + + def head( + self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP HEAD request.""" + return _RequestContextManager( + self._request( + hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs + ) + ) + + def post( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP POST request.""" + return _RequestContextManager( + self._request(hdrs.METH_POST, url, data=data, **kwargs) + ) + + def put( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP PUT request.""" + return _RequestContextManager( + self._request(hdrs.METH_PUT, url, data=data, **kwargs) + ) + + def patch( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP PATCH request.""" + return _RequestContextManager( + self._request(hdrs.METH_PATCH, url, data=data, **kwargs) + ) + + def delete(self, url: StrOrURL, **kwargs: Any) -> "_RequestContextManager": + """Perform HTTP DELETE request.""" + return _RequestContextManager(self._request(hdrs.METH_DELETE, url, **kwargs)) + + async def close(self) -> None: + """Close underlying connector. + + Release all acquired resources. + """ + if not self.closed: + if self._connector is not None and self._connector_owner: + await self._connector.close() + self._connector = None + + @property + def closed(self) -> bool: + """Is client session closed. + + A readonly property. + """ + return self._connector is None or self._connector.closed + + @property + def connector(self) -> Optional[BaseConnector]: + """Connector instance used for the session.""" + return self._connector + + @property + def cookie_jar(self) -> AbstractCookieJar: + """The session cookies.""" + return self._cookie_jar + + @property + def version(self) -> Tuple[int, int]: + """The session HTTP protocol version.""" + return self._version + + @property + def requote_redirect_url(self) -> bool: + """Do URL requoting on redirection handling.""" + return self._requote_redirect_url + + @requote_redirect_url.setter + def requote_redirect_url(self, val: bool) -> None: + """Do URL requoting on redirection handling.""" + warnings.warn( + "session.requote_redirect_url modification " "is deprecated #2778", + DeprecationWarning, + stacklevel=2, + ) + self._requote_redirect_url = val + + @property + def loop(self) -> asyncio.AbstractEventLoop: + """Session's loop.""" + warnings.warn( + "client.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + @property + def timeout(self) -> ClientTimeout: + """Timeout for the session.""" + return self._timeout + + @property + def headers(self) -> "CIMultiDict[str]": + """The default headers of the client session.""" + return self._default_headers + + @property + def skip_auto_headers(self) -> FrozenSet[istr]: + """Headers for which autogeneration should be skipped""" + return self._skip_auto_headers + + @property + def auth(self) -> Optional[BasicAuth]: + """An object that represents HTTP Basic Authorization""" + return self._default_auth + + @property + def json_serialize(self) -> JSONEncoder: + """Json serializer callable""" + return self._json_serialize + + @property + def connector_owner(self) -> bool: + """Should connector be closed on session closing""" + return self._connector_owner + + @property + def raise_for_status( + self, + ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]: + """Should `ClientResponse.raise_for_status()` be called for each response.""" + return self._raise_for_status + + @property + def auto_decompress(self) -> bool: + """Should the body response be automatically decompressed.""" + return self._auto_decompress + + @property + def trust_env(self) -> bool: + """ + Should proxies information from environment or netrc be trusted. + + Information is from HTTP_PROXY / HTTPS_PROXY environment variables + or ~/.netrc file if present. + """ + return self._trust_env + + @property + def trace_configs(self) -> List[TraceConfig]: + """A list of TraceConfig instances used for client tracing""" + return self._trace_configs + + def detach(self) -> None: + """Detach connector from session without closing the former. + + Session is switched to closed state anyway. + """ + self._connector = None + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "ClientSession": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + await self.close() + + +class _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]): + + __slots__ = ("_coro", "_resp") + + def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> None: + self._coro = coro + + def send(self, arg: None) -> "asyncio.Future[Any]": + return self._coro.send(arg) + + def throw(self, arg: BaseException) -> None: # type: ignore[arg-type,override] + self._coro.throw(arg) + + def close(self) -> None: + return self._coro.close() + + def __await__(self) -> Generator[Any, None, _RetType]: + ret = self._coro.__await__() + return ret + + def __iter__(self) -> Generator[Any, None, _RetType]: + return self.__await__() + + async def __aenter__(self) -> _RetType: + self._resp = await self._coro + return self._resp + + +class _RequestContextManager(_BaseRequestContextManager[ClientResponse]): + __slots__ = () + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + # We're basing behavior on the exception as it can be caused by + # user code unrelated to the status of the connection. If you + # would like to close a connection you must do that + # explicitly. Otherwise connection error handling should kick in + # and close/recycle the connection as required. + self._resp.release() + + +class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]): + __slots__ = () + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + await self._resp.close() + + +class _SessionRequestContextManager: + + __slots__ = ("_coro", "_resp", "_session") + + def __init__( + self, + coro: Coroutine["asyncio.Future[Any]", None, ClientResponse], + session: ClientSession, + ) -> None: + self._coro = coro + self._resp: Optional[ClientResponse] = None + self._session = session + + async def __aenter__(self) -> ClientResponse: + try: + self._resp = await self._coro + except BaseException: + await self._session.close() + raise + else: + return self._resp + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + assert self._resp is not None + self._resp.close() + await self._session.close() + + +def request( + method: str, + url: StrOrURL, + *, + params: Optional[Mapping[str, str]] = None, + data: Any = None, + json: Any = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + allow_redirects: bool = True, + max_redirects: int = 10, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + raise_for_status: Optional[bool] = None, + read_until_eof: bool = True, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + timeout: Union[ClientTimeout, object] = sentinel, + cookies: Optional[LooseCookies] = None, + version: HttpVersion = http.HttpVersion11, + connector: Optional[BaseConnector] = None, + read_bufsize: Optional[int] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> _SessionRequestContextManager: + """Constructs and sends a request. + + Returns response object. + method - HTTP method + url - request url + params - (optional) Dictionary or bytes to be sent in the query + string of the new request + data - (optional) Dictionary, bytes, or file-like object to + send in the body of the request + json - (optional) Any json compatible python object + headers - (optional) Dictionary of HTTP Headers to send with + the request + cookies - (optional) Dict object to send with the request + auth - (optional) BasicAuth named tuple represent HTTP Basic Auth + auth - aiohttp.helpers.BasicAuth + allow_redirects - (optional) If set to False, do not follow + redirects + version - Request HTTP version. + compress - Set to True if request has to be compressed + with deflate encoding. + chunked - Set to chunk size for chunked transfer encoding. + expect100 - Expect 100-continue response from server. + connector - BaseConnector sub-class instance to support + connection pooling. + read_until_eof - Read response until eof if response + does not have Content-Length header. + loop - Optional event loop. + timeout - Optional ClientTimeout settings structure, 5min + total timeout by default. + Usage:: + >>> import aiohttp + >>> resp = await aiohttp.request('GET', 'http://python.org/') + >>> resp + + >>> data = await resp.read() + """ + connector_owner = False + if connector is None: + connector_owner = True + connector = TCPConnector(loop=loop, force_close=True) + + session = ClientSession( + loop=loop, + cookies=cookies, + version=version, + timeout=timeout, + connector=connector, + connector_owner=connector_owner, + ) + + return _SessionRequestContextManager( + session._request( + method, + url, + params=params, + data=data, + json=json, + headers=headers, + skip_auto_headers=skip_auto_headers, + auth=auth, + allow_redirects=allow_redirects, + max_redirects=max_redirects, + compress=compress, + chunked=chunked, + expect100=expect100, + raise_for_status=raise_for_status, + read_until_eof=read_until_eof, + proxy=proxy, + proxy_auth=proxy_auth, + read_bufsize=read_bufsize, + ), + session, + ) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/client_exceptions.py b/.venv/lib/python3.7/site-packages/aiohttp/client_exceptions.py new file mode 100644 index 0000000..c640e1e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/client_exceptions.py @@ -0,0 +1,342 @@ +"""HTTP related errors.""" + +import asyncio +import warnings +from typing import TYPE_CHECKING, Any, Optional, Tuple, Union + +from .http_parser import RawResponseMessage +from .typedefs import LooseHeaders + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = SSLContext = None # type: ignore[assignment] + + +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import ClientResponse, ConnectionKey, Fingerprint, RequestInfo +else: + RequestInfo = ClientResponse = ConnectionKey = None + +__all__ = ( + "ClientError", + "ClientConnectionError", + "ClientOSError", + "ClientConnectorError", + "ClientProxyConnectionError", + "ClientSSLError", + "ClientConnectorSSLError", + "ClientConnectorCertificateError", + "ServerConnectionError", + "ServerTimeoutError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ClientResponseError", + "ClientHttpProxyError", + "WSServerHandshakeError", + "ContentTypeError", + "ClientPayloadError", + "InvalidURL", +) + + +class ClientError(Exception): + """Base class for client connection errors.""" + + +class ClientResponseError(ClientError): + """Connection error during reading response. + + request_info: instance of RequestInfo + """ + + def __init__( + self, + request_info: RequestInfo, + history: Tuple[ClientResponse, ...], + *, + code: Optional[int] = None, + status: Optional[int] = None, + message: str = "", + headers: Optional[LooseHeaders] = None, + ) -> None: + self.request_info = request_info + if code is not None: + if status is not None: + raise ValueError( + "Both code and status arguments are provided; " + "code is deprecated, use status instead" + ) + warnings.warn( + "code argument is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + if status is not None: + self.status = status + elif code is not None: + self.status = code + else: + self.status = 0 + self.message = message + self.headers = headers + self.history = history + self.args = (request_info, history) + + def __str__(self) -> str: + return "{}, message={!r}, url={!r}".format( + self.status, + self.message, + self.request_info.real_url, + ) + + def __repr__(self) -> str: + args = f"{self.request_info!r}, {self.history!r}" + if self.status != 0: + args += f", status={self.status!r}" + if self.message != "": + args += f", message={self.message!r}" + if self.headers is not None: + args += f", headers={self.headers!r}" + return f"{type(self).__name__}({args})" + + @property + def code(self) -> int: + warnings.warn( + "code property is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + return self.status + + @code.setter + def code(self, value: int) -> None: + warnings.warn( + "code property is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + self.status = value + + +class ContentTypeError(ClientResponseError): + """ContentType found is not valid.""" + + +class WSServerHandshakeError(ClientResponseError): + """websocket server handshake error.""" + + +class ClientHttpProxyError(ClientResponseError): + """HTTP proxy error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + proxy responds with status other than ``200 OK`` + on ``CONNECT`` request. + """ + + +class TooManyRedirects(ClientResponseError): + """Client was redirected too many times.""" + + +class ClientConnectionError(ClientError): + """Base class for client socket errors.""" + + +class ClientOSError(ClientConnectionError, OSError): + """OSError error.""" + + +class ClientConnectorError(ClientOSError): + """Client connector error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + a connection can not be established. + """ + + def __init__(self, connection_key: ConnectionKey, os_error: OSError) -> None: + self._conn_key = connection_key + self._os_error = os_error + super().__init__(os_error.errno, os_error.strerror) + self.args = (connection_key, os_error) + + @property + def os_error(self) -> OSError: + return self._os_error + + @property + def host(self) -> str: + return self._conn_key.host + + @property + def port(self) -> Optional[int]: + return self._conn_key.port + + @property + def ssl(self) -> Union[SSLContext, None, bool, "Fingerprint"]: + return self._conn_key.ssl + + def __str__(self) -> str: + return "Cannot connect to host {0.host}:{0.port} ssl:{1} [{2}]".format( + self, self.ssl if self.ssl is not None else "default", self.strerror + ) + + # OSError.__reduce__ does too much black magick + __reduce__ = BaseException.__reduce__ + + +class ClientProxyConnectionError(ClientConnectorError): + """Proxy connection error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + connection to proxy can not be established. + """ + + +class UnixClientConnectorError(ClientConnectorError): + """Unix connector error. + + Raised in :py:class:`aiohttp.connector.UnixConnector` + if connection to unix socket can not be established. + """ + + def __init__( + self, path: str, connection_key: ConnectionKey, os_error: OSError + ) -> None: + self._path = path + super().__init__(connection_key, os_error) + + @property + def path(self) -> str: + return self._path + + def __str__(self) -> str: + return "Cannot connect to unix socket {0.path} ssl:{1} [{2}]".format( + self, self.ssl if self.ssl is not None else "default", self.strerror + ) + + +class ServerConnectionError(ClientConnectionError): + """Server connection errors.""" + + +class ServerDisconnectedError(ServerConnectionError): + """Server disconnected.""" + + def __init__(self, message: Union[RawResponseMessage, str, None] = None) -> None: + if message is None: + message = "Server disconnected" + + self.args = (message,) + self.message = message + + +class ServerTimeoutError(ServerConnectionError, asyncio.TimeoutError): + """Server timeout error.""" + + +class ServerFingerprintMismatch(ServerConnectionError): + """SSL certificate does not match expected fingerprint.""" + + def __init__(self, expected: bytes, got: bytes, host: str, port: int) -> None: + self.expected = expected + self.got = got + self.host = host + self.port = port + self.args = (expected, got, host, port) + + def __repr__(self) -> str: + return "<{} expected={!r} got={!r} host={!r} port={!r}>".format( + self.__class__.__name__, self.expected, self.got, self.host, self.port + ) + + +class ClientPayloadError(ClientError): + """Response payload error.""" + + +class InvalidURL(ClientError, ValueError): + """Invalid URL. + + URL used for fetching is malformed, e.g. it doesn't contains host + part. + """ + + # Derive from ValueError for backward compatibility + + def __init__(self, url: Any) -> None: + # The type of url is not yarl.URL because the exception can be raised + # on URL(url) call + super().__init__(url) + + @property + def url(self) -> Any: + return self.args[0] + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.url}>" + + +class ClientSSLError(ClientConnectorError): + """Base error for ssl.*Errors.""" + + +if ssl is not None: + cert_errors = (ssl.CertificateError,) + cert_errors_bases = ( + ClientSSLError, + ssl.CertificateError, + ) + + ssl_errors = (ssl.SSLError,) + ssl_error_bases = (ClientSSLError, ssl.SSLError) +else: # pragma: no cover + cert_errors = tuple() + cert_errors_bases = ( + ClientSSLError, + ValueError, + ) + + ssl_errors = tuple() + ssl_error_bases = (ClientSSLError,) + + +class ClientConnectorSSLError(*ssl_error_bases): # type: ignore[misc] + """Response ssl error.""" + + +class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore[misc] + """Response certificate error.""" + + def __init__( + self, connection_key: ConnectionKey, certificate_error: Exception + ) -> None: + self._conn_key = connection_key + self._certificate_error = certificate_error + self.args = (connection_key, certificate_error) + + @property + def certificate_error(self) -> Exception: + return self._certificate_error + + @property + def host(self) -> str: + return self._conn_key.host + + @property + def port(self) -> Optional[int]: + return self._conn_key.port + + @property + def ssl(self) -> bool: + return self._conn_key.is_ssl + + def __str__(self) -> str: + return ( + "Cannot connect to host {0.host}:{0.port} ssl:{0.ssl} " + "[{0.certificate_error.__class__.__name__}: " + "{0.certificate_error.args}]".format(self) + ) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/client_proto.py b/.venv/lib/python3.7/site-packages/aiohttp/client_proto.py new file mode 100644 index 0000000..3041157 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/client_proto.py @@ -0,0 +1,251 @@ +import asyncio +from contextlib import suppress +from typing import Any, Optional, Tuple + +from .base_protocol import BaseProtocol +from .client_exceptions import ( + ClientOSError, + ClientPayloadError, + ServerDisconnectedError, + ServerTimeoutError, +) +from .helpers import BaseTimerContext +from .http import HttpResponseParser, RawResponseMessage +from .streams import EMPTY_PAYLOAD, DataQueue, StreamReader + + +class ResponseHandler(BaseProtocol, DataQueue[Tuple[RawResponseMessage, StreamReader]]): + """Helper class to adapt between Protocol and StreamReader.""" + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + BaseProtocol.__init__(self, loop=loop) + DataQueue.__init__(self, loop) + + self._should_close = False + + self._payload: Optional[StreamReader] = None + self._skip_payload = False + self._payload_parser = None + + self._timer = None + + self._tail = b"" + self._upgraded = False + self._parser: Optional[HttpResponseParser] = None + + self._read_timeout: Optional[float] = None + self._read_timeout_handle: Optional[asyncio.TimerHandle] = None + + @property + def upgraded(self) -> bool: + return self._upgraded + + @property + def should_close(self) -> bool: + if self._payload is not None and not self._payload.is_eof() or self._upgraded: + return True + + return ( + self._should_close + or self._upgraded + or self.exception() is not None + or self._payload_parser is not None + or len(self) > 0 + or bool(self._tail) + ) + + def force_close(self) -> None: + self._should_close = True + + def close(self) -> None: + transport = self.transport + if transport is not None: + transport.close() + self.transport = None + self._payload = None + self._drop_timeout() + + def is_connected(self) -> bool: + return self.transport is not None and not self.transport.is_closing() + + def connection_lost(self, exc: Optional[BaseException]) -> None: + self._drop_timeout() + + if self._payload_parser is not None: + with suppress(Exception): + self._payload_parser.feed_eof() + + uncompleted = None + if self._parser is not None: + try: + uncompleted = self._parser.feed_eof() + except Exception: + if self._payload is not None: + self._payload.set_exception( + ClientPayloadError("Response payload is not completed") + ) + + if not self.is_eof(): + if isinstance(exc, OSError): + exc = ClientOSError(*exc.args) + if exc is None: + exc = ServerDisconnectedError(uncompleted) + # assigns self._should_close to True as side effect, + # we do it anyway below + self.set_exception(exc) + + self._should_close = True + self._parser = None + self._payload = None + self._payload_parser = None + self._reading_paused = False + + super().connection_lost(exc) + + def eof_received(self) -> None: + # should call parser.feed_eof() most likely + self._drop_timeout() + + def pause_reading(self) -> None: + super().pause_reading() + self._drop_timeout() + + def resume_reading(self) -> None: + super().resume_reading() + self._reschedule_timeout() + + def set_exception(self, exc: BaseException) -> None: + self._should_close = True + self._drop_timeout() + super().set_exception(exc) + + def set_parser(self, parser: Any, payload: Any) -> None: + # TODO: actual types are: + # parser: WebSocketReader + # payload: FlowControlDataQueue + # but they are not generi enough + # Need an ABC for both types + self._payload = payload + self._payload_parser = parser + + self._drop_timeout() + + if self._tail: + data, self._tail = self._tail, b"" + self.data_received(data) + + def set_response_params( + self, + *, + timer: Optional[BaseTimerContext] = None, + skip_payload: bool = False, + read_until_eof: bool = False, + auto_decompress: bool = True, + read_timeout: Optional[float] = None, + read_bufsize: int = 2**16, + ) -> None: + self._skip_payload = skip_payload + + self._read_timeout = read_timeout + self._reschedule_timeout() + + self._parser = HttpResponseParser( + self, + self._loop, + read_bufsize, + timer=timer, + payload_exception=ClientPayloadError, + response_with_body=not skip_payload, + read_until_eof=read_until_eof, + auto_decompress=auto_decompress, + ) + + if self._tail: + data, self._tail = self._tail, b"" + self.data_received(data) + + def _drop_timeout(self) -> None: + if self._read_timeout_handle is not None: + self._read_timeout_handle.cancel() + self._read_timeout_handle = None + + def _reschedule_timeout(self) -> None: + timeout = self._read_timeout + if self._read_timeout_handle is not None: + self._read_timeout_handle.cancel() + + if timeout: + self._read_timeout_handle = self._loop.call_later( + timeout, self._on_read_timeout + ) + else: + self._read_timeout_handle = None + + def _on_read_timeout(self) -> None: + exc = ServerTimeoutError("Timeout on reading data from socket") + self.set_exception(exc) + if self._payload is not None: + self._payload.set_exception(exc) + + def data_received(self, data: bytes) -> None: + self._reschedule_timeout() + + if not data: + return + + # custom payload parser + if self._payload_parser is not None: + eof, tail = self._payload_parser.feed_data(data) + if eof: + self._payload = None + self._payload_parser = None + + if tail: + self.data_received(tail) + return + else: + if self._upgraded or self._parser is None: + # i.e. websocket connection, websocket parser is not set yet + self._tail += data + else: + # parse http messages + try: + messages, upgraded, tail = self._parser.feed_data(data) + except BaseException as exc: + if self.transport is not None: + # connection.release() could be called BEFORE + # data_received(), the transport is already + # closed in this case + self.transport.close() + # should_close is True after the call + self.set_exception(exc) + return + + self._upgraded = upgraded + + payload: Optional[StreamReader] = None + for message, payload in messages: + if message.should_close: + self._should_close = True + + self._payload = payload + + if self._skip_payload or message.code in (204, 304): + self.feed_data((message, EMPTY_PAYLOAD), 0) + else: + self.feed_data((message, payload), 0) + if payload is not None: + # new message(s) was processed + # register timeout handler unsubscribing + # either on end-of-stream or immediately for + # EMPTY_PAYLOAD + if payload is not EMPTY_PAYLOAD: + payload.on_eof(self._drop_timeout) + else: + self._drop_timeout() + + if tail: + if upgraded: + self.data_received(tail) + else: + self._tail = tail diff --git a/.venv/lib/python3.7/site-packages/aiohttp/client_reqrep.py b/.venv/lib/python3.7/site-packages/aiohttp/client_reqrep.py new file mode 100644 index 0000000..987d68f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/client_reqrep.py @@ -0,0 +1,1135 @@ +import asyncio +import codecs +import contextlib +import functools +import io +import re +import sys +import traceback +import warnings +from hashlib import md5, sha1, sha256 +from http.cookies import CookieError, Morsel, SimpleCookie +from types import MappingProxyType, TracebackType +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Iterable, + List, + Mapping, + Optional, + Tuple, + Type, + Union, + cast, +) + +import attr +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +from yarl import URL + +from . import hdrs, helpers, http, multipart, payload +from .abc import AbstractStreamWriter +from .client_exceptions import ( + ClientConnectionError, + ClientOSError, + ClientResponseError, + ContentTypeError, + InvalidURL, + ServerFingerprintMismatch, +) +from .formdata import FormData +from .helpers import ( + PY_36, + BaseTimerContext, + BasicAuth, + HeadersMixin, + TimerNoop, + noop, + reify, + set_result, +) +from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11, StreamWriter +from .log import client_logger +from .streams import StreamReader +from .typedefs import ( + DEFAULT_JSON_DECODER, + JSONDecoder, + LooseCookies, + LooseHeaders, + RawHeaders, +) + +try: + import ssl + from ssl import SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] + + +__all__ = ("ClientRequest", "ClientResponse", "RequestInfo", "Fingerprint") + + +if TYPE_CHECKING: # pragma: no cover + from .client import ClientSession + from .connector import Connection + from .tracing import Trace + + +json_re = re.compile(r"^application/(?:[\w.+-]+?\+)?json") + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ContentDisposition: + type: Optional[str] + parameters: "MappingProxyType[str, str]" + filename: Optional[str] + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class RequestInfo: + url: URL + method: str + headers: "CIMultiDictProxy[str]" + real_url: URL = attr.ib() + + @real_url.default + def real_url_default(self) -> URL: + return self.url + + +class Fingerprint: + HASHFUNC_BY_DIGESTLEN = { + 16: md5, + 20: sha1, + 32: sha256, + } + + def __init__(self, fingerprint: bytes) -> None: + digestlen = len(fingerprint) + hashfunc = self.HASHFUNC_BY_DIGESTLEN.get(digestlen) + if not hashfunc: + raise ValueError("fingerprint has invalid length") + elif hashfunc is md5 or hashfunc is sha1: + raise ValueError( + "md5 and sha1 are insecure and " "not supported. Use sha256." + ) + self._hashfunc = hashfunc + self._fingerprint = fingerprint + + @property + def fingerprint(self) -> bytes: + return self._fingerprint + + def check(self, transport: asyncio.Transport) -> None: + if not transport.get_extra_info("sslcontext"): + return + sslobj = transport.get_extra_info("ssl_object") + cert = sslobj.getpeercert(binary_form=True) + got = self._hashfunc(cert).digest() + if got != self._fingerprint: + host, port, *_ = transport.get_extra_info("peername") + raise ServerFingerprintMismatch(self._fingerprint, got, host, port) + + +if ssl is not None: + SSL_ALLOWED_TYPES = (ssl.SSLContext, bool, Fingerprint, type(None)) +else: # pragma: no cover + SSL_ALLOWED_TYPES = type(None) + + +def _merge_ssl_params( + ssl: Union["SSLContext", bool, Fingerprint, None], + verify_ssl: Optional[bool], + ssl_context: Optional["SSLContext"], + fingerprint: Optional[bytes], +) -> Union["SSLContext", bool, Fingerprint, None]: + if verify_ssl is not None and not verify_ssl: + warnings.warn( + "verify_ssl is deprecated, use ssl=False instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = False + if ssl_context is not None: + warnings.warn( + "ssl_context is deprecated, use ssl=context instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = ssl_context + if fingerprint is not None: + warnings.warn( + "fingerprint is deprecated, " "use ssl=Fingerprint(fingerprint) instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = Fingerprint(fingerprint) + if not isinstance(ssl, SSL_ALLOWED_TYPES): + raise TypeError( + "ssl should be SSLContext, bool, Fingerprint or None, " + "got {!r} instead.".format(ssl) + ) + return ssl + + +@attr.s(auto_attribs=True, slots=True, frozen=True) +class ConnectionKey: + # the key should contain an information about used proxy / TLS + # to prevent reusing wrong connections from a pool + host: str + port: Optional[int] + is_ssl: bool + ssl: Union[SSLContext, None, bool, Fingerprint] + proxy: Optional[URL] + proxy_auth: Optional[BasicAuth] + proxy_headers_hash: Optional[int] # hash(CIMultiDict) + + +def _is_expected_content_type( + response_content_type: str, expected_content_type: str +) -> bool: + if expected_content_type == "application/json": + return json_re.match(response_content_type) is not None + return expected_content_type in response_content_type + + +class ClientRequest: + GET_METHODS = { + hdrs.METH_GET, + hdrs.METH_HEAD, + hdrs.METH_OPTIONS, + hdrs.METH_TRACE, + } + POST_METHODS = {hdrs.METH_PATCH, hdrs.METH_POST, hdrs.METH_PUT} + ALL_METHODS = GET_METHODS.union(POST_METHODS).union({hdrs.METH_DELETE}) + + DEFAULT_HEADERS = { + hdrs.ACCEPT: "*/*", + hdrs.ACCEPT_ENCODING: "gzip, deflate", + } + + body = b"" + auth = None + response = None + + _writer = None # async task for streaming data + _continue = None # waiter future for '100 Continue' response + + # N.B. + # Adding __del__ method with self._writer closing doesn't make sense + # because _writer is instance method, thus it keeps a reference to self. + # Until writer has finished finalizer will not be called. + + def __init__( + self, + method: str, + url: URL, + *, + params: Optional[Mapping[str, str]] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Iterable[str] = frozenset(), + data: Any = None, + cookies: Optional[LooseCookies] = None, + auth: Optional[BasicAuth] = None, + version: http.HttpVersion = http.HttpVersion11, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + response_class: Optional[Type["ClientResponse"]] = None, + proxy: Optional[URL] = None, + proxy_auth: Optional[BasicAuth] = None, + timer: Optional[BaseTimerContext] = None, + session: Optional["ClientSession"] = None, + ssl: Union[SSLContext, bool, Fingerprint, None] = None, + proxy_headers: Optional[LooseHeaders] = None, + traces: Optional[List["Trace"]] = None, + ): + + if loop is None: + loop = asyncio.get_event_loop() + + assert isinstance(url, URL), url + assert isinstance(proxy, (URL, type(None))), proxy + # FIXME: session is None in tests only, need to fix tests + # assert session is not None + self._session = cast("ClientSession", session) + if params: + q = MultiDict(url.query) + url2 = url.with_query(params) + q.extend(url2.query) + url = url.with_query(q) + self.original_url = url + self.url = url.with_fragment(None) + self.method = method.upper() + self.chunked = chunked + self.compress = compress + self.loop = loop + self.length = None + if response_class is None: + real_response_class = ClientResponse + else: + real_response_class = response_class + self.response_class: Type[ClientResponse] = real_response_class + self._timer = timer if timer is not None else TimerNoop() + self._ssl = ssl + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + self.update_version(version) + self.update_host(url) + self.update_headers(headers) + self.update_auto_headers(skip_auto_headers) + self.update_cookies(cookies) + self.update_content_encoding(data) + self.update_auth(auth) + self.update_proxy(proxy, proxy_auth, proxy_headers) + + self.update_body_from_data(data) + if data is not None or self.method not in self.GET_METHODS: + self.update_transfer_encoding() + self.update_expect_continue(expect100) + if traces is None: + traces = [] + self._traces = traces + + def is_ssl(self) -> bool: + return self.url.scheme in ("https", "wss") + + @property + def ssl(self) -> Union["SSLContext", None, bool, Fingerprint]: + return self._ssl + + @property + def connection_key(self) -> ConnectionKey: + proxy_headers = self.proxy_headers + if proxy_headers: + h: Optional[int] = hash(tuple((k, v) for k, v in proxy_headers.items())) + else: + h = None + return ConnectionKey( + self.host, + self.port, + self.is_ssl(), + self.ssl, + self.proxy, + self.proxy_auth, + h, + ) + + @property + def host(self) -> str: + ret = self.url.raw_host + assert ret is not None + return ret + + @property + def port(self) -> Optional[int]: + return self.url.port + + @property + def request_info(self) -> RequestInfo: + headers: CIMultiDictProxy[str] = CIMultiDictProxy(self.headers) + return RequestInfo(self.url, self.method, headers, self.original_url) + + def update_host(self, url: URL) -> None: + """Update destination host, port and connection type (ssl).""" + # get host/port + if not url.raw_host: + raise InvalidURL(url) + + # basic auth info + username, password = url.user, url.password + if username: + self.auth = helpers.BasicAuth(username, password or "") + + def update_version(self, version: Union[http.HttpVersion, str]) -> None: + """Convert request version to two elements tuple. + + parser HTTP version '1.1' => (1, 1) + """ + if isinstance(version, str): + v = [part.strip() for part in version.split(".", 1)] + try: + version = http.HttpVersion(int(v[0]), int(v[1])) + except ValueError: + raise ValueError( + f"Can not parse http version number: {version}" + ) from None + self.version = version + + def update_headers(self, headers: Optional[LooseHeaders]) -> None: + """Update request headers.""" + self.headers: CIMultiDict[str] = CIMultiDict() + + # add host + netloc = cast(str, self.url.raw_host) + if helpers.is_ipv6_address(netloc): + netloc = f"[{netloc}]" + if self.url.port is not None and not self.url.is_default_port(): + netloc += ":" + str(self.url.port) + self.headers[hdrs.HOST] = netloc + + if headers: + if isinstance(headers, (dict, MultiDictProxy, MultiDict)): + headers = headers.items() # type: ignore[assignment] + + for key, value in headers: # type: ignore[misc] + # A special case for Host header + if key.lower() == "host": + self.headers[key] = value + else: + self.headers.add(key, value) + + def update_auto_headers(self, skip_auto_headers: Iterable[str]) -> None: + self.skip_auto_headers = CIMultiDict( + (hdr, None) for hdr in sorted(skip_auto_headers) + ) + used_headers = self.headers.copy() + used_headers.extend(self.skip_auto_headers) # type: ignore[arg-type] + + for hdr, val in self.DEFAULT_HEADERS.items(): + if hdr not in used_headers: + self.headers.add(hdr, val) + + if hdrs.USER_AGENT not in used_headers: + self.headers[hdrs.USER_AGENT] = SERVER_SOFTWARE + + def update_cookies(self, cookies: Optional[LooseCookies]) -> None: + """Update request cookies header.""" + if not cookies: + return + + c: SimpleCookie[str] = SimpleCookie() + if hdrs.COOKIE in self.headers: + c.load(self.headers.get(hdrs.COOKIE, "")) + del self.headers[hdrs.COOKIE] + + if isinstance(cookies, Mapping): + iter_cookies = cookies.items() + else: + iter_cookies = cookies # type: ignore[assignment] + for name, value in iter_cookies: + if isinstance(value, Morsel): + # Preserve coded_value + mrsl_val = value.get(value.key, Morsel()) + mrsl_val.set(value.key, value.value, value.coded_value) + c[name] = mrsl_val + else: + c[name] = value # type: ignore[assignment] + + self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip() + + def update_content_encoding(self, data: Any) -> None: + """Set request content encoding.""" + if data is None: + return + + enc = self.headers.get(hdrs.CONTENT_ENCODING, "").lower() + if enc: + if self.compress: + raise ValueError( + "compress can not be set " "if Content-Encoding header is set" + ) + elif self.compress: + if not isinstance(self.compress, str): + self.compress = "deflate" + self.headers[hdrs.CONTENT_ENCODING] = self.compress + self.chunked = True # enable chunked, no need to deal with length + + def update_transfer_encoding(self) -> None: + """Analyze transfer-encoding header.""" + te = self.headers.get(hdrs.TRANSFER_ENCODING, "").lower() + + if "chunked" in te: + if self.chunked: + raise ValueError( + "chunked can not be set " + 'if "Transfer-Encoding: chunked" header is set' + ) + + elif self.chunked: + if hdrs.CONTENT_LENGTH in self.headers: + raise ValueError( + "chunked can not be set " "if Content-Length header is set" + ) + + self.headers[hdrs.TRANSFER_ENCODING] = "chunked" + else: + if hdrs.CONTENT_LENGTH not in self.headers: + self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) + + def update_auth(self, auth: Optional[BasicAuth]) -> None: + """Set basic auth.""" + if auth is None: + auth = self.auth + if auth is None: + return + + if not isinstance(auth, helpers.BasicAuth): + raise TypeError("BasicAuth() tuple is required instead") + + self.headers[hdrs.AUTHORIZATION] = auth.encode() + + def update_body_from_data(self, body: Any) -> None: + if body is None: + return + + # FormData + if isinstance(body, FormData): + body = body() + + try: + body = payload.PAYLOAD_REGISTRY.get(body, disposition=None) + except payload.LookupError: + body = FormData(body)() + + self.body = body + + # enable chunked encoding if needed + if not self.chunked: + if hdrs.CONTENT_LENGTH not in self.headers: + size = body.size + if size is None: + self.chunked = True + else: + if hdrs.CONTENT_LENGTH not in self.headers: + self.headers[hdrs.CONTENT_LENGTH] = str(size) + + # copy payload headers + assert body.headers + for (key, value) in body.headers.items(): + if key in self.headers: + continue + if key in self.skip_auto_headers: + continue + self.headers[key] = value + + def update_expect_continue(self, expect: bool = False) -> None: + if expect: + self.headers[hdrs.EXPECT] = "100-continue" + elif self.headers.get(hdrs.EXPECT, "").lower() == "100-continue": + expect = True + + if expect: + self._continue = self.loop.create_future() + + def update_proxy( + self, + proxy: Optional[URL], + proxy_auth: Optional[BasicAuth], + proxy_headers: Optional[LooseHeaders], + ) -> None: + if proxy_auth and not isinstance(proxy_auth, helpers.BasicAuth): + raise ValueError("proxy_auth must be None or BasicAuth() tuple") + self.proxy = proxy + self.proxy_auth = proxy_auth + self.proxy_headers = proxy_headers + + def keep_alive(self) -> bool: + if self.version < HttpVersion10: + # keep alive not supported at all + return False + if self.version == HttpVersion10: + if self.headers.get(hdrs.CONNECTION) == "keep-alive": + return True + else: # no headers means we close for Http 1.0 + return False + elif self.headers.get(hdrs.CONNECTION) == "close": + return False + + return True + + async def write_bytes( + self, writer: AbstractStreamWriter, conn: "Connection" + ) -> None: + """Support coroutines that yields bytes objects.""" + # 100 response + if self._continue is not None: + await writer.drain() + await self._continue + + protocol = conn.protocol + assert protocol is not None + try: + if isinstance(self.body, payload.Payload): + await self.body.write(writer) + else: + if isinstance(self.body, (bytes, bytearray)): + self.body = (self.body,) # type: ignore[assignment] + + for chunk in self.body: + await writer.write(chunk) # type: ignore[arg-type] + + await writer.write_eof() + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + protocol.set_exception(exc) + else: + new_exc = ClientOSError( + exc.errno, "Can not write request body for %s" % self.url + ) + new_exc.__context__ = exc + new_exc.__cause__ = exc + protocol.set_exception(new_exc) + except asyncio.CancelledError as exc: + if not conn.closed: + protocol.set_exception(exc) + except Exception as exc: + protocol.set_exception(exc) + finally: + self._writer = None + + async def send(self, conn: "Connection") -> "ClientResponse": + # Specify request target: + # - CONNECT request must send authority form URI + # - not CONNECT proxy must send absolute form URI + # - most common is origin form URI + if self.method == hdrs.METH_CONNECT: + connect_host = self.url.raw_host + assert connect_host is not None + if helpers.is_ipv6_address(connect_host): + connect_host = f"[{connect_host}]" + path = f"{connect_host}:{self.url.port}" + elif self.proxy and not self.is_ssl(): + path = str(self.url) + else: + path = self.url.raw_path + if self.url.raw_query_string: + path += "?" + self.url.raw_query_string + + protocol = conn.protocol + assert protocol is not None + writer = StreamWriter( + protocol, + self.loop, + on_chunk_sent=functools.partial( + self._on_chunk_request_sent, self.method, self.url + ), + on_headers_sent=functools.partial( + self._on_headers_request_sent, self.method, self.url + ), + ) + + if self.compress: + writer.enable_compression(self.compress) + + if self.chunked is not None: + writer.enable_chunking() + + # set default content-type + if ( + self.method in self.POST_METHODS + and hdrs.CONTENT_TYPE not in self.skip_auto_headers + and hdrs.CONTENT_TYPE not in self.headers + ): + self.headers[hdrs.CONTENT_TYPE] = "application/octet-stream" + + # set the connection header + connection = self.headers.get(hdrs.CONNECTION) + if not connection: + if self.keep_alive(): + if self.version == HttpVersion10: + connection = "keep-alive" + else: + if self.version == HttpVersion11: + connection = "close" + + if connection is not None: + self.headers[hdrs.CONNECTION] = connection + + # status + headers + status_line = "{0} {1} HTTP/{2[0]}.{2[1]}".format( + self.method, path, self.version + ) + await writer.write_headers(status_line, self.headers) + + self._writer = self.loop.create_task(self.write_bytes(writer, conn)) + + response_class = self.response_class + assert response_class is not None + self.response = response_class( + self.method, + self.original_url, + writer=self._writer, + continue100=self._continue, + timer=self._timer, + request_info=self.request_info, + traces=self._traces, + loop=self.loop, + session=self._session, + ) + return self.response + + async def close(self) -> None: + if self._writer is not None: + try: + await self._writer + finally: + self._writer = None + + def terminate(self) -> None: + if self._writer is not None: + if not self.loop.is_closed(): + self._writer.cancel() + self._writer = None + + async def _on_chunk_request_sent(self, method: str, url: URL, chunk: bytes) -> None: + for trace in self._traces: + await trace.send_request_chunk_sent(method, url, chunk) + + async def _on_headers_request_sent( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + for trace in self._traces: + await trace.send_request_headers(method, url, headers) + + +class ClientResponse(HeadersMixin): + + # from the Status-Line of the response + version = None # HTTP-Version + status: int = None # type: ignore[assignment] # Status-Code + reason = None # Reason-Phrase + + content: StreamReader = None # type: ignore[assignment] # Payload stream + _headers: "CIMultiDictProxy[str]" = None # type: ignore[assignment] + _raw_headers: RawHeaders = None # type: ignore[assignment] # Response raw headers + + _connection = None # current connection + _source_traceback: Optional[traceback.StackSummary] = None + # set up by ClientRequest after ClientResponse object creation + # post-init stage allows to not change ctor signature + _closed = True # to allow __del__ for non-initialized properly response + _released = False + + def __init__( + self, + method: str, + url: URL, + *, + writer: "asyncio.Task[None]", + continue100: Optional["asyncio.Future[bool]"], + timer: BaseTimerContext, + request_info: RequestInfo, + traces: List["Trace"], + loop: asyncio.AbstractEventLoop, + session: "ClientSession", + ) -> None: + assert isinstance(url, URL) + + self.method = method + self.cookies: SimpleCookie[str] = SimpleCookie() + + self._real_url = url + self._url = url.with_fragment(None) + self._body: Any = None + self._writer: Optional[asyncio.Task[None]] = writer + self._continue = continue100 # None by default + self._closed = True + self._history: Tuple[ClientResponse, ...] = () + self._request_info = request_info + self._timer = timer if timer is not None else TimerNoop() + self._cache: Dict[str, Any] = {} + self._traces = traces + self._loop = loop + # store a reference to session #1985 + self._session: Optional[ClientSession] = session + # Save reference to _resolve_charset, so that get_encoding() will still + # work after the response has finished reading the body. + if session is None: + # TODO: Fix session=None in tests (see ClientRequest.__init__). + self._resolve_charset: Callable[ + ["ClientResponse", bytes], str + ] = lambda *_: "utf-8" + else: + self._resolve_charset = session._resolve_charset + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + @reify + def url(self) -> URL: + return self._url + + @reify + def url_obj(self) -> URL: + warnings.warn("Deprecated, use .url #1654", DeprecationWarning, stacklevel=2) + return self._url + + @reify + def real_url(self) -> URL: + return self._real_url + + @reify + def host(self) -> str: + assert self._url.host is not None + return self._url.host + + @reify + def headers(self) -> "CIMultiDictProxy[str]": + return self._headers + + @reify + def raw_headers(self) -> RawHeaders: + return self._raw_headers + + @reify + def request_info(self) -> RequestInfo: + return self._request_info + + @reify + def content_disposition(self) -> Optional[ContentDisposition]: + raw = self._headers.get(hdrs.CONTENT_DISPOSITION) + if raw is None: + return None + disposition_type, params_dct = multipart.parse_content_disposition(raw) + params = MappingProxyType(params_dct) + filename = multipart.content_disposition_filename(params) + return ContentDisposition(disposition_type, params, filename) + + def __del__(self, _warnings: Any = warnings) -> None: + if self._closed: + return + + if self._connection is not None: + self._connection.release() + self._cleanup_writer() + + if self._loop.get_debug(): + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed response {self!r}", ResourceWarning, **kwargs) + context = {"client_response": self, "message": "Unclosed response"} + if self._source_traceback: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def __repr__(self) -> str: + out = io.StringIO() + ascii_encodable_url = str(self.url) + if self.reason: + ascii_encodable_reason = self.reason.encode( + "ascii", "backslashreplace" + ).decode("ascii") + else: + ascii_encodable_reason = self.reason + print( + "".format( + ascii_encodable_url, self.status, ascii_encodable_reason + ), + file=out, + ) + print(self.headers, file=out) + return out.getvalue() + + @property + def connection(self) -> Optional["Connection"]: + return self._connection + + @reify + def history(self) -> Tuple["ClientResponse", ...]: + """A sequence of of responses, if redirects occurred.""" + return self._history + + @reify + def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]": + links_str = ", ".join(self.headers.getall("link", [])) + + if not links_str: + return MultiDictProxy(MultiDict()) + + links: MultiDict[MultiDictProxy[Union[str, URL]]] = MultiDict() + + for val in re.split(r",(?=\s*<)", links_str): + match = re.match(r"\s*<(.*)>(.*)", val) + if match is None: # pragma: no cover + # the check exists to suppress mypy error + continue + url, params_str = match.groups() + params = params_str.split(";")[1:] + + link: MultiDict[Union[str, URL]] = MultiDict() + + for param in params: + match = re.match(r"^\s*(\S*)\s*=\s*(['\"]?)(.*?)(\2)\s*$", param, re.M) + if match is None: # pragma: no cover + # the check exists to suppress mypy error + continue + key, _, value, _ = match.groups() + + link.add(key, value) + + key = link.get("rel", url) # type: ignore[assignment] + + link.add("url", self.url.join(URL(url))) + + links.add(key, MultiDictProxy(link)) + + return MultiDictProxy(links) + + async def start(self, connection: "Connection") -> "ClientResponse": + """Start response processing.""" + self._closed = False + self._protocol = connection.protocol + self._connection = connection + + with self._timer: + while True: + # read response + try: + protocol = self._protocol + message, payload = await protocol.read() # type: ignore[union-attr] + except http.HttpProcessingError as exc: + raise ClientResponseError( + self.request_info, + self.history, + status=exc.code, + message=exc.message, + headers=exc.headers, + ) from exc + + if message.code < 100 or message.code > 199 or message.code == 101: + break + + if self._continue is not None: + set_result(self._continue, True) + self._continue = None + + # payload eof handler + payload.on_eof(self._response_eof) + + # response status + self.version = message.version + self.status = message.code + self.reason = message.reason + + # headers + self._headers = message.headers # type is CIMultiDictProxy + self._raw_headers = message.raw_headers # type is Tuple[bytes, bytes] + + # payload + self.content = payload + + # cookies + for hdr in self.headers.getall(hdrs.SET_COOKIE, ()): + try: + self.cookies.load(hdr) + except CookieError as exc: + client_logger.warning("Can not load response cookies: %s", exc) + return self + + def _response_eof(self) -> None: + if self._closed: + return + + if self._connection is not None: + # websocket, protocol could be None because + # connection could be detached + if ( + self._connection.protocol is not None + and self._connection.protocol.upgraded + ): + return + + self._connection.release() + self._connection = None + + self._closed = True + self._cleanup_writer() + + @property + def closed(self) -> bool: + return self._closed + + def close(self) -> None: + if not self._released: + self._notify_content() + if self._closed: + return + + self._closed = True + if self._loop is None or self._loop.is_closed(): + return + + if self._connection is not None: + self._connection.close() + self._connection = None + self._cleanup_writer() + + def release(self) -> Any: + if not self._released: + self._notify_content() + if self._closed: + return noop() + + self._closed = True + if self._connection is not None: + self._connection.release() + self._connection = None + + self._cleanup_writer() + return noop() + + @property + def ok(self) -> bool: + """Returns ``True`` if ``status`` is less than ``400``, ``False`` if not. + + This is **not** a check for ``200 OK`` but a check that the response + status is under 400. + """ + return 400 > self.status + + def raise_for_status(self) -> None: + if not self.ok: + # reason should always be not None for a started response + assert self.reason is not None + self.release() + raise ClientResponseError( + self.request_info, + self.history, + status=self.status, + message=self.reason, + headers=self.headers, + ) + + def _cleanup_writer(self) -> None: + if self._writer is not None: + self._writer.cancel() + self._writer = None + self._session = None + + def _notify_content(self) -> None: + content = self.content + if content and content.exception() is None: + content.set_exception(ClientConnectionError("Connection closed")) + self._released = True + + async def wait_for_close(self) -> None: + if self._writer is not None: + try: + await self._writer + finally: + self._writer = None + self.release() + + async def read(self) -> bytes: + """Read response payload.""" + if self._body is None: + try: + self._body = await self.content.read() + for trace in self._traces: + await trace.send_response_chunk_received( + self.method, self.url, self._body + ) + except BaseException: + self.close() + raise + elif self._released: + raise ClientConnectionError("Connection closed") + + return self._body # type: ignore[no-any-return] + + def get_encoding(self) -> str: + ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower() + mimetype = helpers.parse_mimetype(ctype) + + encoding = mimetype.parameters.get("charset") + if encoding: + with contextlib.suppress(LookupError): + return codecs.lookup(encoding).name + + if mimetype.type == "application" and ( + mimetype.subtype == "json" or mimetype.subtype == "rdap" + ): + # RFC 7159 states that the default encoding is UTF-8. + # RFC 7483 defines application/rdap+json + return "utf-8" + + if self._body is None: + raise RuntimeError( + "Cannot compute fallback encoding of a not yet read body" + ) + + return self._resolve_charset(self, self._body) + + async def text(self, encoding: Optional[str] = None, errors: str = "strict") -> str: + """Read response payload and decode.""" + if self._body is None: + await self.read() + + if encoding is None: + encoding = self.get_encoding() + + return self._body.decode( # type: ignore[no-any-return,union-attr] + encoding, errors=errors + ) + + async def json( + self, + *, + encoding: Optional[str] = None, + loads: JSONDecoder = DEFAULT_JSON_DECODER, + content_type: Optional[str] = "application/json", + ) -> Any: + """Read and decodes JSON response.""" + if self._body is None: + await self.read() + + if content_type: + ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower() + if not _is_expected_content_type(ctype, content_type): + raise ContentTypeError( + self.request_info, + self.history, + message=( + "Attempt to decode JSON with " "unexpected mimetype: %s" % ctype + ), + headers=self.headers, + ) + + stripped = self._body.strip() # type: ignore[union-attr] + if not stripped: + return None + + if encoding is None: + encoding = self.get_encoding() + + return loads(stripped.decode(encoding)) + + async def __aenter__(self) -> "ClientResponse": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + # similar to _RequestContextManager, we do not need to check + # for exceptions, response object can close connection + # if state is broken + self.release() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/client_ws.py b/.venv/lib/python3.7/site-packages/aiohttp/client_ws.py new file mode 100644 index 0000000..9a8ba84 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/client_ws.py @@ -0,0 +1,300 @@ +"""WebSocket client for asyncio.""" + +import asyncio +from typing import Any, Optional, cast + +import async_timeout + +from .client_exceptions import ClientError +from .client_reqrep import ClientResponse +from .helpers import call_later, set_result +from .http import ( + WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE, + WebSocketError, + WSCloseCode, + WSMessage, + WSMsgType, +) +from .http_websocket import WebSocketWriter # WSMessage +from .streams import EofStream, FlowControlDataQueue +from .typedefs import ( + DEFAULT_JSON_DECODER, + DEFAULT_JSON_ENCODER, + JSONDecoder, + JSONEncoder, +) + + +class ClientWebSocketResponse: + def __init__( + self, + reader: "FlowControlDataQueue[WSMessage]", + writer: WebSocketWriter, + protocol: Optional[str], + response: ClientResponse, + timeout: float, + autoclose: bool, + autoping: bool, + loop: asyncio.AbstractEventLoop, + *, + receive_timeout: Optional[float] = None, + heartbeat: Optional[float] = None, + compress: int = 0, + client_notakeover: bool = False, + ) -> None: + self._response = response + self._conn = response.connection + + self._writer = writer + self._reader = reader + self._protocol = protocol + self._closed = False + self._closing = False + self._close_code: Optional[int] = None + self._timeout = timeout + self._receive_timeout = receive_timeout + self._autoclose = autoclose + self._autoping = autoping + self._heartbeat = heartbeat + self._heartbeat_cb: Optional[asyncio.TimerHandle] = None + if heartbeat is not None: + self._pong_heartbeat = heartbeat / 2.0 + self._pong_response_cb: Optional[asyncio.TimerHandle] = None + self._loop = loop + self._waiting: Optional[asyncio.Future[bool]] = None + self._exception: Optional[BaseException] = None + self._compress = compress + self._client_notakeover = client_notakeover + + self._reset_heartbeat() + + def _cancel_heartbeat(self) -> None: + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = None + + if self._heartbeat_cb is not None: + self._heartbeat_cb.cancel() + self._heartbeat_cb = None + + def _reset_heartbeat(self) -> None: + self._cancel_heartbeat() + + if self._heartbeat is not None: + self._heartbeat_cb = call_later( + self._send_heartbeat, self._heartbeat, self._loop + ) + + def _send_heartbeat(self) -> None: + if self._heartbeat is not None and not self._closed: + # fire-and-forget a task is not perfect but maybe ok for + # sending ping. Otherwise we need a long-living heartbeat + # task in the class. + self._loop.create_task(self._writer.ping()) + + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = call_later( + self._pong_not_received, self._pong_heartbeat, self._loop + ) + + def _pong_not_received(self) -> None: + if not self._closed: + self._closed = True + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = asyncio.TimeoutError() + self._response.close() + + @property + def closed(self) -> bool: + return self._closed + + @property + def close_code(self) -> Optional[int]: + return self._close_code + + @property + def protocol(self) -> Optional[str]: + return self._protocol + + @property + def compress(self) -> int: + return self._compress + + @property + def client_notakeover(self) -> bool: + return self._client_notakeover + + def get_extra_info(self, name: str, default: Any = None) -> Any: + """extra info from connection transport""" + conn = self._response.connection + if conn is None: + return default + transport = conn.transport + if transport is None: + return default + return transport.get_extra_info(name, default) + + def exception(self) -> Optional[BaseException]: + return self._exception + + async def ping(self, message: bytes = b"") -> None: + await self._writer.ping(message) + + async def pong(self, message: bytes = b"") -> None: + await self._writer.pong(message) + + async def send_str(self, data: str, compress: Optional[int] = None) -> None: + if not isinstance(data, str): + raise TypeError("data argument must be str (%r)" % type(data)) + await self._writer.send(data, binary=False, compress=compress) + + async def send_bytes(self, data: bytes, compress: Optional[int] = None) -> None: + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data argument must be byte-ish (%r)" % type(data)) + await self._writer.send(data, binary=True, compress=compress) + + async def send_json( + self, + data: Any, + compress: Optional[int] = None, + *, + dumps: JSONEncoder = DEFAULT_JSON_ENCODER, + ) -> None: + await self.send_str(dumps(data), compress=compress) + + async def close(self, *, code: int = WSCloseCode.OK, message: bytes = b"") -> bool: + # we need to break `receive()` cycle first, + # `close()` may be called from different task + if self._waiting is not None and not self._closed: + self._reader.feed_data(WS_CLOSING_MESSAGE, 0) + await self._waiting + + if not self._closed: + self._cancel_heartbeat() + self._closed = True + try: + await self._writer.close(code, message) + except asyncio.CancelledError: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._response.close() + raise + except Exception as exc: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = exc + self._response.close() + return True + + if self._closing: + self._response.close() + return True + + while True: + try: + async with async_timeout.timeout(self._timeout): + msg = await self._reader.read() + except asyncio.CancelledError: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._response.close() + raise + except Exception as exc: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = exc + self._response.close() + return True + + if msg.type == WSMsgType.CLOSE: + self._close_code = msg.data + self._response.close() + return True + else: + return False + + async def receive(self, timeout: Optional[float] = None) -> WSMessage: + while True: + if self._waiting is not None: + raise RuntimeError("Concurrent call to receive() is not allowed") + + if self._closed: + return WS_CLOSED_MESSAGE + elif self._closing: + await self.close() + return WS_CLOSED_MESSAGE + + try: + self._waiting = self._loop.create_future() + try: + async with async_timeout.timeout(timeout or self._receive_timeout): + msg = await self._reader.read() + self._reset_heartbeat() + finally: + waiter = self._waiting + self._waiting = None + set_result(waiter, True) + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + raise + except EofStream: + self._close_code = WSCloseCode.OK + await self.close() + return WSMessage(WSMsgType.CLOSED, None, None) + except ClientError: + self._closed = True + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + return WS_CLOSED_MESSAGE + except WebSocketError as exc: + self._close_code = exc.code + await self.close(code=exc.code) + return WSMessage(WSMsgType.ERROR, exc, None) + except Exception as exc: + self._exception = exc + self._closing = True + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + await self.close() + return WSMessage(WSMsgType.ERROR, exc, None) + + if msg.type == WSMsgType.CLOSE: + self._closing = True + self._close_code = msg.data + if not self._closed and self._autoclose: + await self.close() + elif msg.type == WSMsgType.CLOSING: + self._closing = True + elif msg.type == WSMsgType.PING and self._autoping: + await self.pong(msg.data) + continue + elif msg.type == WSMsgType.PONG and self._autoping: + continue + + return msg + + async def receive_str(self, *, timeout: Optional[float] = None) -> str: + msg = await self.receive(timeout) + if msg.type != WSMsgType.TEXT: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not str") + return cast(str, msg.data) + + async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: + msg = await self.receive(timeout) + if msg.type != WSMsgType.BINARY: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") + return cast(bytes, msg.data) + + async def receive_json( + self, + *, + loads: JSONDecoder = DEFAULT_JSON_DECODER, + timeout: Optional[float] = None, + ) -> Any: + data = await self.receive_str(timeout=timeout) + return loads(data) + + def __aiter__(self) -> "ClientWebSocketResponse": + return self + + async def __anext__(self) -> WSMessage: + msg = await self.receive() + if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): + raise StopAsyncIteration + return msg diff --git a/.venv/lib/python3.7/site-packages/aiohttp/connector.py b/.venv/lib/python3.7/site-packages/aiohttp/connector.py new file mode 100644 index 0000000..2499a2d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/connector.py @@ -0,0 +1,1456 @@ +import asyncio +import functools +import random +import sys +import traceback +import warnings +from collections import defaultdict, deque +from contextlib import suppress +from http.cookies import SimpleCookie +from itertools import cycle, islice +from time import monotonic +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + DefaultDict, + Dict, + Iterator, + List, + Optional, + Set, + Tuple, + Type, + Union, + cast, +) + +import attr + +from . import hdrs, helpers +from .abc import AbstractResolver +from .client_exceptions import ( + ClientConnectionError, + ClientConnectorCertificateError, + ClientConnectorError, + ClientConnectorSSLError, + ClientHttpProxyError, + ClientProxyConnectionError, + ServerFingerprintMismatch, + UnixClientConnectorError, + cert_errors, + ssl_errors, +) +from .client_proto import ResponseHandler +from .client_reqrep import ClientRequest, Fingerprint, _merge_ssl_params +from .helpers import ( + PY_36, + ceil_timeout, + get_running_loop, + is_ip_address, + noop, + sentinel, +) +from .http import RESPONSES +from .locks import EventResultOrError +from .resolver import DefaultResolver + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] + + +__all__ = ("BaseConnector", "TCPConnector", "UnixConnector", "NamedPipeConnector") + + +if TYPE_CHECKING: # pragma: no cover + from .client import ClientTimeout + from .client_reqrep import ConnectionKey + from .tracing import Trace + + +class _DeprecationWaiter: + __slots__ = ("_awaitable", "_awaited") + + def __init__(self, awaitable: Awaitable[Any]) -> None: + self._awaitable = awaitable + self._awaited = False + + def __await__(self) -> Any: + self._awaited = True + return self._awaitable.__await__() + + def __del__(self) -> None: + if not self._awaited: + warnings.warn( + "Connector.close() is a coroutine, " + "please use await connector.close()", + DeprecationWarning, + ) + + +class Connection: + + _source_traceback = None + _transport = None + + def __init__( + self, + connector: "BaseConnector", + key: "ConnectionKey", + protocol: ResponseHandler, + loop: asyncio.AbstractEventLoop, + ) -> None: + self._key = key + self._connector = connector + self._loop = loop + self._protocol: Optional[ResponseHandler] = protocol + self._callbacks: List[Callable[[], None]] = [] + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + def __repr__(self) -> str: + return f"Connection<{self._key}>" + + def __del__(self, _warnings: Any = warnings) -> None: + if self._protocol is not None: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed connection {self!r}", ResourceWarning, **kwargs) + if self._loop.is_closed(): + return + + self._connector._release(self._key, self._protocol, should_close=True) + + context = {"client_connection": self, "message": "Unclosed connection"} + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + @property + def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn( + "connector.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + @property + def transport(self) -> Optional[asyncio.Transport]: + if self._protocol is None: + return None + return self._protocol.transport + + @property + def protocol(self) -> Optional[ResponseHandler]: + return self._protocol + + def add_callback(self, callback: Callable[[], None]) -> None: + if callback is not None: + self._callbacks.append(callback) + + def _notify_release(self) -> None: + callbacks, self._callbacks = self._callbacks[:], [] + + for cb in callbacks: + with suppress(Exception): + cb() + + def close(self) -> None: + self._notify_release() + + if self._protocol is not None: + self._connector._release(self._key, self._protocol, should_close=True) + self._protocol = None + + def release(self) -> None: + self._notify_release() + + if self._protocol is not None: + self._connector._release( + self._key, self._protocol, should_close=self._protocol.should_close + ) + self._protocol = None + + @property + def closed(self) -> bool: + return self._protocol is None or not self._protocol.is_connected() + + +class _TransportPlaceholder: + """placeholder for BaseConnector.connect function""" + + def close(self) -> None: + pass + + +class BaseConnector: + """Base connector class. + + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + enable_cleanup_closed - Enables clean-up closed ssl transports. + Disabled by default. + loop - Optional event loop. + """ + + _closed = True # prevent AttributeError in __del__ if ctor was failed + _source_traceback = None + + # abort transport after 2 seconds (cleanup broken connections) + _cleanup_closed_period = 2.0 + + def __init__( + self, + *, + keepalive_timeout: Union[object, None, float] = sentinel, + force_close: bool = False, + limit: int = 100, + limit_per_host: int = 0, + enable_cleanup_closed: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + + if force_close: + if keepalive_timeout is not None and keepalive_timeout is not sentinel: + raise ValueError( + "keepalive_timeout cannot " "be set if force_close is True" + ) + else: + if keepalive_timeout is sentinel: + keepalive_timeout = 15.0 + + loop = get_running_loop(loop) + + self._closed = False + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + self._conns: Dict[ConnectionKey, List[Tuple[ResponseHandler, float]]] = {} + self._limit = limit + self._limit_per_host = limit_per_host + self._acquired: Set[ResponseHandler] = set() + self._acquired_per_host: DefaultDict[ + ConnectionKey, Set[ResponseHandler] + ] = defaultdict(set) + self._keepalive_timeout = cast(float, keepalive_timeout) + self._force_close = force_close + + # {host_key: FIFO list of waiters} + self._waiters = defaultdict(deque) # type: ignore[var-annotated] + + self._loop = loop + self._factory = functools.partial(ResponseHandler, loop=loop) + + self.cookies: SimpleCookie[str] = SimpleCookie() + + # start keep-alive connection cleanup task + self._cleanup_handle: Optional[asyncio.TimerHandle] = None + + # start cleanup closed transports task + self._cleanup_closed_handle: Optional[asyncio.TimerHandle] = None + self._cleanup_closed_disabled = not enable_cleanup_closed + self._cleanup_closed_transports: List[Optional[asyncio.Transport]] = [] + self._cleanup_closed() + + def __del__(self, _warnings: Any = warnings) -> None: + if self._closed: + return + if not self._conns: + return + + conns = [repr(c) for c in self._conns.values()] + + self._close() + + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed connector {self!r}", ResourceWarning, **kwargs) + context = { + "connector": self, + "connections": conns, + "message": "Unclosed connector", + } + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def __enter__(self) -> "BaseConnector": + warnings.warn( + '"with Connector():" is deprecated, ' + 'use "async with Connector():" instead', + DeprecationWarning, + ) + return self + + def __exit__(self, *exc: Any) -> None: + self._close() + + async def __aenter__(self) -> "BaseConnector": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]] = None, + exc_value: Optional[BaseException] = None, + exc_traceback: Optional[TracebackType] = None, + ) -> None: + await self.close() + + @property + def force_close(self) -> bool: + """Ultimately close connection on releasing if True.""" + return self._force_close + + @property + def limit(self) -> int: + """The total number for simultaneous connections. + + If limit is 0 the connector has no limit. + The default limit size is 100. + """ + return self._limit + + @property + def limit_per_host(self) -> int: + """The limit for simultaneous connections to the same endpoint. + + Endpoints are the same if they are have equal + (host, port, is_ssl) triple. + """ + return self._limit_per_host + + def _cleanup(self) -> None: + """Cleanup unused transports.""" + if self._cleanup_handle: + self._cleanup_handle.cancel() + # _cleanup_handle should be unset, otherwise _release() will not + # recreate it ever! + self._cleanup_handle = None + + now = self._loop.time() + timeout = self._keepalive_timeout + + if self._conns: + connections = {} + deadline = now - timeout + for key, conns in self._conns.items(): + alive = [] + for proto, use_time in conns: + if proto.is_connected(): + if use_time - deadline < 0: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + alive.append((proto, use_time)) + else: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + + if alive: + connections[key] = alive + + self._conns = connections + + if self._conns: + self._cleanup_handle = helpers.weakref_handle( + self, "_cleanup", timeout, self._loop + ) + + def _drop_acquired_per_host( + self, key: "ConnectionKey", val: ResponseHandler + ) -> None: + acquired_per_host = self._acquired_per_host + if key not in acquired_per_host: + return + conns = acquired_per_host[key] + conns.remove(val) + if not conns: + del self._acquired_per_host[key] + + def _cleanup_closed(self) -> None: + """Double confirmation for transport close. + + Some broken ssl servers may leave socket open without proper close. + """ + if self._cleanup_closed_handle: + self._cleanup_closed_handle.cancel() + + for transport in self._cleanup_closed_transports: + if transport is not None: + transport.abort() + + self._cleanup_closed_transports = [] + + if not self._cleanup_closed_disabled: + self._cleanup_closed_handle = helpers.weakref_handle( + self, "_cleanup_closed", self._cleanup_closed_period, self._loop + ) + + def close(self) -> Awaitable[None]: + """Close all opened transports.""" + self._close() + return _DeprecationWaiter(noop()) + + def _close(self) -> None: + if self._closed: + return + + self._closed = True + + try: + if self._loop.is_closed(): + return + + # cancel cleanup task + if self._cleanup_handle: + self._cleanup_handle.cancel() + + # cancel cleanup close task + if self._cleanup_closed_handle: + self._cleanup_closed_handle.cancel() + + for data in self._conns.values(): + for proto, t0 in data: + proto.close() + + for proto in self._acquired: + proto.close() + + for transport in self._cleanup_closed_transports: + if transport is not None: + transport.abort() + + finally: + self._conns.clear() + self._acquired.clear() + self._waiters.clear() + self._cleanup_handle = None + self._cleanup_closed_transports.clear() + self._cleanup_closed_handle = None + + @property + def closed(self) -> bool: + """Is connector closed. + + A readonly property. + """ + return self._closed + + def _available_connections(self, key: "ConnectionKey") -> int: + """ + Return number of available connections. + + The limit, limit_per_host and the connection key are taken into account. + + If it returns less than 1 means that there are no connections + available. + """ + if self._limit: + # total calc available connections + available = self._limit - len(self._acquired) + + # check limit per host + if ( + self._limit_per_host + and available > 0 + and key in self._acquired_per_host + ): + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) + + elif self._limit_per_host and key in self._acquired_per_host: + # check limit per host + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) + else: + available = 1 + + return available + + async def connect( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> Connection: + """Get from pool or create new connection.""" + key = req.connection_key + available = self._available_connections(key) + + # Wait if there are no available connections or if there are/were + # waiters (i.e. don't steal connection from a waiter about to wake up) + if available <= 0 or key in self._waiters: + fut = self._loop.create_future() + + # This connection will now count towards the limit. + self._waiters[key].append(fut) + + if traces: + for trace in traces: + await trace.send_connection_queued_start() + + try: + await fut + except BaseException as e: + if key in self._waiters: + # remove a waiter even if it was cancelled, normally it's + # removed when it's notified + try: + self._waiters[key].remove(fut) + except ValueError: # fut may no longer be in list + pass + + raise e + finally: + if key in self._waiters and not self._waiters[key]: + del self._waiters[key] + + if traces: + for trace in traces: + await trace.send_connection_queued_end() + + proto = self._get(key) + if proto is None: + placeholder = cast(ResponseHandler, _TransportPlaceholder()) + self._acquired.add(placeholder) + self._acquired_per_host[key].add(placeholder) + + if traces: + for trace in traces: + await trace.send_connection_create_start() + + try: + proto = await self._create_connection(req, traces, timeout) + if self._closed: + proto.close() + raise ClientConnectionError("Connector is closed.") + except BaseException: + if not self._closed: + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) + self._release_waiter() + raise + else: + if not self._closed: + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) + + if traces: + for trace in traces: + await trace.send_connection_create_end() + else: + if traces: + # Acquire the connection to prevent race conditions with limits + placeholder = cast(ResponseHandler, _TransportPlaceholder()) + self._acquired.add(placeholder) + self._acquired_per_host[key].add(placeholder) + for trace in traces: + await trace.send_connection_reuseconn() + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) + + self._acquired.add(proto) + self._acquired_per_host[key].add(proto) + return Connection(self, key, proto, self._loop) + + def _get(self, key: "ConnectionKey") -> Optional[ResponseHandler]: + try: + conns = self._conns[key] + except KeyError: + return None + + t1 = self._loop.time() + while conns: + proto, t0 = conns.pop() + if proto.is_connected(): + if t1 - t0 > self._keepalive_timeout: + transport = proto.transport + proto.close() + # only for SSL transports + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + if not conns: + # The very last connection was reclaimed: drop the key + del self._conns[key] + return proto + else: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + + # No more connections: drop the key + del self._conns[key] + return None + + def _release_waiter(self) -> None: + """ + Iterates over all waiters until one to be released is found. + + The one to be released is not finsihed and + belongs to a host that has available connections. + """ + if not self._waiters: + return + + # Having the dict keys ordered this avoids to iterate + # at the same order at each call. + queues = list(self._waiters.keys()) + random.shuffle(queues) + + for key in queues: + if self._available_connections(key) < 1: + continue + + waiters = self._waiters[key] + while waiters: + waiter = waiters.popleft() + if not waiter.done(): + waiter.set_result(None) + return + + def _release_acquired(self, key: "ConnectionKey", proto: ResponseHandler) -> None: + if self._closed: + # acquired connection is already released on connector closing + return + + try: + self._acquired.remove(proto) + self._drop_acquired_per_host(key, proto) + except KeyError: # pragma: no cover + # this may be result of undetermenistic order of objects + # finalization due garbage collection. + pass + else: + self._release_waiter() + + def _release( + self, + key: "ConnectionKey", + protocol: ResponseHandler, + *, + should_close: bool = False, + ) -> None: + if self._closed: + # acquired connection is already released on connector closing + return + + self._release_acquired(key, protocol) + + if self._force_close: + should_close = True + + if should_close or protocol.should_close: + transport = protocol.transport + protocol.close() + + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + conns = self._conns.get(key) + if conns is None: + conns = self._conns[key] = [] + conns.append((protocol, self._loop.time())) + + if self._cleanup_handle is None: + self._cleanup_handle = helpers.weakref_handle( + self, "_cleanup", self._keepalive_timeout, self._loop + ) + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + raise NotImplementedError() + + +class _DNSCacheTable: + def __init__(self, ttl: Optional[float] = None) -> None: + self._addrs_rr: Dict[Tuple[str, int], Tuple[Iterator[Dict[str, Any]], int]] = {} + self._timestamps: Dict[Tuple[str, int], float] = {} + self._ttl = ttl + + def __contains__(self, host: object) -> bool: + return host in self._addrs_rr + + def add(self, key: Tuple[str, int], addrs: List[Dict[str, Any]]) -> None: + self._addrs_rr[key] = (cycle(addrs), len(addrs)) + + if self._ttl: + self._timestamps[key] = monotonic() + + def remove(self, key: Tuple[str, int]) -> None: + self._addrs_rr.pop(key, None) + + if self._ttl: + self._timestamps.pop(key, None) + + def clear(self) -> None: + self._addrs_rr.clear() + self._timestamps.clear() + + def next_addrs(self, key: Tuple[str, int]) -> List[Dict[str, Any]]: + loop, length = self._addrs_rr[key] + addrs = list(islice(loop, length)) + # Consume one more element to shift internal state of `cycle` + next(loop) + return addrs + + def expired(self, key: Tuple[str, int]) -> bool: + if self._ttl is None: + return False + + return self._timestamps[key] + self._ttl < monotonic() + + +class TCPConnector(BaseConnector): + """TCP connector. + + verify_ssl - Set to True to check ssl certifications. + fingerprint - Pass the binary sha256 + digest of the expected certificate in DER format to verify + that the certificate the server presents matches. See also + https://en.wikipedia.org/wiki/Transport_Layer_Security#Certificate_pinning + resolver - Enable DNS lookups and use this + resolver + use_dns_cache - Use memory cache for DNS lookups. + ttl_dns_cache - Max seconds having cached a DNS entry, None forever. + family - socket address family + local_addr - local tuple of (host, port) to bind socket to + + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + enable_cleanup_closed - Enables clean-up closed ssl transports. + Disabled by default. + loop - Optional event loop. + """ + + def __init__( + self, + *, + verify_ssl: bool = True, + fingerprint: Optional[bytes] = None, + use_dns_cache: bool = True, + ttl_dns_cache: Optional[int] = 10, + family: int = 0, + ssl_context: Optional[SSLContext] = None, + ssl: Union[None, bool, Fingerprint, SSLContext] = None, + local_addr: Optional[Tuple[str, int]] = None, + resolver: Optional[AbstractResolver] = None, + keepalive_timeout: Union[None, float, object] = sentinel, + force_close: bool = False, + limit: int = 100, + limit_per_host: int = 0, + enable_cleanup_closed: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + ): + super().__init__( + keepalive_timeout=keepalive_timeout, + force_close=force_close, + limit=limit, + limit_per_host=limit_per_host, + enable_cleanup_closed=enable_cleanup_closed, + loop=loop, + ) + + self._ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + if resolver is None: + resolver = DefaultResolver(loop=self._loop) + self._resolver = resolver + + self._use_dns_cache = use_dns_cache + self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache) + self._throttle_dns_events: Dict[Tuple[str, int], EventResultOrError] = {} + self._family = family + self._local_addr = local_addr + + def close(self) -> Awaitable[None]: + """Close all ongoing DNS calls.""" + for ev in self._throttle_dns_events.values(): + ev.cancel() + + return super().close() + + @property + def family(self) -> int: + """Socket family like AF_INET.""" + return self._family + + @property + def use_dns_cache(self) -> bool: + """True if local DNS caching is enabled.""" + return self._use_dns_cache + + def clear_dns_cache( + self, host: Optional[str] = None, port: Optional[int] = None + ) -> None: + """Remove specified host/port or clear all dns local cache.""" + if host is not None and port is not None: + self._cached_hosts.remove((host, port)) + elif host is not None or port is not None: + raise ValueError("either both host and port " "or none of them are allowed") + else: + self._cached_hosts.clear() + + async def _resolve_host( + self, host: str, port: int, traces: Optional[List["Trace"]] = None + ) -> List[Dict[str, Any]]: + if is_ip_address(host): + return [ + { + "hostname": host, + "host": host, + "port": port, + "family": self._family, + "proto": 0, + "flags": 0, + } + ] + + if not self._use_dns_cache: + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_start(host) + + res = await self._resolver.resolve(host, port, family=self._family) + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_end(host) + + return res + + key = (host, port) + + if (key in self._cached_hosts) and (not self._cached_hosts.expired(key)): + # get result early, before any await (#4014) + result = self._cached_hosts.next_addrs(key) + + if traces: + for trace in traces: + await trace.send_dns_cache_hit(host) + return result + + if key in self._throttle_dns_events: + # get event early, before any await (#4014) + event = self._throttle_dns_events[key] + if traces: + for trace in traces: + await trace.send_dns_cache_hit(host) + await event.wait() + else: + # update dict early, before any await (#4014) + self._throttle_dns_events[key] = EventResultOrError(self._loop) + if traces: + for trace in traces: + await trace.send_dns_cache_miss(host) + try: + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_start(host) + + addrs = await self._resolver.resolve(host, port, family=self._family) + if traces: + for trace in traces: + await trace.send_dns_resolvehost_end(host) + + self._cached_hosts.add(key, addrs) + self._throttle_dns_events[key].set() + except BaseException as e: + # any DNS exception, independently of the implementation + # is set for the waiters to raise the same exception. + self._throttle_dns_events[key].set(exc=e) + raise + finally: + self._throttle_dns_events.pop(key) + + return self._cached_hosts.next_addrs(key) + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + """Create connection. + + Has same keyword arguments as BaseEventLoop.create_connection. + """ + if req.proxy: + _, proto = await self._create_proxy_connection(req, traces, timeout) + else: + _, proto = await self._create_direct_connection(req, traces, timeout) + + return proto + + @staticmethod + @functools.lru_cache(None) + def _make_ssl_context(verified: bool) -> SSLContext: + if verified: + return ssl.create_default_context() + else: + sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.options |= ssl.OP_NO_SSLv3 + sslcontext.check_hostname = False + sslcontext.verify_mode = ssl.CERT_NONE + try: + sslcontext.options |= ssl.OP_NO_COMPRESSION + except AttributeError as attr_err: + warnings.warn( + "{!s}: The Python interpreter is compiled " + "against OpenSSL < 1.0.0. Ref: " + "https://docs.python.org/3/library/ssl.html" + "#ssl.OP_NO_COMPRESSION".format(attr_err), + ) + sslcontext.set_default_verify_paths() + return sslcontext + + def _get_ssl_context(self, req: "ClientRequest") -> Optional[SSLContext]: + """Logic to get the correct SSL context + + 0. if req.ssl is false, return None + + 1. if ssl_context is specified in req, use it + 2. if _ssl_context is specified in self, use it + 3. otherwise: + 1. if verify_ssl is not specified in req, use self.ssl_context + (will generate a default context according to self.verify_ssl) + 2. if verify_ssl is True in req, generate a default SSL context + 3. if verify_ssl is False in req, generate a SSL context that + won't verify + """ + if req.is_ssl(): + if ssl is None: # pragma: no cover + raise RuntimeError("SSL is not supported.") + sslcontext = req.ssl + if isinstance(sslcontext, ssl.SSLContext): + return sslcontext + if sslcontext is not None: + # not verified or fingerprinted + return self._make_ssl_context(False) + sslcontext = self._ssl + if isinstance(sslcontext, ssl.SSLContext): + return sslcontext + if sslcontext is not None: + # not verified or fingerprinted + return self._make_ssl_context(False) + return self._make_ssl_context(True) + else: + return None + + def _get_fingerprint(self, req: "ClientRequest") -> Optional["Fingerprint"]: + ret = req.ssl + if isinstance(ret, Fingerprint): + return ret + ret = self._ssl + if isinstance(ret, Fingerprint): + return ret + return None + + async def _wrap_create_connection( + self, + *args: Any, + req: "ClientRequest", + timeout: "ClientTimeout", + client_error: Type[Exception] = ClientConnectorError, + **kwargs: Any, + ) -> Tuple[asyncio.Transport, ResponseHandler]: + try: + async with ceil_timeout(timeout.sock_connect): + return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa + except cert_errors as exc: + raise ClientConnectorCertificateError(req.connection_key, exc) from exc + except ssl_errors as exc: + raise ClientConnectorSSLError(req.connection_key, exc) from exc + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise client_error(req.connection_key, exc) from exc + + def _fail_on_no_start_tls(self, req: "ClientRequest") -> None: + """Raise a :py:exc:`RuntimeError` on missing ``start_tls()``. + + One case is that :py:meth:`asyncio.loop.start_tls` is not yet + implemented under Python 3.6. It is necessary for TLS-in-TLS so + that it is possible to send HTTPS queries through HTTPS proxies. + + This doesn't affect regular HTTP requests, though. + """ + if not req.is_ssl(): + return + + proxy_url = req.proxy + assert proxy_url is not None + if proxy_url.scheme != "https": + return + + self._check_loop_for_start_tls() + + def _check_loop_for_start_tls(self) -> None: + try: + self._loop.start_tls + except AttributeError as attr_exc: + raise RuntimeError( + "An HTTPS request is being sent through an HTTPS proxy. " + "This needs support for TLS in TLS but it is not implemented " + "in your runtime for the stdlib asyncio.\n\n" + "Please upgrade to Python 3.7 or higher. For more details, " + "please see:\n" + "* https://bugs.python.org/issue37179\n" + "* https://github.com/python/cpython/pull/28073\n" + "* https://docs.aiohttp.org/en/stable/" + "client_advanced.html#proxy-support\n" + "* https://github.com/aio-libs/aiohttp/discussions/6044\n", + ) from attr_exc + + def _loop_supports_start_tls(self) -> bool: + try: + self._check_loop_for_start_tls() + except RuntimeError: + return False + else: + return True + + def _warn_about_tls_in_tls( + self, + underlying_transport: asyncio.Transport, + req: "ClientRequest", + ) -> None: + """Issue a warning if the requested URL has HTTPS scheme.""" + if req.request_info.url.scheme != "https": + return + + asyncio_supports_tls_in_tls = getattr( + underlying_transport, + "_start_tls_compatible", + False, + ) + + if asyncio_supports_tls_in_tls: + return + + warnings.warn( + "An HTTPS request is being sent through an HTTPS proxy. " + "This support for TLS in TLS is known to be disabled " + "in the stdlib asyncio. This is why you'll probably see " + "an error in the log below.\n\n" + "It is possible to enable it via monkeypatching under " + "Python 3.7 or higher. For more details, see:\n" + "* https://bugs.python.org/issue37179\n" + "* https://github.com/python/cpython/pull/28073\n\n" + "You can temporarily patch this as follows:\n" + "* https://docs.aiohttp.org/en/stable/client_advanced.html#proxy-support\n" + "* https://github.com/aio-libs/aiohttp/discussions/6044\n", + RuntimeWarning, + source=self, + # Why `4`? At least 3 of the calls in the stack originate + # from the methods in this class. + stacklevel=3, + ) + + async def _start_tls_connection( + self, + underlying_transport: asyncio.Transport, + req: "ClientRequest", + timeout: "ClientTimeout", + client_error: Type[Exception] = ClientConnectorError, + ) -> Tuple[asyncio.BaseTransport, ResponseHandler]: + """Wrap the raw TCP transport with TLS.""" + tls_proto = self._factory() # Create a brand new proto for TLS + + # Safety of the `cast()` call here is based on the fact that + # internally `_get_ssl_context()` only returns `None` when + # `req.is_ssl()` evaluates to `False` which is never gonna happen + # in this code path. Of course, it's rather fragile + # maintainability-wise but this is to be solved separately. + sslcontext = cast(ssl.SSLContext, self._get_ssl_context(req)) + + try: + async with ceil_timeout(timeout.sock_connect): + try: + tls_transport = await self._loop.start_tls( + underlying_transport, + tls_proto, + sslcontext, + server_hostname=req.host, + ssl_handshake_timeout=timeout.total, + ) + except BaseException: + # We need to close the underlying transport since + # `start_tls()` probably failed before it had a + # chance to do this: + underlying_transport.close() + raise + except cert_errors as exc: + raise ClientConnectorCertificateError(req.connection_key, exc) from exc + except ssl_errors as exc: + raise ClientConnectorSSLError(req.connection_key, exc) from exc + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise client_error(req.connection_key, exc) from exc + except TypeError as type_err: + # Example cause looks like this: + # TypeError: transport is not supported by start_tls() + + raise ClientConnectionError( + "Cannot initialize a TLS-in-TLS connection to host " + f"{req.host!s}:{req.port:d} through an underlying connection " + f"to an HTTPS proxy {req.proxy!s} ssl:{req.ssl or 'default'} " + f"[{type_err!s}]" + ) from type_err + else: + if tls_transport is None: + msg = "Failed to start TLS (possibly caused by closing transport)" + raise client_error(req.connection_key, OSError(msg)) + tls_proto.connection_made( + tls_transport + ) # Kick the state machine of the new TLS protocol + + return tls_transport, tls_proto + + async def _create_direct_connection( + self, + req: "ClientRequest", + traces: List["Trace"], + timeout: "ClientTimeout", + *, + client_error: Type[Exception] = ClientConnectorError, + ) -> Tuple[asyncio.Transport, ResponseHandler]: + sslcontext = self._get_ssl_context(req) + fingerprint = self._get_fingerprint(req) + + host = req.url.raw_host + assert host is not None + port = req.port + assert port is not None + host_resolved = asyncio.ensure_future( + self._resolve_host(host, port, traces=traces), loop=self._loop + ) + try: + # Cancelling this lookup should not cancel the underlying lookup + # or else the cancel event will get broadcast to all the waiters + # across all connections. + hosts = await asyncio.shield(host_resolved) + except asyncio.CancelledError: + + def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: + with suppress(Exception, asyncio.CancelledError): + fut.result() + + host_resolved.add_done_callback(drop_exception) + raise + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + # in case of proxy it is not ClientProxyConnectionError + # it is problem of resolving proxy ip itself + raise ClientConnectorError(req.connection_key, exc) from exc + + last_exc: Optional[Exception] = None + + for hinfo in hosts: + host = hinfo["host"] + port = hinfo["port"] + + try: + transp, proto = await self._wrap_create_connection( + self._factory, + host, + port, + timeout=timeout, + ssl=sslcontext, + family=hinfo["family"], + proto=hinfo["proto"], + flags=hinfo["flags"], + server_hostname=hinfo["hostname"] if sslcontext else None, + local_addr=self._local_addr, + req=req, + client_error=client_error, + ) + except ClientConnectorError as exc: + last_exc = exc + continue + + if req.is_ssl() and fingerprint: + try: + fingerprint.check(transp) + except ServerFingerprintMismatch as exc: + transp.close() + if not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transp) + last_exc = exc + continue + + return transp, proto + else: + assert last_exc is not None + raise last_exc + + async def _create_proxy_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> Tuple[asyncio.BaseTransport, ResponseHandler]: + self._fail_on_no_start_tls(req) + runtime_has_start_tls = self._loop_supports_start_tls() + + headers: Dict[str, str] = {} + if req.proxy_headers is not None: + headers = req.proxy_headers # type: ignore[assignment] + headers[hdrs.HOST] = req.headers[hdrs.HOST] + + url = req.proxy + assert url is not None + proxy_req = ClientRequest( + hdrs.METH_GET, + url, + headers=headers, + auth=req.proxy_auth, + loop=self._loop, + ssl=req.ssl, + ) + + # create connection to proxy server + transport, proto = await self._create_direct_connection( + proxy_req, [], timeout, client_error=ClientProxyConnectionError + ) + + # Many HTTP proxies has buggy keepalive support. Let's not + # reuse connection but close it after processing every + # response. + proto.force_close() + + auth = proxy_req.headers.pop(hdrs.AUTHORIZATION, None) + if auth is not None: + if not req.is_ssl(): + req.headers[hdrs.PROXY_AUTHORIZATION] = auth + else: + proxy_req.headers[hdrs.PROXY_AUTHORIZATION] = auth + + if req.is_ssl(): + if runtime_has_start_tls: + self._warn_about_tls_in_tls(transport, req) + + # For HTTPS requests over HTTP proxy + # we must notify proxy to tunnel connection + # so we send CONNECT command: + # CONNECT www.python.org:443 HTTP/1.1 + # Host: www.python.org + # + # next we must do TLS handshake and so on + # to do this we must wrap raw socket into secure one + # asyncio handles this perfectly + proxy_req.method = hdrs.METH_CONNECT + proxy_req.url = req.url + key = attr.evolve( + req.connection_key, proxy=None, proxy_auth=None, proxy_headers_hash=None + ) + conn = Connection(self, key, proto, self._loop) + proxy_resp = await proxy_req.send(conn) + try: + protocol = conn._protocol + assert protocol is not None + + # read_until_eof=True will ensure the connection isn't closed + # once the response is received and processed allowing + # START_TLS to work on the connection below. + protocol.set_response_params(read_until_eof=runtime_has_start_tls) + resp = await proxy_resp.start(conn) + except BaseException: + proxy_resp.close() + conn.close() + raise + else: + conn._protocol = None + conn._transport = None + try: + if resp.status != 200: + message = resp.reason + if message is None: + message = RESPONSES[resp.status][0] + raise ClientHttpProxyError( + proxy_resp.request_info, + resp.history, + status=resp.status, + message=message, + headers=resp.headers, + ) + if not runtime_has_start_tls: + rawsock = transport.get_extra_info("socket", default=None) + if rawsock is None: + raise RuntimeError( + "Transport does not expose socket instance" + ) + # Duplicate the socket, so now we can close proxy transport + rawsock = rawsock.dup() + except BaseException: + # It shouldn't be closed in `finally` because it's fed to + # `loop.start_tls()` and the docs say not to touch it after + # passing there. + transport.close() + raise + finally: + if not runtime_has_start_tls: + transport.close() + + if not runtime_has_start_tls: + # HTTP proxy with support for upgrade to HTTPS + sslcontext = self._get_ssl_context(req) + return await self._wrap_create_connection( + self._factory, + timeout=timeout, + ssl=sslcontext, + sock=rawsock, + server_hostname=req.host, + req=req, + ) + + return await self._start_tls_connection( + # Access the old transport for the last time before it's + # closed and forgotten forever: + transport, + req=req, + timeout=timeout, + ) + finally: + proxy_resp.close() + + return transport, proto + + +class UnixConnector(BaseConnector): + """Unix socket connector. + + path - Unix socket path. + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + loop - Optional event loop. + """ + + def __init__( + self, + path: str, + force_close: bool = False, + keepalive_timeout: Union[object, float, None] = sentinel, + limit: int = 100, + limit_per_host: int = 0, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + super().__init__( + force_close=force_close, + keepalive_timeout=keepalive_timeout, + limit=limit, + limit_per_host=limit_per_host, + loop=loop, + ) + self._path = path + + @property + def path(self) -> str: + """Path to unix socket.""" + return self._path + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + try: + async with ceil_timeout(timeout.sock_connect): + _, proto = await self._loop.create_unix_connection( + self._factory, self._path + ) + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise UnixClientConnectorError(self.path, req.connection_key, exc) from exc + + return cast(ResponseHandler, proto) + + +class NamedPipeConnector(BaseConnector): + """Named pipe connector. + + Only supported by the proactor event loop. + See also: https://docs.python.org/3.7/library/asyncio-eventloop.html + + path - Windows named pipe path. + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + loop - Optional event loop. + """ + + def __init__( + self, + path: str, + force_close: bool = False, + keepalive_timeout: Union[object, float, None] = sentinel, + limit: int = 100, + limit_per_host: int = 0, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + super().__init__( + force_close=force_close, + keepalive_timeout=keepalive_timeout, + limit=limit, + limit_per_host=limit_per_host, + loop=loop, + ) + if not isinstance( + self._loop, asyncio.ProactorEventLoop # type: ignore[attr-defined] + ): + raise RuntimeError( + "Named Pipes only available in proactor " "loop under windows" + ) + self._path = path + + @property + def path(self) -> str: + """Path to the named pipe.""" + return self._path + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + try: + async with ceil_timeout(timeout.sock_connect): + _, proto = await self._loop.create_pipe_connection( # type: ignore[attr-defined] # noqa: E501 + self._factory, self._path + ) + # the drain is required so that the connection_made is called + # and transport is set otherwise it is not set before the + # `assert conn.transport is not None` + # in client.py's _request method + await asyncio.sleep(0) + # other option is to manually set transport like + # `proto.transport = trans` + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise ClientConnectorError(req.connection_key, exc) from exc + + return cast(ResponseHandler, proto) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/cookiejar.py b/.venv/lib/python3.7/site-packages/aiohttp/cookiejar.py new file mode 100644 index 0000000..e395b74 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/cookiejar.py @@ -0,0 +1,416 @@ +import asyncio +import contextlib +import datetime +import os # noqa +import pathlib +import pickle +import re +from collections import defaultdict +from http.cookies import BaseCookie, Morsel, SimpleCookie +from typing import ( # noqa + DefaultDict, + Dict, + Iterable, + Iterator, + List, + Mapping, + Optional, + Set, + Tuple, + Union, + cast, +) + +from yarl import URL + +from .abc import AbstractCookieJar, ClearCookiePredicate +from .helpers import is_ip_address, next_whole_second +from .typedefs import LooseCookies, PathLike, StrOrURL + +__all__ = ("CookieJar", "DummyCookieJar") + + +CookieItem = Union[str, "Morsel[str]"] + + +class CookieJar(AbstractCookieJar): + """Implements cookie storage adhering to RFC 6265.""" + + DATE_TOKENS_RE = re.compile( + r"[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]*" + r"(?P[\x00-\x08\x0A-\x1F\d:a-zA-Z\x7F-\xFF]+)" + ) + + DATE_HMS_TIME_RE = re.compile(r"(\d{1,2}):(\d{1,2}):(\d{1,2})") + + DATE_DAY_OF_MONTH_RE = re.compile(r"(\d{1,2})") + + DATE_MONTH_RE = re.compile( + "(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|" "(aug)|(sep)|(oct)|(nov)|(dec)", + re.I, + ) + + DATE_YEAR_RE = re.compile(r"(\d{2,4})") + + MAX_TIME = datetime.datetime.max.replace(tzinfo=datetime.timezone.utc) + + MAX_32BIT_TIME = datetime.datetime.utcfromtimestamp(2**31 - 1) + + def __init__( + self, + *, + unsafe: bool = False, + quote_cookie: bool = True, + treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + super().__init__(loop=loop) + self._cookies: DefaultDict[Tuple[str, str], SimpleCookie[str]] = defaultdict( + SimpleCookie + ) + self._host_only_cookies: Set[Tuple[str, str]] = set() + self._unsafe = unsafe + self._quote_cookie = quote_cookie + if treat_as_secure_origin is None: + treat_as_secure_origin = [] + elif isinstance(treat_as_secure_origin, URL): + treat_as_secure_origin = [treat_as_secure_origin.origin()] + elif isinstance(treat_as_secure_origin, str): + treat_as_secure_origin = [URL(treat_as_secure_origin).origin()] + else: + treat_as_secure_origin = [ + URL(url).origin() if isinstance(url, str) else url.origin() + for url in treat_as_secure_origin + ] + self._treat_as_secure_origin = treat_as_secure_origin + self._next_expiration = next_whole_second() + self._expirations: Dict[Tuple[str, str, str], datetime.datetime] = {} + # #4515: datetime.max may not be representable on 32-bit platforms + self._max_time = self.MAX_TIME + try: + self._max_time.timestamp() + except OverflowError: + self._max_time = self.MAX_32BIT_TIME + + def save(self, file_path: PathLike) -> None: + file_path = pathlib.Path(file_path) + with file_path.open(mode="wb") as f: + pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL) + + def load(self, file_path: PathLike) -> None: + file_path = pathlib.Path(file_path) + with file_path.open(mode="rb") as f: + self._cookies = pickle.load(f) + + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + if predicate is None: + self._next_expiration = next_whole_second() + self._cookies.clear() + self._host_only_cookies.clear() + self._expirations.clear() + return + + to_del = [] + now = datetime.datetime.now(datetime.timezone.utc) + for (domain, path), cookie in self._cookies.items(): + for name, morsel in cookie.items(): + key = (domain, path, name) + if ( + key in self._expirations and self._expirations[key] <= now + ) or predicate(morsel): + to_del.append(key) + + for domain, path, name in to_del: + self._host_only_cookies.discard((domain, name)) + key = (domain, path, name) + if key in self._expirations: + del self._expirations[(domain, path, name)] + self._cookies[(domain, path)].pop(name, None) + + next_expiration = min(self._expirations.values(), default=self._max_time) + try: + self._next_expiration = next_expiration.replace( + microsecond=0 + ) + datetime.timedelta(seconds=1) + except OverflowError: + self._next_expiration = self._max_time + + def clear_domain(self, domain: str) -> None: + self.clear(lambda x: self._is_domain_match(domain, x["domain"])) + + def __iter__(self) -> "Iterator[Morsel[str]]": + self._do_expiration() + for val in self._cookies.values(): + yield from val.values() + + def __len__(self) -> int: + return sum(1 for i in self) + + def _do_expiration(self) -> None: + self.clear(lambda x: False) + + def _expire_cookie( + self, when: datetime.datetime, domain: str, path: str, name: str + ) -> None: + self._next_expiration = min(self._next_expiration, when) + self._expirations[(domain, path, name)] = when + + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + """Update cookies.""" + hostname = response_url.raw_host + + if not self._unsafe and is_ip_address(hostname): + # Don't accept cookies from IPs + return + + if isinstance(cookies, Mapping): + cookies = cookies.items() + + for name, cookie in cookies: + if not isinstance(cookie, Morsel): + tmp: SimpleCookie[str] = SimpleCookie() + tmp[name] = cookie # type: ignore[assignment] + cookie = tmp[name] + + domain = cookie["domain"] + + # ignore domains with trailing dots + if domain.endswith("."): + domain = "" + del cookie["domain"] + + if not domain and hostname is not None: + # Set the cookie's domain to the response hostname + # and set its host-only-flag + self._host_only_cookies.add((hostname, name)) + domain = cookie["domain"] = hostname + + if domain.startswith("."): + # Remove leading dot + domain = domain[1:] + cookie["domain"] = domain + + if hostname and not self._is_domain_match(domain, hostname): + # Setting cookies for different domains is not allowed + continue + + path = cookie["path"] + if not path or not path.startswith("/"): + # Set the cookie's path to the response path + path = response_url.path + if not path.startswith("/"): + path = "/" + else: + # Cut everything from the last slash to the end + path = "/" + path[1 : path.rfind("/")] + cookie["path"] = path + + max_age = cookie["max-age"] + if max_age: + try: + delta_seconds = int(max_age) + try: + max_age_expiration = datetime.datetime.now( + datetime.timezone.utc + ) + datetime.timedelta(seconds=delta_seconds) + except OverflowError: + max_age_expiration = self._max_time + self._expire_cookie(max_age_expiration, domain, path, name) + except ValueError: + cookie["max-age"] = "" + + else: + expires = cookie["expires"] + if expires: + expire_time = self._parse_date(expires) + if expire_time: + self._expire_cookie(expire_time, domain, path, name) + else: + cookie["expires"] = "" + + self._cookies[(domain, path)][name] = cookie + + self._do_expiration() + + def filter_cookies( + self, request_url: URL = URL() + ) -> Union["BaseCookie[str]", "SimpleCookie[str]"]: + """Returns this jar's cookies filtered by their attributes.""" + self._do_expiration() + request_url = URL(request_url) + filtered: Union["SimpleCookie[str]", "BaseCookie[str]"] = ( + SimpleCookie() if self._quote_cookie else BaseCookie() + ) + hostname = request_url.raw_host or "" + request_origin = URL() + with contextlib.suppress(ValueError): + request_origin = request_url.origin() + + is_not_secure = ( + request_url.scheme not in ("https", "wss") + and request_origin not in self._treat_as_secure_origin + ) + + # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4 + for cookie in sorted(self, key=lambda c: len(c["path"])): + name = cookie.key + domain = cookie["domain"] + + # Send shared cookies + if not domain: + filtered[name] = cookie.value + continue + + if not self._unsafe and is_ip_address(hostname): + continue + + if (domain, name) in self._host_only_cookies: + if domain != hostname: + continue + elif not self._is_domain_match(domain, hostname): + continue + + if not self._is_path_match(request_url.path, cookie["path"]): + continue + + if is_not_secure and cookie["secure"]: + continue + + # It's critical we use the Morsel so the coded_value + # (based on cookie version) is preserved + mrsl_val = cast("Morsel[str]", cookie.get(cookie.key, Morsel())) + mrsl_val.set(cookie.key, cookie.value, cookie.coded_value) + filtered[name] = mrsl_val + + return filtered + + @staticmethod + def _is_domain_match(domain: str, hostname: str) -> bool: + """Implements domain matching adhering to RFC 6265.""" + if hostname == domain: + return True + + if not hostname.endswith(domain): + return False + + non_matching = hostname[: -len(domain)] + + if not non_matching.endswith("."): + return False + + return not is_ip_address(hostname) + + @staticmethod + def _is_path_match(req_path: str, cookie_path: str) -> bool: + """Implements path matching adhering to RFC 6265.""" + if not req_path.startswith("/"): + req_path = "/" + + if req_path == cookie_path: + return True + + if not req_path.startswith(cookie_path): + return False + + if cookie_path.endswith("/"): + return True + + non_matching = req_path[len(cookie_path) :] + + return non_matching.startswith("/") + + @classmethod + def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: + """Implements date string parsing adhering to RFC 6265.""" + if not date_str: + return None + + found_time = False + found_day = False + found_month = False + found_year = False + + hour = minute = second = 0 + day = 0 + month = 0 + year = 0 + + for token_match in cls.DATE_TOKENS_RE.finditer(date_str): + + token = token_match.group("token") + + if not found_time: + time_match = cls.DATE_HMS_TIME_RE.match(token) + if time_match: + found_time = True + hour, minute, second = (int(s) for s in time_match.groups()) + continue + + if not found_day: + day_match = cls.DATE_DAY_OF_MONTH_RE.match(token) + if day_match: + found_day = True + day = int(day_match.group()) + continue + + if not found_month: + month_match = cls.DATE_MONTH_RE.match(token) + if month_match: + found_month = True + assert month_match.lastindex is not None + month = month_match.lastindex + continue + + if not found_year: + year_match = cls.DATE_YEAR_RE.match(token) + if year_match: + found_year = True + year = int(year_match.group()) + + if 70 <= year <= 99: + year += 1900 + elif 0 <= year <= 69: + year += 2000 + + if False in (found_day, found_month, found_year, found_time): + return None + + if not 1 <= day <= 31: + return None + + if year < 1601 or hour > 23 or minute > 59 or second > 59: + return None + + return datetime.datetime( + year, month, day, hour, minute, second, tzinfo=datetime.timezone.utc + ) + + +class DummyCookieJar(AbstractCookieJar): + """Implements a dummy cookie storage. + + It can be used with the ClientSession when no cookie processing is needed. + + """ + + def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + super().__init__(loop=loop) + + def __iter__(self) -> "Iterator[Morsel[str]]": + while False: + yield None + + def __len__(self) -> int: + return 0 + + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + pass + + def clear_domain(self, domain: str) -> None: + pass + + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + pass + + def filter_cookies(self, request_url: URL) -> "BaseCookie[str]": + return SimpleCookie() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/formdata.py b/.venv/lib/python3.7/site-packages/aiohttp/formdata.py new file mode 100644 index 0000000..e7cd24c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/formdata.py @@ -0,0 +1,172 @@ +import io +from typing import Any, Iterable, List, Optional +from urllib.parse import urlencode + +from multidict import MultiDict, MultiDictProxy + +from . import hdrs, multipart, payload +from .helpers import guess_filename +from .payload import Payload + +__all__ = ("FormData",) + + +class FormData: + """Helper class for form body generation. + + Supports multipart/form-data and application/x-www-form-urlencoded. + """ + + def __init__( + self, + fields: Iterable[Any] = (), + quote_fields: bool = True, + charset: Optional[str] = None, + ) -> None: + self._writer = multipart.MultipartWriter("form-data") + self._fields: List[Any] = [] + self._is_multipart = False + self._is_processed = False + self._quote_fields = quote_fields + self._charset = charset + + if isinstance(fields, dict): + fields = list(fields.items()) + elif not isinstance(fields, (list, tuple)): + fields = (fields,) + self.add_fields(*fields) + + @property + def is_multipart(self) -> bool: + return self._is_multipart + + def add_field( + self, + name: str, + value: Any, + *, + content_type: Optional[str] = None, + filename: Optional[str] = None, + content_transfer_encoding: Optional[str] = None, + ) -> None: + + if isinstance(value, io.IOBase): + self._is_multipart = True + elif isinstance(value, (bytes, bytearray, memoryview)): + if filename is None and content_transfer_encoding is None: + filename = name + + type_options: MultiDict[str] = MultiDict({"name": name}) + if filename is not None and not isinstance(filename, str): + raise TypeError( + "filename must be an instance of str. " "Got: %s" % filename + ) + if filename is None and isinstance(value, io.IOBase): + filename = guess_filename(value, name) + if filename is not None: + type_options["filename"] = filename + self._is_multipart = True + + headers = {} + if content_type is not None: + if not isinstance(content_type, str): + raise TypeError( + "content_type must be an instance of str. " "Got: %s" % content_type + ) + headers[hdrs.CONTENT_TYPE] = content_type + self._is_multipart = True + if content_transfer_encoding is not None: + if not isinstance(content_transfer_encoding, str): + raise TypeError( + "content_transfer_encoding must be an instance" + " of str. Got: %s" % content_transfer_encoding + ) + headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding + self._is_multipart = True + + self._fields.append((type_options, headers, value)) + + def add_fields(self, *fields: Any) -> None: + to_add = list(fields) + + while to_add: + rec = to_add.pop(0) + + if isinstance(rec, io.IOBase): + k = guess_filename(rec, "unknown") + self.add_field(k, rec) # type: ignore[arg-type] + + elif isinstance(rec, (MultiDictProxy, MultiDict)): + to_add.extend(rec.items()) + + elif isinstance(rec, (list, tuple)) and len(rec) == 2: + k, fp = rec + self.add_field(k, fp) # type: ignore[arg-type] + + else: + raise TypeError( + "Only io.IOBase, multidict and (name, file) " + "pairs allowed, use .add_field() for passing " + "more complex parameters, got {!r}".format(rec) + ) + + def _gen_form_urlencoded(self) -> payload.BytesPayload: + # form data (x-www-form-urlencoded) + data = [] + for type_options, _, value in self._fields: + data.append((type_options["name"], value)) + + charset = self._charset if self._charset is not None else "utf-8" + + if charset == "utf-8": + content_type = "application/x-www-form-urlencoded" + else: + content_type = "application/x-www-form-urlencoded; " "charset=%s" % charset + + return payload.BytesPayload( + urlencode(data, doseq=True, encoding=charset).encode(), + content_type=content_type, + ) + + def _gen_form_data(self) -> multipart.MultipartWriter: + """Encode a list of fields using the multipart/form-data MIME format""" + if self._is_processed: + raise RuntimeError("Form data has been processed already") + for dispparams, headers, value in self._fields: + try: + if hdrs.CONTENT_TYPE in headers: + part = payload.get_payload( + value, + content_type=headers[hdrs.CONTENT_TYPE], + headers=headers, + encoding=self._charset, + ) + else: + part = payload.get_payload( + value, headers=headers, encoding=self._charset + ) + except Exception as exc: + raise TypeError( + "Can not serialize value type: %r\n " + "headers: %r\n value: %r" % (type(value), headers, value) + ) from exc + + if dispparams: + part.set_content_disposition( + "form-data", quote_fields=self._quote_fields, **dispparams + ) + # FIXME cgi.FieldStorage doesn't likes body parts with + # Content-Length which were sent via chunked transfer encoding + assert part.headers is not None + part.headers.popall(hdrs.CONTENT_LENGTH, None) + + self._writer.append_payload(part) + + self._is_processed = True + return self._writer + + def __call__(self) -> Payload: + if self._is_multipart: + return self._gen_form_data() + else: + return self._gen_form_urlencoded() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/hdrs.py b/.venv/lib/python3.7/site-packages/aiohttp/hdrs.py new file mode 100644 index 0000000..a619f25 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/hdrs.py @@ -0,0 +1,114 @@ +"""HTTP Headers constants.""" + +# After changing the file content call ./tools/gen.py +# to regenerate the headers parser +import sys +from typing import Set + +from multidict import istr + +if sys.version_info >= (3, 8): + from typing import Final +else: + from typing_extensions import Final + +METH_ANY: Final[str] = "*" +METH_CONNECT: Final[str] = "CONNECT" +METH_HEAD: Final[str] = "HEAD" +METH_GET: Final[str] = "GET" +METH_DELETE: Final[str] = "DELETE" +METH_OPTIONS: Final[str] = "OPTIONS" +METH_PATCH: Final[str] = "PATCH" +METH_POST: Final[str] = "POST" +METH_PUT: Final[str] = "PUT" +METH_TRACE: Final[str] = "TRACE" + +METH_ALL: Final[Set[str]] = { + METH_CONNECT, + METH_HEAD, + METH_GET, + METH_DELETE, + METH_OPTIONS, + METH_PATCH, + METH_POST, + METH_PUT, + METH_TRACE, +} + +ACCEPT: Final[istr] = istr("Accept") +ACCEPT_CHARSET: Final[istr] = istr("Accept-Charset") +ACCEPT_ENCODING: Final[istr] = istr("Accept-Encoding") +ACCEPT_LANGUAGE: Final[istr] = istr("Accept-Language") +ACCEPT_RANGES: Final[istr] = istr("Accept-Ranges") +ACCESS_CONTROL_MAX_AGE: Final[istr] = istr("Access-Control-Max-Age") +ACCESS_CONTROL_ALLOW_CREDENTIALS: Final[istr] = istr("Access-Control-Allow-Credentials") +ACCESS_CONTROL_ALLOW_HEADERS: Final[istr] = istr("Access-Control-Allow-Headers") +ACCESS_CONTROL_ALLOW_METHODS: Final[istr] = istr("Access-Control-Allow-Methods") +ACCESS_CONTROL_ALLOW_ORIGIN: Final[istr] = istr("Access-Control-Allow-Origin") +ACCESS_CONTROL_EXPOSE_HEADERS: Final[istr] = istr("Access-Control-Expose-Headers") +ACCESS_CONTROL_REQUEST_HEADERS: Final[istr] = istr("Access-Control-Request-Headers") +ACCESS_CONTROL_REQUEST_METHOD: Final[istr] = istr("Access-Control-Request-Method") +AGE: Final[istr] = istr("Age") +ALLOW: Final[istr] = istr("Allow") +AUTHORIZATION: Final[istr] = istr("Authorization") +CACHE_CONTROL: Final[istr] = istr("Cache-Control") +CONNECTION: Final[istr] = istr("Connection") +CONTENT_DISPOSITION: Final[istr] = istr("Content-Disposition") +CONTENT_ENCODING: Final[istr] = istr("Content-Encoding") +CONTENT_LANGUAGE: Final[istr] = istr("Content-Language") +CONTENT_LENGTH: Final[istr] = istr("Content-Length") +CONTENT_LOCATION: Final[istr] = istr("Content-Location") +CONTENT_MD5: Final[istr] = istr("Content-MD5") +CONTENT_RANGE: Final[istr] = istr("Content-Range") +CONTENT_TRANSFER_ENCODING: Final[istr] = istr("Content-Transfer-Encoding") +CONTENT_TYPE: Final[istr] = istr("Content-Type") +COOKIE: Final[istr] = istr("Cookie") +DATE: Final[istr] = istr("Date") +DESTINATION: Final[istr] = istr("Destination") +DIGEST: Final[istr] = istr("Digest") +ETAG: Final[istr] = istr("Etag") +EXPECT: Final[istr] = istr("Expect") +EXPIRES: Final[istr] = istr("Expires") +FORWARDED: Final[istr] = istr("Forwarded") +FROM: Final[istr] = istr("From") +HOST: Final[istr] = istr("Host") +IF_MATCH: Final[istr] = istr("If-Match") +IF_MODIFIED_SINCE: Final[istr] = istr("If-Modified-Since") +IF_NONE_MATCH: Final[istr] = istr("If-None-Match") +IF_RANGE: Final[istr] = istr("If-Range") +IF_UNMODIFIED_SINCE: Final[istr] = istr("If-Unmodified-Since") +KEEP_ALIVE: Final[istr] = istr("Keep-Alive") +LAST_EVENT_ID: Final[istr] = istr("Last-Event-ID") +LAST_MODIFIED: Final[istr] = istr("Last-Modified") +LINK: Final[istr] = istr("Link") +LOCATION: Final[istr] = istr("Location") +MAX_FORWARDS: Final[istr] = istr("Max-Forwards") +ORIGIN: Final[istr] = istr("Origin") +PRAGMA: Final[istr] = istr("Pragma") +PROXY_AUTHENTICATE: Final[istr] = istr("Proxy-Authenticate") +PROXY_AUTHORIZATION: Final[istr] = istr("Proxy-Authorization") +RANGE: Final[istr] = istr("Range") +REFERER: Final[istr] = istr("Referer") +RETRY_AFTER: Final[istr] = istr("Retry-After") +SEC_WEBSOCKET_ACCEPT: Final[istr] = istr("Sec-WebSocket-Accept") +SEC_WEBSOCKET_VERSION: Final[istr] = istr("Sec-WebSocket-Version") +SEC_WEBSOCKET_PROTOCOL: Final[istr] = istr("Sec-WebSocket-Protocol") +SEC_WEBSOCKET_EXTENSIONS: Final[istr] = istr("Sec-WebSocket-Extensions") +SEC_WEBSOCKET_KEY: Final[istr] = istr("Sec-WebSocket-Key") +SEC_WEBSOCKET_KEY1: Final[istr] = istr("Sec-WebSocket-Key1") +SERVER: Final[istr] = istr("Server") +SET_COOKIE: Final[istr] = istr("Set-Cookie") +TE: Final[istr] = istr("TE") +TRAILER: Final[istr] = istr("Trailer") +TRANSFER_ENCODING: Final[istr] = istr("Transfer-Encoding") +UPGRADE: Final[istr] = istr("Upgrade") +URI: Final[istr] = istr("URI") +USER_AGENT: Final[istr] = istr("User-Agent") +VARY: Final[istr] = istr("Vary") +VIA: Final[istr] = istr("Via") +WANT_DIGEST: Final[istr] = istr("Want-Digest") +WARNING: Final[istr] = istr("Warning") +WWW_AUTHENTICATE: Final[istr] = istr("WWW-Authenticate") +X_FORWARDED_FOR: Final[istr] = istr("X-Forwarded-For") +X_FORWARDED_HOST: Final[istr] = istr("X-Forwarded-Host") +X_FORWARDED_PROTO: Final[istr] = istr("X-Forwarded-Proto") diff --git a/.venv/lib/python3.7/site-packages/aiohttp/helpers.py b/.venv/lib/python3.7/site-packages/aiohttp/helpers.py new file mode 100644 index 0000000..eb0782f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/helpers.py @@ -0,0 +1,881 @@ +"""Various helper functions""" + +import asyncio +import base64 +import binascii +import contextlib +import datetime +import functools +import inspect +import netrc +import os +import platform +import re +import sys +import time +import warnings +import weakref +from collections import namedtuple +from contextlib import suppress +from email.parser import HeaderParser +from email.utils import parsedate +from math import ceil +from pathlib import Path +from types import TracebackType +from typing import ( + Any, + Callable, + ContextManager, + Dict, + Generator, + Generic, + Iterable, + Iterator, + List, + Mapping, + Optional, + Pattern, + Set, + Tuple, + Type, + TypeVar, + Union, + cast, +) +from urllib.parse import quote +from urllib.request import getproxies, proxy_bypass + +import async_timeout +import attr +from multidict import MultiDict, MultiDictProxy +from yarl import URL + +from . import hdrs +from .log import client_logger, internal_logger +from .typedefs import PathLike, Protocol # noqa + +__all__ = ("BasicAuth", "ChainMapProxy", "ETag") + +IS_MACOS = platform.system() == "Darwin" +IS_WINDOWS = platform.system() == "Windows" + +PY_36 = sys.version_info >= (3, 6) +PY_37 = sys.version_info >= (3, 7) +PY_38 = sys.version_info >= (3, 8) +PY_310 = sys.version_info >= (3, 10) +PY_311 = sys.version_info >= (3, 11) + +if sys.version_info < (3, 7): + import idna_ssl + + idna_ssl.patch_match_hostname() + + def all_tasks( + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> Set["asyncio.Task[Any]"]: + tasks = list(asyncio.Task.all_tasks(loop)) + return {t for t in tasks if not t.done()} + +else: + all_tasks = asyncio.all_tasks + + +_T = TypeVar("_T") +_S = TypeVar("_S") + + +sentinel: Any = object() +NO_EXTENSIONS: bool = bool(os.environ.get("AIOHTTP_NO_EXTENSIONS")) + +# N.B. sys.flags.dev_mode is available on Python 3.7+, use getattr +# for compatibility with older versions +DEBUG: bool = getattr(sys.flags, "dev_mode", False) or ( + not sys.flags.ignore_environment and bool(os.environ.get("PYTHONASYNCIODEBUG")) +) + + +CHAR = {chr(i) for i in range(0, 128)} +CTL = {chr(i) for i in range(0, 32)} | { + chr(127), +} +SEPARATORS = { + "(", + ")", + "<", + ">", + "@", + ",", + ";", + ":", + "\\", + '"', + "/", + "[", + "]", + "?", + "=", + "{", + "}", + " ", + chr(9), +} +TOKEN = CHAR ^ CTL ^ SEPARATORS + + +class noop: + def __await__(self) -> Generator[None, None, None]: + yield + + +class BasicAuth(namedtuple("BasicAuth", ["login", "password", "encoding"])): + """Http basic authentication helper.""" + + def __new__( + cls, login: str, password: str = "", encoding: str = "latin1" + ) -> "BasicAuth": + if login is None: + raise ValueError("None is not allowed as login value") + + if password is None: + raise ValueError("None is not allowed as password value") + + if ":" in login: + raise ValueError('A ":" is not allowed in login (RFC 1945#section-11.1)') + + return super().__new__(cls, login, password, encoding) + + @classmethod + def decode(cls, auth_header: str, encoding: str = "latin1") -> "BasicAuth": + """Create a BasicAuth object from an Authorization HTTP header.""" + try: + auth_type, encoded_credentials = auth_header.split(" ", 1) + except ValueError: + raise ValueError("Could not parse authorization header.") + + if auth_type.lower() != "basic": + raise ValueError("Unknown authorization method %s" % auth_type) + + try: + decoded = base64.b64decode( + encoded_credentials.encode("ascii"), validate=True + ).decode(encoding) + except binascii.Error: + raise ValueError("Invalid base64 encoding.") + + try: + # RFC 2617 HTTP Authentication + # https://www.ietf.org/rfc/rfc2617.txt + # the colon must be present, but the username and password may be + # otherwise blank. + username, password = decoded.split(":", 1) + except ValueError: + raise ValueError("Invalid credentials.") + + return cls(username, password, encoding=encoding) + + @classmethod + def from_url(cls, url: URL, *, encoding: str = "latin1") -> Optional["BasicAuth"]: + """Create BasicAuth from url.""" + if not isinstance(url, URL): + raise TypeError("url should be yarl.URL instance") + if url.user is None: + return None + return cls(url.user, url.password or "", encoding=encoding) + + def encode(self) -> str: + """Encode credentials.""" + creds = (f"{self.login}:{self.password}").encode(self.encoding) + return "Basic %s" % base64.b64encode(creds).decode(self.encoding) + + +def strip_auth_from_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: + auth = BasicAuth.from_url(url) + if auth is None: + return url, None + else: + return url.with_user(None), auth + + +def netrc_from_env() -> Optional[netrc.netrc]: + """Load netrc from file. + + Attempt to load it from the path specified by the env-var + NETRC or in the default location in the user's home directory. + + Returns None if it couldn't be found or fails to parse. + """ + netrc_env = os.environ.get("NETRC") + + if netrc_env is not None: + netrc_path = Path(netrc_env) + else: + try: + home_dir = Path.home() + except RuntimeError as e: # pragma: no cover + # if pathlib can't resolve home, it may raise a RuntimeError + client_logger.debug( + "Could not resolve home directory when " + "trying to look for .netrc file: %s", + e, + ) + return None + + netrc_path = home_dir / ("_netrc" if IS_WINDOWS else ".netrc") + + try: + return netrc.netrc(str(netrc_path)) + except netrc.NetrcParseError as e: + client_logger.warning("Could not parse .netrc file: %s", e) + except OSError as e: + netrc_exists = False + with contextlib.suppress(OSError): + netrc_exists = netrc_path.is_file() + # we couldn't read the file (doesn't exist, permissions, etc.) + if netrc_env or netrc_exists: + # only warn if the environment wanted us to load it, + # or it appears like the default file does actually exist + client_logger.warning("Could not read .netrc file: %s", e) + + return None + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ProxyInfo: + proxy: URL + proxy_auth: Optional[BasicAuth] + + +def proxies_from_env() -> Dict[str, ProxyInfo]: + proxy_urls = { + k: URL(v) + for k, v in getproxies().items() + if k in ("http", "https", "ws", "wss") + } + netrc_obj = netrc_from_env() + stripped = {k: strip_auth_from_url(v) for k, v in proxy_urls.items()} + ret = {} + for proto, val in stripped.items(): + proxy, auth = val + if proxy.scheme in ("https", "wss"): + client_logger.warning( + "%s proxies %s are not supported, ignoring", proxy.scheme.upper(), proxy + ) + continue + if netrc_obj and auth is None: + auth_from_netrc = None + if proxy.host is not None: + auth_from_netrc = netrc_obj.authenticators(proxy.host) + if auth_from_netrc is not None: + # auth_from_netrc is a (`user`, `account`, `password`) tuple, + # `user` and `account` both can be username, + # if `user` is None, use `account` + *logins, password = auth_from_netrc + login = logins[0] if logins[0] else logins[-1] + auth = BasicAuth(cast(str, login), cast(str, password)) + ret[proto] = ProxyInfo(proxy, auth) + return ret + + +def current_task( + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> "Optional[asyncio.Task[Any]]": + if sys.version_info >= (3, 7): + return asyncio.current_task(loop=loop) + else: + return asyncio.Task.current_task(loop=loop) + + +def get_running_loop( + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> asyncio.AbstractEventLoop: + if loop is None: + loop = asyncio.get_event_loop() + if not loop.is_running(): + warnings.warn( + "The object should be created within an async function", + DeprecationWarning, + stacklevel=3, + ) + if loop.get_debug(): + internal_logger.warning( + "The object should be created within an async function", stack_info=True + ) + return loop + + +def isasyncgenfunction(obj: Any) -> bool: + func = getattr(inspect, "isasyncgenfunction", None) + if func is not None: + return func(obj) # type: ignore[no-any-return] + else: + return False + + +def get_env_proxy_for_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: + """Get a permitted proxy for the given URL from the env.""" + if url.host is not None and proxy_bypass(url.host): + raise LookupError(f"Proxying is disallowed for `{url.host!r}`") + + proxies_in_env = proxies_from_env() + try: + proxy_info = proxies_in_env[url.scheme] + except KeyError: + raise LookupError(f"No proxies found for `{url!s}` in the env") + else: + return proxy_info.proxy, proxy_info.proxy_auth + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class MimeType: + type: str + subtype: str + suffix: str + parameters: "MultiDictProxy[str]" + + +@functools.lru_cache(maxsize=56) +def parse_mimetype(mimetype: str) -> MimeType: + """Parses a MIME type into its components. + + mimetype is a MIME type string. + + Returns a MimeType object. + + Example: + + >>> parse_mimetype('text/html; charset=utf-8') + MimeType(type='text', subtype='html', suffix='', + parameters={'charset': 'utf-8'}) + + """ + if not mimetype: + return MimeType( + type="", subtype="", suffix="", parameters=MultiDictProxy(MultiDict()) + ) + + parts = mimetype.split(";") + params: MultiDict[str] = MultiDict() + for item in parts[1:]: + if not item: + continue + key, value = cast( + Tuple[str, str], item.split("=", 1) if "=" in item else (item, "") + ) + params.add(key.lower().strip(), value.strip(' "')) + + fulltype = parts[0].strip().lower() + if fulltype == "*": + fulltype = "*/*" + + mtype, stype = ( + cast(Tuple[str, str], fulltype.split("/", 1)) + if "/" in fulltype + else (fulltype, "") + ) + stype, suffix = ( + cast(Tuple[str, str], stype.split("+", 1)) if "+" in stype else (stype, "") + ) + + return MimeType( + type=mtype, subtype=stype, suffix=suffix, parameters=MultiDictProxy(params) + ) + + +def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]: + name = getattr(obj, "name", None) + if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">": + return Path(name).name + return default + + +not_qtext_re = re.compile(r"[^\041\043-\133\135-\176]") +QCONTENT = {chr(i) for i in range(0x20, 0x7F)} | {"\t"} + + +def quoted_string(content: str) -> str: + """Return 7-bit content as quoted-string. + + Format content into a quoted-string as defined in RFC5322 for + Internet Message Format. Notice that this is not the 8-bit HTTP + format, but the 7-bit email format. Content must be in usascii or + a ValueError is raised. + """ + if not (QCONTENT > set(content)): + raise ValueError(f"bad content for quoted-string {content!r}") + return not_qtext_re.sub(lambda x: "\\" + x.group(0), content) + + +def content_disposition_header( + disptype: str, quote_fields: bool = True, _charset: str = "utf-8", **params: str +) -> str: + """Sets ``Content-Disposition`` header for MIME. + + This is the MIME payload Content-Disposition header from RFC 2183 + and RFC 7579 section 4.2, not the HTTP Content-Disposition from + RFC 6266. + + disptype is a disposition type: inline, attachment, form-data. + Should be valid extension token (see RFC 2183) + + quote_fields performs value quoting to 7-bit MIME headers + according to RFC 7578. Set to quote_fields to False if recipient + can take 8-bit file names and field values. + + _charset specifies the charset to use when quote_fields is True. + + params is a dict with disposition params. + """ + if not disptype or not (TOKEN > set(disptype)): + raise ValueError("bad content disposition type {!r}" "".format(disptype)) + + value = disptype + if params: + lparams = [] + for key, val in params.items(): + if not key or not (TOKEN > set(key)): + raise ValueError( + "bad content disposition parameter" " {!r}={!r}".format(key, val) + ) + if quote_fields: + if key.lower() == "filename": + qval = quote(val, "", encoding=_charset) + lparams.append((key, '"%s"' % qval)) + else: + try: + qval = quoted_string(val) + except ValueError: + qval = "".join( + (_charset, "''", quote(val, "", encoding=_charset)) + ) + lparams.append((key + "*", qval)) + else: + lparams.append((key, '"%s"' % qval)) + else: + qval = val.replace("\\", "\\\\").replace('"', '\\"') + lparams.append((key, '"%s"' % qval)) + sparams = "; ".join("=".join(pair) for pair in lparams) + value = "; ".join((value, sparams)) + return value + + +class _TSelf(Protocol, Generic[_T]): + _cache: Dict[str, _T] + + +class reify(Generic[_T]): + """Use as a class method decorator. + + It operates almost exactly like + the Python `@property` decorator, but it puts the result of the + method it decorates into the instance dict after the first call, + effectively replacing the function it decorates with an instance + variable. It is, in Python parlance, a data descriptor. + """ + + def __init__(self, wrapped: Callable[..., _T]) -> None: + self.wrapped = wrapped + self.__doc__ = wrapped.__doc__ + self.name = wrapped.__name__ + + def __get__(self, inst: _TSelf[_T], owner: Optional[Type[Any]] = None) -> _T: + try: + try: + return inst._cache[self.name] + except KeyError: + val = self.wrapped(inst) + inst._cache[self.name] = val + return val + except AttributeError: + if inst is None: + return self + raise + + def __set__(self, inst: _TSelf[_T], value: _T) -> None: + raise AttributeError("reified property is read-only") + + +reify_py = reify + +try: + from ._helpers import reify as reify_c + + if not NO_EXTENSIONS: + reify = reify_c # type: ignore[misc,assignment] +except ImportError: + pass + +_ipv4_pattern = ( + r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}" + r"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" +) +_ipv6_pattern = ( + r"^(?:(?:(?:[A-F0-9]{1,4}:){6}|(?=(?:[A-F0-9]{0,4}:){0,6}" + r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)(([0-9A-F]{1,4}:){0,5}|:)" + r"((:[0-9A-F]{1,4}){1,5}:|:)|::(?:[A-F0-9]{1,4}:){5})" + r"(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}" + r"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])|(?:[A-F0-9]{1,4}:){7}" + r"[A-F0-9]{1,4}|(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}$)" + r"(([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)|(?:[A-F0-9]{1,4}:){7}" + r":|:(:[A-F0-9]{1,4}){7})$" +) +_ipv4_regex = re.compile(_ipv4_pattern) +_ipv6_regex = re.compile(_ipv6_pattern, flags=re.IGNORECASE) +_ipv4_regexb = re.compile(_ipv4_pattern.encode("ascii")) +_ipv6_regexb = re.compile(_ipv6_pattern.encode("ascii"), flags=re.IGNORECASE) + + +def _is_ip_address( + regex: Pattern[str], regexb: Pattern[bytes], host: Optional[Union[str, bytes]] +) -> bool: + if host is None: + return False + if isinstance(host, str): + return bool(regex.match(host)) + elif isinstance(host, (bytes, bytearray, memoryview)): + return bool(regexb.match(host)) + else: + raise TypeError(f"{host} [{type(host)}] is not a str or bytes") + + +is_ipv4_address = functools.partial(_is_ip_address, _ipv4_regex, _ipv4_regexb) +is_ipv6_address = functools.partial(_is_ip_address, _ipv6_regex, _ipv6_regexb) + + +def is_ip_address(host: Optional[Union[str, bytes, bytearray, memoryview]]) -> bool: + return is_ipv4_address(host) or is_ipv6_address(host) + + +def next_whole_second() -> datetime.datetime: + """Return current time rounded up to the next whole second.""" + return datetime.datetime.now(datetime.timezone.utc).replace( + microsecond=0 + ) + datetime.timedelta(seconds=0) + + +_cached_current_datetime: Optional[int] = None +_cached_formatted_datetime = "" + + +def rfc822_formatted_time() -> str: + global _cached_current_datetime + global _cached_formatted_datetime + + now = int(time.time()) + if now != _cached_current_datetime: + # Weekday and month names for HTTP date/time formatting; + # always English! + # Tuples are constants stored in codeobject! + _weekdayname = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") + _monthname = ( + "", # Dummy so we can use 1-based month numbers + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + ) + + year, month, day, hh, mm, ss, wd, *tail = time.gmtime(now) + _cached_formatted_datetime = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + _weekdayname[wd], + day, + _monthname[month], + year, + hh, + mm, + ss, + ) + _cached_current_datetime = now + return _cached_formatted_datetime + + +def _weakref_handle(info: "Tuple[weakref.ref[object], str]") -> None: + ref, name = info + ob = ref() + if ob is not None: + with suppress(Exception): + getattr(ob, name)() + + +def weakref_handle( + ob: object, name: str, timeout: float, loop: asyncio.AbstractEventLoop +) -> Optional[asyncio.TimerHandle]: + if timeout is not None and timeout > 0: + when = loop.time() + timeout + if timeout >= 5: + when = ceil(when) + + return loop.call_at(when, _weakref_handle, (weakref.ref(ob), name)) + return None + + +def call_later( + cb: Callable[[], Any], timeout: float, loop: asyncio.AbstractEventLoop +) -> Optional[asyncio.TimerHandle]: + if timeout is not None and timeout > 0: + when = loop.time() + timeout + if timeout > 5: + when = ceil(when) + return loop.call_at(when, cb) + return None + + +class TimeoutHandle: + """Timeout handle""" + + def __init__( + self, loop: asyncio.AbstractEventLoop, timeout: Optional[float] + ) -> None: + self._timeout = timeout + self._loop = loop + self._callbacks: List[ + Tuple[Callable[..., None], Tuple[Any, ...], Dict[str, Any]] + ] = [] + + def register( + self, callback: Callable[..., None], *args: Any, **kwargs: Any + ) -> None: + self._callbacks.append((callback, args, kwargs)) + + def close(self) -> None: + self._callbacks.clear() + + def start(self) -> Optional[asyncio.Handle]: + timeout = self._timeout + if timeout is not None and timeout > 0: + when = self._loop.time() + timeout + if timeout >= 5: + when = ceil(when) + return self._loop.call_at(when, self.__call__) + else: + return None + + def timer(self) -> "BaseTimerContext": + if self._timeout is not None and self._timeout > 0: + timer = TimerContext(self._loop) + self.register(timer.timeout) + return timer + else: + return TimerNoop() + + def __call__(self) -> None: + for cb, args, kwargs in self._callbacks: + with suppress(Exception): + cb(*args, **kwargs) + + self._callbacks.clear() + + +class BaseTimerContext(ContextManager["BaseTimerContext"]): + pass + + +class TimerNoop(BaseTimerContext): + def __enter__(self) -> BaseTimerContext: + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + return + + +class TimerContext(BaseTimerContext): + """Low resolution timeout context manager""" + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._tasks: List[asyncio.Task[Any]] = [] + self._cancelled = False + + def __enter__(self) -> BaseTimerContext: + task = current_task(loop=self._loop) + + if task is None: + raise RuntimeError( + "Timeout context manager should be used " "inside a task" + ) + + if self._cancelled: + raise asyncio.TimeoutError from None + + self._tasks.append(task) + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + if self._tasks: + self._tasks.pop() + + if exc_type is asyncio.CancelledError and self._cancelled: + raise asyncio.TimeoutError from None + return None + + def timeout(self) -> None: + if not self._cancelled: + for task in set(self._tasks): + task.cancel() + + self._cancelled = True + + +def ceil_timeout(delay: Optional[float]) -> async_timeout.Timeout: + if delay is None or delay <= 0: + return async_timeout.timeout(None) + + loop = get_running_loop() + now = loop.time() + when = now + delay + if delay > 5: + when = ceil(when) + return async_timeout.timeout_at(when) + + +class HeadersMixin: + ATTRS = frozenset(["_content_type", "_content_dict", "_stored_content_type"]) + + _content_type: Optional[str] = None + _content_dict: Optional[Dict[str, str]] = None + _stored_content_type = sentinel + + def _parse_content_type(self, raw: str) -> None: + self._stored_content_type = raw + if raw is None: + # default value according to RFC 2616 + self._content_type = "application/octet-stream" + self._content_dict = {} + else: + msg = HeaderParser().parsestr("Content-Type: " + raw) + self._content_type = msg.get_content_type() + params = msg.get_params() + self._content_dict = dict(params[1:]) # First element is content type again + + @property + def content_type(self) -> str: + """The value of content part for Content-Type HTTP header.""" + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore[attr-defined] + if self._stored_content_type != raw: + self._parse_content_type(raw) + return self._content_type # type: ignore[return-value] + + @property + def charset(self) -> Optional[str]: + """The value of charset part for Content-Type HTTP header.""" + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore[attr-defined] + if self._stored_content_type != raw: + self._parse_content_type(raw) + return self._content_dict.get("charset") # type: ignore[union-attr] + + @property + def content_length(self) -> Optional[int]: + """The value of Content-Length HTTP header.""" + content_length = self._headers.get( # type: ignore[attr-defined] + hdrs.CONTENT_LENGTH + ) + + if content_length is not None: + return int(content_length) + else: + return None + + +def set_result(fut: "asyncio.Future[_T]", result: _T) -> None: + if not fut.done(): + fut.set_result(result) + + +def set_exception(fut: "asyncio.Future[_T]", exc: BaseException) -> None: + if not fut.done(): + fut.set_exception(exc) + + +class ChainMapProxy(Mapping[str, Any]): + __slots__ = ("_maps",) + + def __init__(self, maps: Iterable[Mapping[str, Any]]) -> None: + self._maps = tuple(maps) + + def __init_subclass__(cls) -> None: + raise TypeError( + "Inheritance class {} from ChainMapProxy " + "is forbidden".format(cls.__name__) + ) + + def __getitem__(self, key: str) -> Any: + for mapping in self._maps: + try: + return mapping[key] + except KeyError: + pass + raise KeyError(key) + + def get(self, key: str, default: Any = None) -> Any: + return self[key] if key in self else default + + def __len__(self) -> int: + # reuses stored hash values if possible + return len(set().union(*self._maps)) # type: ignore[arg-type] + + def __iter__(self) -> Iterator[str]: + d: Dict[str, Any] = {} + for mapping in reversed(self._maps): + # reuses stored hash values if possible + d.update(mapping) + return iter(d) + + def __contains__(self, key: object) -> bool: + return any(key in m for m in self._maps) + + def __bool__(self) -> bool: + return any(self._maps) + + def __repr__(self) -> str: + content = ", ".join(map(repr, self._maps)) + return f"ChainMapProxy({content})" + + +# https://tools.ietf.org/html/rfc7232#section-2.3 +_ETAGC = r"[!#-}\x80-\xff]+" +_ETAGC_RE = re.compile(_ETAGC) +_QUOTED_ETAG = rf'(W/)?"({_ETAGC})"' +QUOTED_ETAG_RE = re.compile(_QUOTED_ETAG) +LIST_QUOTED_ETAG_RE = re.compile(rf"({_QUOTED_ETAG})(?:\s*,\s*|$)|(.)") + +ETAG_ANY = "*" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ETag: + value: str + is_weak: bool = False + + +def validate_etag_value(value: str) -> None: + if value != ETAG_ANY and not _ETAGC_RE.fullmatch(value): + raise ValueError( + f"Value {value!r} is not a valid etag. Maybe it contains '\"'?" + ) + + +def parse_http_date(date_str: Optional[str]) -> Optional[datetime.datetime]: + """Process a date string, return a datetime object""" + if date_str is not None: + timetuple = parsedate(date_str) + if timetuple is not None: + with suppress(ValueError): + return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) + return None diff --git a/.venv/lib/python3.7/site-packages/aiohttp/http.py b/.venv/lib/python3.7/site-packages/aiohttp/http.py new file mode 100644 index 0000000..ca9dc54 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/http.py @@ -0,0 +1,70 @@ +import http.server +import sys +from typing import Mapping, Tuple + +from . import __version__ +from .http_exceptions import HttpProcessingError as HttpProcessingError +from .http_parser import ( + HeadersParser as HeadersParser, + HttpParser as HttpParser, + HttpRequestParser as HttpRequestParser, + HttpResponseParser as HttpResponseParser, + RawRequestMessage as RawRequestMessage, + RawResponseMessage as RawResponseMessage, +) +from .http_websocket import ( + WS_CLOSED_MESSAGE as WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE as WS_CLOSING_MESSAGE, + WS_KEY as WS_KEY, + WebSocketError as WebSocketError, + WebSocketReader as WebSocketReader, + WebSocketWriter as WebSocketWriter, + WSCloseCode as WSCloseCode, + WSMessage as WSMessage, + WSMsgType as WSMsgType, + ws_ext_gen as ws_ext_gen, + ws_ext_parse as ws_ext_parse, +) +from .http_writer import ( + HttpVersion as HttpVersion, + HttpVersion10 as HttpVersion10, + HttpVersion11 as HttpVersion11, + StreamWriter as StreamWriter, +) + +__all__ = ( + "HttpProcessingError", + "RESPONSES", + "SERVER_SOFTWARE", + # .http_writer + "StreamWriter", + "HttpVersion", + "HttpVersion10", + "HttpVersion11", + # .http_parser + "HeadersParser", + "HttpParser", + "HttpRequestParser", + "HttpResponseParser", + "RawRequestMessage", + "RawResponseMessage", + # .http_websocket + "WS_CLOSED_MESSAGE", + "WS_CLOSING_MESSAGE", + "WS_KEY", + "WebSocketReader", + "WebSocketWriter", + "ws_ext_gen", + "ws_ext_parse", + "WSMessage", + "WebSocketError", + "WSMsgType", + "WSCloseCode", +) + + +SERVER_SOFTWARE: str = "Python/{0[0]}.{0[1]} aiohttp/{1}".format( + sys.version_info, __version__ +) + +RESPONSES: Mapping[int, Tuple[str, str]] = http.server.BaseHTTPRequestHandler.responses diff --git a/.venv/lib/python3.7/site-packages/aiohttp/http_exceptions.py b/.venv/lib/python3.7/site-packages/aiohttp/http_exceptions.py new file mode 100644 index 0000000..63c20af --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/http_exceptions.py @@ -0,0 +1,107 @@ +"""Low-level http related exceptions.""" + + +from textwrap import indent +from typing import Optional, Union + +from .typedefs import _CIMultiDict + +__all__ = ("HttpProcessingError",) + + +class HttpProcessingError(Exception): + """HTTP error. + + Shortcut for raising HTTP errors with custom code, message and headers. + + code: HTTP Error code. + message: (optional) Error message. + headers: (optional) Headers to be sent in response, a list of pairs + """ + + code = 0 + message = "" + headers = None + + def __init__( + self, + *, + code: Optional[int] = None, + message: str = "", + headers: Optional[_CIMultiDict] = None, + ) -> None: + if code is not None: + self.code = code + self.headers = headers + self.message = message + + def __str__(self) -> str: + msg = indent(self.message, " ") + return f"{self.code}, message:\n{msg}" + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}: {self.code}, message={self.message!r}>" + + +class BadHttpMessage(HttpProcessingError): + + code = 400 + message = "Bad Request" + + def __init__(self, message: str, *, headers: Optional[_CIMultiDict] = None) -> None: + super().__init__(message=message, headers=headers) + self.args = (message,) + + +class HttpBadRequest(BadHttpMessage): + + code = 400 + message = "Bad Request" + + +class PayloadEncodingError(BadHttpMessage): + """Base class for payload errors""" + + +class ContentEncodingError(PayloadEncodingError): + """Content encoding error.""" + + +class TransferEncodingError(PayloadEncodingError): + """transfer encoding error.""" + + +class ContentLengthError(PayloadEncodingError): + """Not enough data for satisfy content length header.""" + + +class LineTooLong(BadHttpMessage): + def __init__( + self, line: str, limit: str = "Unknown", actual_size: str = "Unknown" + ) -> None: + super().__init__( + f"Got more than {limit} bytes ({actual_size}) when reading {line}." + ) + self.args = (line, limit, actual_size) + + +class InvalidHeader(BadHttpMessage): + def __init__(self, hdr: Union[bytes, str]) -> None: + if isinstance(hdr, bytes): + hdr = hdr.decode("utf-8", "surrogateescape") + super().__init__(f"Invalid HTTP Header: {hdr}") + self.hdr = hdr + self.args = (hdr,) + + +class BadStatusLine(BadHttpMessage): + def __init__(self, line: str = "", error: Optional[str] = None) -> None: + if not isinstance(line, str): + line = repr(line) + super().__init__(error or f"Bad status line {line!r}") + self.args = (line,) + self.line = line + + +class InvalidURLError(BadHttpMessage): + pass diff --git a/.venv/lib/python3.7/site-packages/aiohttp/http_parser.py b/.venv/lib/python3.7/site-packages/aiohttp/http_parser.py new file mode 100644 index 0000000..91e01f4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/http_parser.py @@ -0,0 +1,1025 @@ +import abc +import asyncio +import collections +import re +import string +import sys +import zlib +from contextlib import suppress +from enum import IntEnum +from typing import ( + Any, + ClassVar, + Generic, + List, + NamedTuple, + Optional, + Pattern, + Set, + Tuple, + Type, + TypeVar, + Union, + cast, +) + +from multidict import CIMultiDict, CIMultiDictProxy, istr +from yarl import URL + +from . import hdrs +from .base_protocol import BaseProtocol +from .helpers import DEBUG, NO_EXTENSIONS, BaseTimerContext +from .http_exceptions import ( + BadHttpMessage, + BadStatusLine, + ContentEncodingError, + ContentLengthError, + InvalidHeader, + LineTooLong, + TransferEncodingError, +) +from .http_writer import HttpVersion, HttpVersion10 +from .log import internal_logger +from .streams import EMPTY_PAYLOAD, StreamReader +from .typedefs import Final, RawHeaders + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + +try: + import brotli + + HAS_BROTLI = True +except ImportError: # pragma: no cover + HAS_BROTLI = False + + +__all__ = ( + "HeadersParser", + "HttpParser", + "HttpRequestParser", + "HttpResponseParser", + "RawRequestMessage", + "RawResponseMessage", +) + +_SEP = Literal[b"\r\n", b"\n"] + +ASCIISET: Final[Set[str]] = set(string.printable) + +# See https://www.rfc-editor.org/rfc/rfc9110.html#name-overview +# and https://www.rfc-editor.org/rfc/rfc9110.html#name-tokens +# +# method = token +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / +# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA +# token = 1*tchar +METHRE: Final[Pattern[str]] = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") +VERSRE: Final[Pattern[str]] = re.compile(r"HTTP/(\d).(\d)") +HDRRE: Final[Pattern[bytes]] = re.compile(rb"[\x00-\x1F\x7F()<>@,;:\[\]={} \t\"\\]") +HEXDIGIT = re.compile(rb"[0-9a-fA-F]+") + + +class RawRequestMessage(NamedTuple): + method: str + path: str + version: HttpVersion + headers: "CIMultiDictProxy[str]" + raw_headers: RawHeaders + should_close: bool + compression: Optional[str] + upgrade: bool + chunked: bool + url: URL + + +RawResponseMessage = collections.namedtuple( + "RawResponseMessage", + [ + "version", + "code", + "reason", + "headers", + "raw_headers", + "should_close", + "compression", + "upgrade", + "chunked", + ], +) + + +_MsgT = TypeVar("_MsgT", RawRequestMessage, RawResponseMessage) + + +class ParseState(IntEnum): + + PARSE_NONE = 0 + PARSE_LENGTH = 1 + PARSE_CHUNKED = 2 + PARSE_UNTIL_EOF = 3 + + +class ChunkState(IntEnum): + PARSE_CHUNKED_SIZE = 0 + PARSE_CHUNKED_CHUNK = 1 + PARSE_CHUNKED_CHUNK_EOF = 2 + PARSE_MAYBE_TRAILERS = 3 + PARSE_TRAILERS = 4 + + +class HeadersParser: + def __init__( + self, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + ) -> None: + self.max_line_size = max_line_size + self.max_headers = max_headers + self.max_field_size = max_field_size + + def parse_headers( + self, lines: List[bytes] + ) -> Tuple["CIMultiDictProxy[str]", RawHeaders]: + headers: CIMultiDict[str] = CIMultiDict() + raw_headers = [] + + lines_idx = 1 + line = lines[1] + line_count = len(lines) + + while line: + # Parse initial header name : value pair. + try: + bname, bvalue = line.split(b":", 1) + except ValueError: + raise InvalidHeader(line) from None + + # https://www.rfc-editor.org/rfc/rfc9112.html#section-5.1-2 + if {bname[0], bname[-1]} & {32, 9}: # {" ", "\t"} + raise InvalidHeader(line) + + bvalue = bvalue.lstrip(b" \t") + if HDRRE.search(bname): + raise InvalidHeader(bname) + if len(bname) > self.max_field_size: + raise LineTooLong( + "request header name {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(len(bname)), + ) + + header_length = len(bvalue) + + # next line + lines_idx += 1 + line = lines[lines_idx] + + # consume continuation lines + continuation = line and line[0] in (32, 9) # (' ', '\t') + + # Deprecated: + # https://www.rfc-editor.org/rfc/rfc9112.html#name-obsolete-line-folding + if continuation: + bvalue_lst = [bvalue] + while continuation: + header_length += len(line) + if header_length > self.max_field_size: + raise LineTooLong( + "request header field {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(header_length), + ) + bvalue_lst.append(line) + + # next line + lines_idx += 1 + if lines_idx < line_count: + line = lines[lines_idx] + if line: + continuation = line[0] in (32, 9) # (' ', '\t') + else: + line = b"" + break + bvalue = b"".join(bvalue_lst) + else: + if header_length > self.max_field_size: + raise LineTooLong( + "request header field {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(header_length), + ) + + bvalue = bvalue.strip(b" \t") + name = bname.decode("utf-8", "surrogateescape") + value = bvalue.decode("utf-8", "surrogateescape") + + # https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-5 + if "\n" in value or "\r" in value or "\x00" in value: + raise InvalidHeader(bvalue) + + headers.add(name, value) + raw_headers.append((bname, bvalue)) + + return (CIMultiDictProxy(headers), tuple(raw_headers)) + + +class HttpParser(abc.ABC, Generic[_MsgT]): + lax: ClassVar[bool] = False + + def __init__( + self, + protocol: Optional[BaseProtocol] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + limit: int = 2**16, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + timer: Optional[BaseTimerContext] = None, + code: Optional[int] = None, + method: Optional[str] = None, + readall: bool = False, + payload_exception: Optional[Type[BaseException]] = None, + response_with_body: bool = True, + read_until_eof: bool = False, + auto_decompress: bool = True, + ) -> None: + self.protocol = protocol + self.loop = loop + self.max_line_size = max_line_size + self.max_headers = max_headers + self.max_field_size = max_field_size + self.timer = timer + self.code = code + self.method = method + self.readall = readall + self.payload_exception = payload_exception + self.response_with_body = response_with_body + self.read_until_eof = read_until_eof + + self._lines: List[bytes] = [] + self._tail = b"" + self._upgraded = False + self._payload = None + self._payload_parser: Optional[HttpPayloadParser] = None + self._auto_decompress = auto_decompress + self._limit = limit + self._headers_parser = HeadersParser(max_line_size, max_headers, max_field_size) + + @abc.abstractmethod + def parse_message(self, lines: List[bytes]) -> _MsgT: + pass + + def feed_eof(self) -> Optional[_MsgT]: + if self._payload_parser is not None: + self._payload_parser.feed_eof() + self._payload_parser = None + else: + # try to extract partial message + if self._tail: + self._lines.append(self._tail) + + if self._lines: + if self._lines[-1] != "\r\n": + self._lines.append(b"") + with suppress(Exception): + return self.parse_message(self._lines) + return None + + def feed_data( + self, + data: bytes, + SEP: _SEP = b"\r\n", + EMPTY: bytes = b"", + CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, + METH_CONNECT: str = hdrs.METH_CONNECT, + SEC_WEBSOCKET_KEY1: istr = hdrs.SEC_WEBSOCKET_KEY1, + ) -> Tuple[List[Tuple[_MsgT, StreamReader]], bool, bytes]: + + messages = [] + + if self._tail: + data, self._tail = self._tail + data, b"" + + data_len = len(data) + start_pos = 0 + loop = self.loop + + while start_pos < data_len: + + # read HTTP message (request/response line + headers), \r\n\r\n + # and split by lines + if self._payload_parser is None and not self._upgraded: + pos = data.find(SEP, start_pos) + # consume \r\n + if pos == start_pos and not self._lines: + start_pos = pos + len(SEP) + continue + + if pos >= start_pos: + # line found + line = data[start_pos:pos] + if SEP == b"\n": # For lax response parsing + line = line.rstrip(b"\r") + self._lines.append(line) + start_pos = pos + len(SEP) + + # \r\n\r\n found + if self._lines[-1] == EMPTY: + try: + msg: _MsgT = self.parse_message(self._lines) + finally: + self._lines.clear() + + def get_content_length() -> Optional[int]: + # payload length + length_hdr = msg.headers.get(CONTENT_LENGTH) + if length_hdr is None: + return None + + # Shouldn't allow +/- or other number formats. + # https://www.rfc-editor.org/rfc/rfc9110#section-8.6-2 + if not length_hdr.strip(" \t").isdecimal(): + raise InvalidHeader(CONTENT_LENGTH) + + return int(length_hdr) + + length = get_content_length() + # do not support old websocket spec + if SEC_WEBSOCKET_KEY1 in msg.headers: + raise InvalidHeader(SEC_WEBSOCKET_KEY1) + + self._upgraded = msg.upgrade + + method = getattr(msg, "method", self.method) + + assert self.protocol is not None + # calculate payload + if ( + (length is not None and length > 0) + or msg.chunked + and not msg.upgrade + ): + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + payload_parser = HttpPayloadParser( + payload, + length=length, + chunked=msg.chunked, + method=method, + compression=msg.compression, + code=self.code, + readall=self.readall, + response_with_body=self.response_with_body, + auto_decompress=self._auto_decompress, + lax=self.lax, + ) + if not payload_parser.done: + self._payload_parser = payload_parser + elif method == METH_CONNECT: + assert isinstance(msg, RawRequestMessage) + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + self._upgraded = True + self._payload_parser = HttpPayloadParser( + payload, + method=msg.method, + compression=msg.compression, + readall=True, + auto_decompress=self._auto_decompress, + lax=self.lax, + ) + else: + if ( + getattr(msg, "code", 100) >= 199 + and length is None + and self.read_until_eof + ): + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + payload_parser = HttpPayloadParser( + payload, + length=length, + chunked=msg.chunked, + method=method, + compression=msg.compression, + code=self.code, + readall=True, + response_with_body=self.response_with_body, + auto_decompress=self._auto_decompress, + lax=self.lax, + ) + if not payload_parser.done: + self._payload_parser = payload_parser + else: + payload = EMPTY_PAYLOAD + + messages.append((msg, payload)) + else: + self._tail = data[start_pos:] + data = EMPTY + break + + # no parser, just store + elif self._payload_parser is None and self._upgraded: + assert not self._lines + break + + # feed payload + elif data and start_pos < data_len: + assert not self._lines + assert self._payload_parser is not None + try: + eof, data = self._payload_parser.feed_data(data[start_pos:], SEP) + except BaseException as exc: + if self.payload_exception is not None: + self._payload_parser.payload.set_exception( + self.payload_exception(str(exc)) + ) + else: + self._payload_parser.payload.set_exception(exc) + + eof = True + data = b"" + + if eof: + start_pos = 0 + data_len = len(data) + self._payload_parser = None + continue + else: + break + + if data and start_pos < data_len: + data = data[start_pos:] + else: + data = EMPTY + + return messages, self._upgraded, data + + def parse_headers( + self, lines: List[bytes] + ) -> Tuple[ + "CIMultiDictProxy[str]", RawHeaders, Optional[bool], Optional[str], bool, bool + ]: + """Parses RFC 5322 headers from a stream. + + Line continuations are supported. Returns list of header name + and value pairs. Header name is in upper case. + """ + headers, raw_headers = self._headers_parser.parse_headers(lines) + close_conn = None + encoding = None + upgrade = False + chunked = False + + # https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-6 + # https://www.rfc-editor.org/rfc/rfc9110.html#name-collected-abnf + singletons = ( + hdrs.CONTENT_LENGTH, + hdrs.CONTENT_LOCATION, + hdrs.CONTENT_RANGE, + hdrs.CONTENT_TYPE, + hdrs.ETAG, + hdrs.HOST, + hdrs.MAX_FORWARDS, + hdrs.SERVER, + hdrs.TRANSFER_ENCODING, + hdrs.USER_AGENT, + ) + bad_hdr = next((h for h in singletons if len(headers.getall(h, ())) > 1), None) + if bad_hdr is not None: + raise BadHttpMessage(f"Duplicate '{bad_hdr}' header found.") + + # keep-alive + conn = headers.get(hdrs.CONNECTION) + if conn: + v = conn.lower() + if v == "close": + close_conn = True + elif v == "keep-alive": + close_conn = False + elif v == "upgrade": + upgrade = True + + # encoding + enc = headers.get(hdrs.CONTENT_ENCODING) + if enc: + enc = enc.lower() + if enc in ("gzip", "deflate", "br"): + encoding = enc + + # chunking + te = headers.get(hdrs.TRANSFER_ENCODING) + if te is not None: + if "chunked" == te.lower(): + chunked = True + else: + raise BadHttpMessage("Request has invalid `Transfer-Encoding`") + + if hdrs.CONTENT_LENGTH in headers: + raise BadHttpMessage( + "Transfer-Encoding can't be present with Content-Length", + ) + + return (headers, raw_headers, close_conn, encoding, upgrade, chunked) + + def set_upgraded(self, val: bool) -> None: + """Set connection upgraded (to websocket) mode. + + :param bool val: new state. + """ + self._upgraded = val + + +class HttpRequestParser(HttpParser[RawRequestMessage]): + """Read request status line. + + Exception .http_exceptions.BadStatusLine + could be raised in case of any errors in status line. + Returns RawRequestMessage. + """ + + def parse_message(self, lines: List[bytes]) -> RawRequestMessage: + # request line + line = lines[0].decode("utf-8", "surrogateescape") + try: + method, path, version = line.split(maxsplit=2) + except ValueError: + raise BadStatusLine(line) from None + + if len(path) > self.max_line_size: + raise LineTooLong( + "Status line is too long", str(self.max_line_size), str(len(path)) + ) + + # method + if not METHRE.match(method): + raise BadStatusLine(method) + + # version + match = VERSRE.match(version) + if match is None: + raise BadStatusLine(line) + version_o = HttpVersion(int(match.group(1)), int(match.group(2))) + + if method == "CONNECT": + # authority-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3 + url = URL.build(authority=path, encoded=True) + elif path.startswith("/"): + # origin-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.1 + path_part, _hash_separator, url_fragment = path.partition("#") + path_part, _question_mark_separator, qs_part = path_part.partition("?") + + # NOTE: `yarl.URL.build()` is used to mimic what the Cython-based + # NOTE: parser does, otherwise it results into the same + # NOTE: HTTP Request-Line input producing different + # NOTE: `yarl.URL()` objects + url = URL.build( + path=path_part, + query_string=qs_part, + fragment=url_fragment, + encoded=True, + ) + else: + # absolute-form for proxy maybe, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2 + url = URL(path, encoded=True) + + # read headers + ( + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) = self.parse_headers(lines) + + if close is None: # then the headers weren't set in the request + if version_o <= HttpVersion10: # HTTP 1.0 must asks to not close + close = True + else: # HTTP 1.1 must ask to close. + close = False + + return RawRequestMessage( + method, + path, + version_o, + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + url, + ) + + +class HttpResponseParser(HttpParser[RawResponseMessage]): + """Read response status line and headers. + + BadStatusLine could be raised in case of any errors in status line. + Returns RawResponseMessage. + """ + + # Lax mode should only be enabled on response parser. + lax = not DEBUG + + def feed_data( + self, + data: bytes, + SEP: Optional[_SEP] = None, + *args: Any, + **kwargs: Any, + ) -> Tuple[List[Tuple[RawResponseMessage, StreamReader]], bool, bytes]: + if SEP is None: + SEP = b"\r\n" if DEBUG else b"\n" + return super().feed_data(data, SEP, *args, **kwargs) + + def parse_message(self, lines: List[bytes]) -> RawResponseMessage: + line = lines[0].decode("utf-8", "surrogateescape") + try: + version, status = line.split(maxsplit=1) + except ValueError: + raise BadStatusLine(line) from None + + try: + status, reason = status.split(maxsplit=1) + except ValueError: + reason = "" + + if len(reason) > self.max_line_size: + raise LineTooLong( + "Status line is too long", str(self.max_line_size), str(len(reason)) + ) + + # version + match = VERSRE.match(version) + if match is None: + raise BadStatusLine(line) + version_o = HttpVersion(int(match.group(1)), int(match.group(2))) + + # The status code is a three-digit number + if len(status) != 3 or not status.isdecimal(): + raise BadStatusLine(line) + status_i = int(status) + + # read headers + ( + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) = self.parse_headers(lines) + + if close is None: + close = version_o <= HttpVersion10 + + return RawResponseMessage( + version_o, + status_i, + reason.strip(), + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) + + +class HttpPayloadParser: + def __init__( + self, + payload: StreamReader, + length: Optional[int] = None, + chunked: bool = False, + compression: Optional[str] = None, + code: Optional[int] = None, + method: Optional[str] = None, + readall: bool = False, + response_with_body: bool = True, + auto_decompress: bool = True, + lax: bool = False, + ) -> None: + self._length = 0 + self._type = ParseState.PARSE_NONE + self._chunk = ChunkState.PARSE_CHUNKED_SIZE + self._chunk_size = 0 + self._chunk_tail = b"" + self._auto_decompress = auto_decompress + self._lax = lax + self.done = False + + # payload decompression wrapper + if response_with_body and compression and self._auto_decompress: + real_payload: Union[StreamReader, DeflateBuffer] = DeflateBuffer( + payload, compression + ) + else: + real_payload = payload + + # payload parser + if not response_with_body: + # don't parse payload if it's not expected to be received + self._type = ParseState.PARSE_NONE + real_payload.feed_eof() + self.done = True + + elif chunked: + self._type = ParseState.PARSE_CHUNKED + elif length is not None: + self._type = ParseState.PARSE_LENGTH + self._length = length + if self._length == 0: + real_payload.feed_eof() + self.done = True + else: + if readall and code != 204: + self._type = ParseState.PARSE_UNTIL_EOF + elif method in ("PUT", "POST"): + internal_logger.warning( # pragma: no cover + "Content-Length or Transfer-Encoding header is required" + ) + self._type = ParseState.PARSE_NONE + real_payload.feed_eof() + self.done = True + + self.payload = real_payload + + def feed_eof(self) -> None: + if self._type == ParseState.PARSE_UNTIL_EOF: + self.payload.feed_eof() + elif self._type == ParseState.PARSE_LENGTH: + raise ContentLengthError( + "Not enough data for satisfy content length header." + ) + elif self._type == ParseState.PARSE_CHUNKED: + raise TransferEncodingError( + "Not enough data for satisfy transfer length header." + ) + + def feed_data( + self, chunk: bytes, SEP: _SEP = b"\r\n", CHUNK_EXT: bytes = b";" + ) -> Tuple[bool, bytes]: + # Read specified amount of bytes + if self._type == ParseState.PARSE_LENGTH: + required = self._length + chunk_len = len(chunk) + + if required >= chunk_len: + self._length = required - chunk_len + self.payload.feed_data(chunk, chunk_len) + if self._length == 0: + self.payload.feed_eof() + return True, b"" + else: + self._length = 0 + self.payload.feed_data(chunk[:required], required) + self.payload.feed_eof() + return True, chunk[required:] + + # Chunked transfer encoding parser + elif self._type == ParseState.PARSE_CHUNKED: + if self._chunk_tail: + chunk = self._chunk_tail + chunk + self._chunk_tail = b"" + + while chunk: + + # read next chunk size + if self._chunk == ChunkState.PARSE_CHUNKED_SIZE: + pos = chunk.find(SEP) + if pos >= 0: + i = chunk.find(CHUNK_EXT, 0, pos) + if i >= 0: + size_b = chunk[:i] # strip chunk-extensions + else: + size_b = chunk[:pos] + + if self._lax: # Allow whitespace in lax mode. + size_b = size_b.strip() + + if not re.fullmatch(HEXDIGIT, size_b): + exc = TransferEncodingError( + chunk[:pos].decode("ascii", "surrogateescape") + ) + self.payload.set_exception(exc) + raise exc + size = int(bytes(size_b), 16) + + chunk = chunk[pos + len(SEP) :] + if size == 0: # eof marker + self._chunk = ChunkState.PARSE_MAYBE_TRAILERS + if self._lax and chunk.startswith(b"\r"): + chunk = chunk[1:] + else: + self._chunk = ChunkState.PARSE_CHUNKED_CHUNK + self._chunk_size = size + self.payload.begin_http_chunk_receiving() + else: + self._chunk_tail = chunk + return False, b"" + + # read chunk and feed buffer + if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK: + required = self._chunk_size + chunk_len = len(chunk) + + if required > chunk_len: + self._chunk_size = required - chunk_len + self.payload.feed_data(chunk, chunk_len) + return False, b"" + else: + self._chunk_size = 0 + self.payload.feed_data(chunk[:required], required) + chunk = chunk[required:] + if self._lax and chunk.startswith(b"\r"): + chunk = chunk[1:] + self._chunk = ChunkState.PARSE_CHUNKED_CHUNK_EOF + self.payload.end_http_chunk_receiving() + + # toss the CRLF at the end of the chunk + if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK_EOF: + if chunk[: len(SEP)] == SEP: + chunk = chunk[len(SEP) :] + self._chunk = ChunkState.PARSE_CHUNKED_SIZE + else: + self._chunk_tail = chunk + return False, b"" + + # if stream does not contain trailer, after 0\r\n + # we should get another \r\n otherwise + # trailers needs to be skiped until \r\n\r\n + if self._chunk == ChunkState.PARSE_MAYBE_TRAILERS: + head = chunk[: len(SEP)] + if head == SEP: + # end of stream + self.payload.feed_eof() + return True, chunk[len(SEP) :] + # Both CR and LF, or only LF may not be received yet. It is + # expected that CRLF or LF will be shown at the very first + # byte next time, otherwise trailers should come. The last + # CRLF which marks the end of response might not be + # contained in the same TCP segment which delivered the + # size indicator. + if not head: + return False, b"" + if head == SEP[:1]: + self._chunk_tail = head + return False, b"" + self._chunk = ChunkState.PARSE_TRAILERS + + # read and discard trailer up to the CRLF terminator + if self._chunk == ChunkState.PARSE_TRAILERS: + pos = chunk.find(SEP) + if pos >= 0: + chunk = chunk[pos + len(SEP) :] + self._chunk = ChunkState.PARSE_MAYBE_TRAILERS + else: + self._chunk_tail = chunk + return False, b"" + + # Read all bytes until eof + elif self._type == ParseState.PARSE_UNTIL_EOF: + self.payload.feed_data(chunk, len(chunk)) + + return False, b"" + + +class DeflateBuffer: + """DeflateStream decompress stream and feed data into specified stream.""" + + decompressor: Any + + def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: + self.out = out + self.size = 0 + self.encoding = encoding + self._started_decoding = False + + if encoding == "br": + if not HAS_BROTLI: # pragma: no cover + raise ContentEncodingError( + "Can not decode content-encoding: brotli (br). " + "Please install `Brotli`" + ) + + class BrotliDecoder: + # Supports both 'brotlipy' and 'Brotli' packages + # since they share an import name. The top branches + # are for 'brotlipy' and bottom branches for 'Brotli' + def __init__(self) -> None: + self._obj = brotli.Decompressor() + + def decompress(self, data: bytes) -> bytes: + if hasattr(self._obj, "decompress"): + return cast(bytes, self._obj.decompress(data)) + return cast(bytes, self._obj.process(data)) + + def flush(self) -> bytes: + if hasattr(self._obj, "flush"): + return cast(bytes, self._obj.flush()) + return b"" + + self.decompressor = BrotliDecoder() + else: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS + self.decompressor = zlib.decompressobj(wbits=zlib_mode) + + def set_exception(self, exc: BaseException) -> None: + self.out.set_exception(exc) + + def feed_data(self, chunk: bytes, size: int) -> None: + if not size: + return + + self.size += size + + # RFC1950 + # bits 0..3 = CM = 0b1000 = 8 = "deflate" + # bits 4..7 = CINFO = 1..7 = windows size. + if ( + not self._started_decoding + and self.encoding == "deflate" + and chunk[0] & 0xF != 8 + ): + # Change the decoder to decompress incorrectly compressed data + # Actually we should issue a warning about non-RFC-compliant data. + self.decompressor = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + + try: + chunk = self.decompressor.decompress(chunk) + except Exception: + raise ContentEncodingError( + "Can not decode content-encoding: %s" % self.encoding + ) + + self._started_decoding = True + + if chunk: + self.out.feed_data(chunk, len(chunk)) + + def feed_eof(self) -> None: + chunk = self.decompressor.flush() + + if chunk or self.size > 0: + self.out.feed_data(chunk, len(chunk)) + if self.encoding == "deflate" and not self.decompressor.eof: + raise ContentEncodingError("deflate") + + self.out.feed_eof() + + def begin_http_chunk_receiving(self) -> None: + self.out.begin_http_chunk_receiving() + + def end_http_chunk_receiving(self) -> None: + self.out.end_http_chunk_receiving() + + +HttpRequestParserPy = HttpRequestParser +HttpResponseParserPy = HttpResponseParser +RawRequestMessagePy = RawRequestMessage +RawResponseMessagePy = RawResponseMessage + +try: + if not NO_EXTENSIONS: + from ._http_parser import ( # type: ignore[import,no-redef] + HttpRequestParser, + HttpResponseParser, + RawRequestMessage, + RawResponseMessage, + ) + + HttpRequestParserC = HttpRequestParser + HttpResponseParserC = HttpResponseParser + RawRequestMessageC = RawRequestMessage + RawResponseMessageC = RawResponseMessage +except ImportError: # pragma: no cover + pass diff --git a/.venv/lib/python3.7/site-packages/aiohttp/http_websocket.py b/.venv/lib/python3.7/site-packages/aiohttp/http_websocket.py new file mode 100644 index 0000000..2cfc519 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/http_websocket.py @@ -0,0 +1,701 @@ +"""WebSocket protocol versions 13 and 8.""" + +import asyncio +import collections +import json +import random +import re +import sys +import zlib +from enum import IntEnum +from struct import Struct +from typing import Any, Callable, List, Optional, Pattern, Set, Tuple, Union, cast + +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS +from .streams import DataQueue +from .typedefs import Final + +__all__ = ( + "WS_CLOSED_MESSAGE", + "WS_CLOSING_MESSAGE", + "WS_KEY", + "WebSocketReader", + "WebSocketWriter", + "WSMessage", + "WebSocketError", + "WSMsgType", + "WSCloseCode", +) + + +class WSCloseCode(IntEnum): + OK = 1000 + GOING_AWAY = 1001 + PROTOCOL_ERROR = 1002 + UNSUPPORTED_DATA = 1003 + ABNORMAL_CLOSURE = 1006 + INVALID_TEXT = 1007 + POLICY_VIOLATION = 1008 + MESSAGE_TOO_BIG = 1009 + MANDATORY_EXTENSION = 1010 + INTERNAL_ERROR = 1011 + SERVICE_RESTART = 1012 + TRY_AGAIN_LATER = 1013 + BAD_GATEWAY = 1014 + + +ALLOWED_CLOSE_CODES: Final[Set[int]] = {int(i) for i in WSCloseCode} + + +class WSMsgType(IntEnum): + # websocket spec types + CONTINUATION = 0x0 + TEXT = 0x1 + BINARY = 0x2 + PING = 0x9 + PONG = 0xA + CLOSE = 0x8 + + # aiohttp specific types + CLOSING = 0x100 + CLOSED = 0x101 + ERROR = 0x102 + + text = TEXT + binary = BINARY + ping = PING + pong = PONG + close = CLOSE + closing = CLOSING + closed = CLOSED + error = ERROR + + +WS_KEY: Final[bytes] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + + +UNPACK_LEN2 = Struct("!H").unpack_from +UNPACK_LEN3 = Struct("!Q").unpack_from +UNPACK_CLOSE_CODE = Struct("!H").unpack +PACK_LEN1 = Struct("!BB").pack +PACK_LEN2 = Struct("!BBH").pack +PACK_LEN3 = Struct("!BBQ").pack +PACK_CLOSE_CODE = Struct("!H").pack +MSG_SIZE: Final[int] = 2**14 +DEFAULT_LIMIT: Final[int] = 2**16 + + +_WSMessageBase = collections.namedtuple("_WSMessageBase", ["type", "data", "extra"]) + + +class WSMessage(_WSMessageBase): + def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any: + """Return parsed JSON data. + + .. versionadded:: 0.22 + """ + return loads(self.data) + + +WS_CLOSED_MESSAGE = WSMessage(WSMsgType.CLOSED, None, None) +WS_CLOSING_MESSAGE = WSMessage(WSMsgType.CLOSING, None, None) + + +class WebSocketError(Exception): + """WebSocket protocol parser error.""" + + def __init__(self, code: int, message: str) -> None: + self.code = code + super().__init__(code, message) + + def __str__(self) -> str: + return cast(str, self.args[1]) + + +class WSHandshakeError(Exception): + """WebSocket protocol handshake error.""" + + +native_byteorder: Final[str] = sys.byteorder + + +# Used by _websocket_mask_python +_XOR_TABLE: Final[List[bytes]] = [bytes(a ^ b for a in range(256)) for b in range(256)] + + +def _websocket_mask_python(mask: bytes, data: bytearray) -> None: + """Websocket masking function. + + `mask` is a `bytes` object of length 4; `data` is a `bytearray` + object of any length. The contents of `data` are masked with `mask`, + as specified in section 5.3 of RFC 6455. + + Note that this function mutates the `data` argument. + + This pure-python implementation may be replaced by an optimized + version when available. + + """ + assert isinstance(data, bytearray), data + assert len(mask) == 4, mask + + if data: + a, b, c, d = (_XOR_TABLE[n] for n in mask) + data[::4] = data[::4].translate(a) + data[1::4] = data[1::4].translate(b) + data[2::4] = data[2::4].translate(c) + data[3::4] = data[3::4].translate(d) + + +if NO_EXTENSIONS: # pragma: no cover + _websocket_mask = _websocket_mask_python +else: + try: + from ._websocket import _websocket_mask_cython # type: ignore[import] + + _websocket_mask = _websocket_mask_cython + except ImportError: # pragma: no cover + _websocket_mask = _websocket_mask_python + +_WS_DEFLATE_TRAILING: Final[bytes] = bytes([0x00, 0x00, 0xFF, 0xFF]) + + +_WS_EXT_RE: Final[Pattern[str]] = re.compile( + r"^(?:;\s*(?:" + r"(server_no_context_takeover)|" + r"(client_no_context_takeover)|" + r"(server_max_window_bits(?:=(\d+))?)|" + r"(client_max_window_bits(?:=(\d+))?)))*$" +) + +_WS_EXT_RE_SPLIT: Final[Pattern[str]] = re.compile(r"permessage-deflate([^,]+)?") + + +def ws_ext_parse(extstr: Optional[str], isserver: bool = False) -> Tuple[int, bool]: + if not extstr: + return 0, False + + compress = 0 + notakeover = False + for ext in _WS_EXT_RE_SPLIT.finditer(extstr): + defext = ext.group(1) + # Return compress = 15 when get `permessage-deflate` + if not defext: + compress = 15 + break + match = _WS_EXT_RE.match(defext) + if match: + compress = 15 + if isserver: + # Server never fail to detect compress handshake. + # Server does not need to send max wbit to client + if match.group(4): + compress = int(match.group(4)) + # Group3 must match if group4 matches + # Compress wbit 8 does not support in zlib + # If compress level not support, + # CONTINUE to next extension + if compress > 15 or compress < 9: + compress = 0 + continue + if match.group(1): + notakeover = True + # Ignore regex group 5 & 6 for client_max_window_bits + break + else: + if match.group(6): + compress = int(match.group(6)) + # Group5 must match if group6 matches + # Compress wbit 8 does not support in zlib + # If compress level not support, + # FAIL the parse progress + if compress > 15 or compress < 9: + raise WSHandshakeError("Invalid window size") + if match.group(2): + notakeover = True + # Ignore regex group 5 & 6 for client_max_window_bits + break + # Return Fail if client side and not match + elif not isserver: + raise WSHandshakeError("Extension for deflate not supported" + ext.group(1)) + + return compress, notakeover + + +def ws_ext_gen( + compress: int = 15, isserver: bool = False, server_notakeover: bool = False +) -> str: + # client_notakeover=False not used for server + # compress wbit 8 does not support in zlib + if compress < 9 or compress > 15: + raise ValueError( + "Compress wbits must between 9 and 15, " "zlib does not support wbits=8" + ) + enabledext = ["permessage-deflate"] + if not isserver: + enabledext.append("client_max_window_bits") + + if compress < 15: + enabledext.append("server_max_window_bits=" + str(compress)) + if server_notakeover: + enabledext.append("server_no_context_takeover") + # if client_notakeover: + # enabledext.append('client_no_context_takeover') + return "; ".join(enabledext) + + +class WSParserState(IntEnum): + READ_HEADER = 1 + READ_PAYLOAD_LENGTH = 2 + READ_PAYLOAD_MASK = 3 + READ_PAYLOAD = 4 + + +class WebSocketReader: + def __init__( + self, queue: DataQueue[WSMessage], max_msg_size: int, compress: bool = True + ) -> None: + self.queue = queue + self._max_msg_size = max_msg_size + + self._exc: Optional[BaseException] = None + self._partial = bytearray() + self._state = WSParserState.READ_HEADER + + self._opcode: Optional[int] = None + self._frame_fin = False + self._frame_opcode: Optional[int] = None + self._frame_payload = bytearray() + + self._tail = b"" + self._has_mask = False + self._frame_mask: Optional[bytes] = None + self._payload_length = 0 + self._payload_length_flag = 0 + self._compressed: Optional[bool] = None + self._decompressobj: Any = None # zlib.decompressobj actually + self._compress = compress + + def feed_eof(self) -> None: + self.queue.feed_eof() + + def feed_data(self, data: bytes) -> Tuple[bool, bytes]: + if self._exc: + return True, data + + try: + return self._feed_data(data) + except Exception as exc: + self._exc = exc + self.queue.set_exception(exc) + return True, b"" + + def _feed_data(self, data: bytes) -> Tuple[bool, bytes]: + for fin, opcode, payload, compressed in self.parse_frame(data): + if compressed and not self._decompressobj: + self._decompressobj = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + if opcode == WSMsgType.CLOSE: + if len(payload) >= 2: + close_code = UNPACK_CLOSE_CODE(payload[:2])[0] + if close_code < 3000 and close_code not in ALLOWED_CLOSE_CODES: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + f"Invalid close code: {close_code}", + ) + try: + close_message = payload[2:].decode("utf-8") + except UnicodeDecodeError as exc: + raise WebSocketError( + WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message" + ) from exc + msg = WSMessage(WSMsgType.CLOSE, close_code, close_message) + elif payload: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + f"Invalid close frame: {fin} {opcode} {payload!r}", + ) + else: + msg = WSMessage(WSMsgType.CLOSE, 0, "") + + self.queue.feed_data(msg, 0) + + elif opcode == WSMsgType.PING: + self.queue.feed_data( + WSMessage(WSMsgType.PING, payload, ""), len(payload) + ) + + elif opcode == WSMsgType.PONG: + self.queue.feed_data( + WSMessage(WSMsgType.PONG, payload, ""), len(payload) + ) + + elif ( + opcode not in (WSMsgType.TEXT, WSMsgType.BINARY) + and self._opcode is None + ): + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, f"Unexpected opcode={opcode!r}" + ) + else: + # load text/binary + if not fin: + # got partial frame payload + if opcode != WSMsgType.CONTINUATION: + self._opcode = opcode + self._partial.extend(payload) + if self._max_msg_size and len(self._partial) >= self._max_msg_size: + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Message size {} exceeds limit {}".format( + len(self._partial), self._max_msg_size + ), + ) + else: + # previous frame was non finished + # we should get continuation opcode + if self._partial: + if opcode != WSMsgType.CONTINUATION: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "The opcode in non-fin frame is expected " + "to be zero, got {!r}".format(opcode), + ) + + if opcode == WSMsgType.CONTINUATION: + assert self._opcode is not None + opcode = self._opcode + self._opcode = None + + self._partial.extend(payload) + if self._max_msg_size and len(self._partial) >= self._max_msg_size: + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Message size {} exceeds limit {}".format( + len(self._partial), self._max_msg_size + ), + ) + + # Decompress process must to be done after all packets + # received. + if compressed: + self._partial.extend(_WS_DEFLATE_TRAILING) + payload_merged = self._decompressobj.decompress( + self._partial, self._max_msg_size + ) + if self._decompressobj.unconsumed_tail: + left = len(self._decompressobj.unconsumed_tail) + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Decompressed message size {} exceeds limit {}".format( + self._max_msg_size + left, self._max_msg_size + ), + ) + else: + payload_merged = bytes(self._partial) + + self._partial.clear() + + if opcode == WSMsgType.TEXT: + try: + text = payload_merged.decode("utf-8") + self.queue.feed_data( + WSMessage(WSMsgType.TEXT, text, ""), len(text) + ) + except UnicodeDecodeError as exc: + raise WebSocketError( + WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message" + ) from exc + else: + self.queue.feed_data( + WSMessage(WSMsgType.BINARY, payload_merged, ""), + len(payload_merged), + ) + + return False, b"" + + def parse_frame( + self, buf: bytes + ) -> List[Tuple[bool, Optional[int], bytearray, Optional[bool]]]: + """Return the next frame from the socket.""" + frames = [] + if self._tail: + buf, self._tail = self._tail + buf, b"" + + start_pos = 0 + buf_length = len(buf) + + while True: + # read header + if self._state == WSParserState.READ_HEADER: + if buf_length - start_pos >= 2: + data = buf[start_pos : start_pos + 2] + start_pos += 2 + first_byte, second_byte = data + + fin = (first_byte >> 7) & 1 + rsv1 = (first_byte >> 6) & 1 + rsv2 = (first_byte >> 5) & 1 + rsv3 = (first_byte >> 4) & 1 + opcode = first_byte & 0xF + + # frame-fin = %x0 ; more frames of this message follow + # / %x1 ; final frame of this message + # frame-rsv1 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # frame-rsv2 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # frame-rsv3 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # + # Remove rsv1 from this test for deflate development + if rsv2 or rsv3 or (rsv1 and not self._compress): + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received frame with non-zero reserved bits", + ) + + if opcode > 0x7 and fin == 0: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received fragmented control frame", + ) + + has_mask = (second_byte >> 7) & 1 + length = second_byte & 0x7F + + # Control frames MUST have a payload + # length of 125 bytes or less + if opcode > 0x7 and length > 125: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Control frame payload cannot be " "larger than 125 bytes", + ) + + # Set compress status if last package is FIN + # OR set compress status if this is first fragment + # Raise error if not first fragment with rsv1 = 0x1 + if self._frame_fin or self._compressed is None: + self._compressed = True if rsv1 else False + elif rsv1: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received frame with non-zero reserved bits", + ) + + self._frame_fin = bool(fin) + self._frame_opcode = opcode + self._has_mask = bool(has_mask) + self._payload_length_flag = length + self._state = WSParserState.READ_PAYLOAD_LENGTH + else: + break + + # read payload length + if self._state == WSParserState.READ_PAYLOAD_LENGTH: + length = self._payload_length_flag + if length == 126: + if buf_length - start_pos >= 2: + data = buf[start_pos : start_pos + 2] + start_pos += 2 + length = UNPACK_LEN2(data)[0] + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + else: + break + elif length > 126: + if buf_length - start_pos >= 8: + data = buf[start_pos : start_pos + 8] + start_pos += 8 + length = UNPACK_LEN3(data)[0] + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + else: + break + else: + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + + # read payload mask + if self._state == WSParserState.READ_PAYLOAD_MASK: + if buf_length - start_pos >= 4: + self._frame_mask = buf[start_pos : start_pos + 4] + start_pos += 4 + self._state = WSParserState.READ_PAYLOAD + else: + break + + if self._state == WSParserState.READ_PAYLOAD: + length = self._payload_length + payload = self._frame_payload + + chunk_len = buf_length - start_pos + if length >= chunk_len: + self._payload_length = length - chunk_len + payload.extend(buf[start_pos:]) + start_pos = buf_length + else: + self._payload_length = 0 + payload.extend(buf[start_pos : start_pos + length]) + start_pos = start_pos + length + + if self._payload_length == 0: + if self._has_mask: + assert self._frame_mask is not None + _websocket_mask(self._frame_mask, payload) + + frames.append( + (self._frame_fin, self._frame_opcode, payload, self._compressed) + ) + + self._frame_payload = bytearray() + self._state = WSParserState.READ_HEADER + else: + break + + self._tail = buf[start_pos:] + + return frames + + +class WebSocketWriter: + def __init__( + self, + protocol: BaseProtocol, + transport: asyncio.Transport, + *, + use_mask: bool = False, + limit: int = DEFAULT_LIMIT, + random: Any = random.Random(), + compress: int = 0, + notakeover: bool = False, + ) -> None: + self.protocol = protocol + self.transport = transport + self.use_mask = use_mask + self.randrange = random.randrange + self.compress = compress + self.notakeover = notakeover + self._closing = False + self._limit = limit + self._output_size = 0 + self._compressobj: Any = None # actually compressobj + + async def _send_frame( + self, message: bytes, opcode: int, compress: Optional[int] = None + ) -> None: + """Send a frame over the websocket with message as its payload.""" + if self._closing and not (opcode & WSMsgType.CLOSE): + raise ConnectionResetError("Cannot write to closing transport") + + rsv = 0 + + # Only compress larger packets (disabled) + # Does small packet needs to be compressed? + # if self.compress and opcode < 8 and len(message) > 124: + if (compress or self.compress) and opcode < 8: + if compress: + # Do not set self._compress if compressing is for this frame + compressobj = zlib.compressobj(level=zlib.Z_BEST_SPEED, wbits=-compress) + else: # self.compress + if not self._compressobj: + self._compressobj = zlib.compressobj( + level=zlib.Z_BEST_SPEED, wbits=-self.compress + ) + compressobj = self._compressobj + + message = compressobj.compress(message) + message = message + compressobj.flush( + zlib.Z_FULL_FLUSH if self.notakeover else zlib.Z_SYNC_FLUSH + ) + if message.endswith(_WS_DEFLATE_TRAILING): + message = message[:-4] + rsv = rsv | 0x40 + + msg_length = len(message) + + use_mask = self.use_mask + if use_mask: + mask_bit = 0x80 + else: + mask_bit = 0 + + if msg_length < 126: + header = PACK_LEN1(0x80 | rsv | opcode, msg_length | mask_bit) + elif msg_length < (1 << 16): + header = PACK_LEN2(0x80 | rsv | opcode, 126 | mask_bit, msg_length) + else: + header = PACK_LEN3(0x80 | rsv | opcode, 127 | mask_bit, msg_length) + if use_mask: + mask = self.randrange(0, 0xFFFFFFFF) + mask = mask.to_bytes(4, "big") + message = bytearray(message) + _websocket_mask(mask, message) + self._write(header + mask + message) + self._output_size += len(header) + len(mask) + len(message) + else: + if len(message) > MSG_SIZE: + self._write(header) + self._write(message) + else: + self._write(header + message) + + self._output_size += len(header) + len(message) + + if self._output_size > self._limit: + self._output_size = 0 + await self.protocol._drain_helper() + + def _write(self, data: bytes) -> None: + if self.transport is None or self.transport.is_closing(): + raise ConnectionResetError("Cannot write to closing transport") + self.transport.write(data) + + async def pong(self, message: bytes = b"") -> None: + """Send pong message.""" + if isinstance(message, str): + message = message.encode("utf-8") + await self._send_frame(message, WSMsgType.PONG) + + async def ping(self, message: bytes = b"") -> None: + """Send ping message.""" + if isinstance(message, str): + message = message.encode("utf-8") + await self._send_frame(message, WSMsgType.PING) + + async def send( + self, + message: Union[str, bytes], + binary: bool = False, + compress: Optional[int] = None, + ) -> None: + """Send a frame over the websocket with message as its payload.""" + if isinstance(message, str): + message = message.encode("utf-8") + if binary: + await self._send_frame(message, WSMsgType.BINARY, compress) + else: + await self._send_frame(message, WSMsgType.TEXT, compress) + + async def close(self, code: int = 1000, message: bytes = b"") -> None: + """Close the websocket, sending the specified code and message.""" + if isinstance(message, str): + message = message.encode("utf-8") + try: + await self._send_frame( + PACK_CLOSE_CODE(code) + message, opcode=WSMsgType.CLOSE + ) + finally: + self._closing = True diff --git a/.venv/lib/python3.7/site-packages/aiohttp/http_writer.py b/.venv/lib/python3.7/site-packages/aiohttp/http_writer.py new file mode 100644 index 0000000..73f0f96 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/http_writer.py @@ -0,0 +1,198 @@ +"""Http related parsers and protocol.""" + +import asyncio +import zlib +from typing import Any, Awaitable, Callable, NamedTuple, Optional, Union # noqa + +from multidict import CIMultiDict + +from .abc import AbstractStreamWriter +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS + +__all__ = ("StreamWriter", "HttpVersion", "HttpVersion10", "HttpVersion11") + + +class HttpVersion(NamedTuple): + major: int + minor: int + + +HttpVersion10 = HttpVersion(1, 0) +HttpVersion11 = HttpVersion(1, 1) + + +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] +_T_OnHeadersSent = Optional[Callable[["CIMultiDict[str]"], Awaitable[None]]] + + +class StreamWriter(AbstractStreamWriter): + def __init__( + self, + protocol: BaseProtocol, + loop: asyncio.AbstractEventLoop, + on_chunk_sent: _T_OnChunkSent = None, + on_headers_sent: _T_OnHeadersSent = None, + ) -> None: + self._protocol = protocol + + self.loop = loop + self.length = None + self.chunked = False + self.buffer_size = 0 + self.output_size = 0 + + self._eof = False + self._compress: Any = None + self._drain_waiter = None + + self._on_chunk_sent: _T_OnChunkSent = on_chunk_sent + self._on_headers_sent: _T_OnHeadersSent = on_headers_sent + + @property + def transport(self) -> Optional[asyncio.Transport]: + return self._protocol.transport + + @property + def protocol(self) -> BaseProtocol: + return self._protocol + + def enable_chunking(self) -> None: + self.chunked = True + + def enable_compression( + self, encoding: str = "deflate", strategy: int = zlib.Z_DEFAULT_STRATEGY + ) -> None: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS + self._compress = zlib.compressobj(wbits=zlib_mode, strategy=strategy) + + def _write(self, chunk: bytes) -> None: + size = len(chunk) + self.buffer_size += size + self.output_size += size + transport = self.transport + if not self._protocol.connected or transport is None or transport.is_closing(): + raise ConnectionResetError("Cannot write to closing transport") + transport.write(chunk) + + async def write( + self, chunk: bytes, *, drain: bool = True, LIMIT: int = 0x10000 + ) -> None: + """Writes chunk of data to a stream. + + write_eof() indicates end of stream. + writer can't be used after write_eof() method being called. + write() return drain future. + """ + if self._on_chunk_sent is not None: + await self._on_chunk_sent(chunk) + + if isinstance(chunk, memoryview): + if chunk.nbytes != len(chunk): + # just reshape it + chunk = chunk.cast("c") + + if self._compress is not None: + chunk = self._compress.compress(chunk) + if not chunk: + return + + if self.length is not None: + chunk_len = len(chunk) + if self.length >= chunk_len: + self.length = self.length - chunk_len + else: + chunk = chunk[: self.length] + self.length = 0 + if not chunk: + return + + if chunk: + if self.chunked: + chunk_len_pre = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len_pre + chunk + b"\r\n" + + self._write(chunk) + + if self.buffer_size > LIMIT and drain: + self.buffer_size = 0 + await self.drain() + + async def write_headers( + self, status_line: str, headers: "CIMultiDict[str]" + ) -> None: + """Write request/response status and headers.""" + if self._on_headers_sent is not None: + await self._on_headers_sent(headers) + + # status + headers + buf = _serialize_headers(status_line, headers) + self._write(buf) + + async def write_eof(self, chunk: bytes = b"") -> None: + if self._eof: + return + + if chunk and self._on_chunk_sent is not None: + await self._on_chunk_sent(chunk) + + if self._compress: + if chunk: + chunk = self._compress.compress(chunk) + + chunk = chunk + self._compress.flush() + if chunk and self.chunked: + chunk_len = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len + chunk + b"\r\n0\r\n\r\n" + else: + if self.chunked: + if chunk: + chunk_len = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len + chunk + b"\r\n0\r\n\r\n" + else: + chunk = b"0\r\n\r\n" + + if chunk: + self._write(chunk) + + await self.drain() + + self._eof = True + + async def drain(self) -> None: + """Flush the write buffer. + + The intended use is to write + + await w.write(data) + await w.drain() + """ + if self._protocol.transport is not None: + await self._protocol._drain_helper() + + +def _safe_header(string: str) -> str: + if "\r" in string or "\n" in string: + raise ValueError( + "Newline or carriage return detected in headers. " + "Potential header injection attack." + ) + return string + + +def _py_serialize_headers(status_line: str, headers: "CIMultiDict[str]") -> bytes: + headers_gen = (_safe_header(k) + ": " + _safe_header(v) for k, v in headers.items()) + line = status_line + "\r\n" + "\r\n".join(headers_gen) + "\r\n\r\n" + return line.encode("utf-8") + + +_serialize_headers = _py_serialize_headers + +try: + import aiohttp._http_writer as _http_writer # type: ignore[import] + + _c_serialize_headers = _http_writer._serialize_headers + if not NO_EXTENSIONS: + _serialize_headers = _c_serialize_headers +except ImportError: + pass diff --git a/.venv/lib/python3.7/site-packages/aiohttp/locks.py b/.venv/lib/python3.7/site-packages/aiohttp/locks.py new file mode 100644 index 0000000..de2dc83 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/locks.py @@ -0,0 +1,41 @@ +import asyncio +import collections +from typing import Any, Deque, Optional + + +class EventResultOrError: + """Event asyncio lock helper class. + + Wraps the Event asyncio lock allowing either to awake the + locked Tasks without any error or raising an exception. + + thanks to @vorpalsmith for the simple design. + """ + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._exc: Optional[BaseException] = None + self._event = asyncio.Event() + self._waiters: Deque[asyncio.Future[Any]] = collections.deque() + + def set(self, exc: Optional[BaseException] = None) -> None: + self._exc = exc + self._event.set() + + async def wait(self) -> Any: + waiter = self._loop.create_task(self._event.wait()) + self._waiters.append(waiter) + try: + val = await waiter + finally: + self._waiters.remove(waiter) + + if self._exc is not None: + raise self._exc + + return val + + def cancel(self) -> None: + """Cancel all waiters""" + for waiter in self._waiters: + waiter.cancel() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/log.py b/.venv/lib/python3.7/site-packages/aiohttp/log.py new file mode 100644 index 0000000..3cecea2 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/log.py @@ -0,0 +1,8 @@ +import logging + +access_logger = logging.getLogger("aiohttp.access") +client_logger = logging.getLogger("aiohttp.client") +internal_logger = logging.getLogger("aiohttp.internal") +server_logger = logging.getLogger("aiohttp.server") +web_logger = logging.getLogger("aiohttp.web") +ws_logger = logging.getLogger("aiohttp.websocket") diff --git a/.venv/lib/python3.7/site-packages/aiohttp/multipart.py b/.venv/lib/python3.7/site-packages/aiohttp/multipart.py new file mode 100644 index 0000000..73801f4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/multipart.py @@ -0,0 +1,961 @@ +import base64 +import binascii +import json +import re +import uuid +import warnings +import zlib +from collections import deque +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + AsyncIterator, + Deque, + Dict, + Iterator, + List, + Mapping, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +from urllib.parse import parse_qsl, unquote, urlencode + +from multidict import CIMultiDict, CIMultiDictProxy, MultiMapping + +from .hdrs import ( + CONTENT_DISPOSITION, + CONTENT_ENCODING, + CONTENT_LENGTH, + CONTENT_TRANSFER_ENCODING, + CONTENT_TYPE, +) +from .helpers import CHAR, TOKEN, parse_mimetype, reify +from .http import HeadersParser +from .payload import ( + JsonPayload, + LookupError, + Order, + Payload, + StringPayload, + get_payload, + payload_type, +) +from .streams import StreamReader + +__all__ = ( + "MultipartReader", + "MultipartWriter", + "BodyPartReader", + "BadContentDispositionHeader", + "BadContentDispositionParam", + "parse_content_disposition", + "content_disposition_filename", +) + + +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import ClientResponse + + +class BadContentDispositionHeader(RuntimeWarning): + pass + + +class BadContentDispositionParam(RuntimeWarning): + pass + + +def parse_content_disposition( + header: Optional[str], +) -> Tuple[Optional[str], Dict[str, str]]: + def is_token(string: str) -> bool: + return bool(string) and TOKEN >= set(string) + + def is_quoted(string: str) -> bool: + return string[0] == string[-1] == '"' + + def is_rfc5987(string: str) -> bool: + return is_token(string) and string.count("'") == 2 + + def is_extended_param(string: str) -> bool: + return string.endswith("*") + + def is_continuous_param(string: str) -> bool: + pos = string.find("*") + 1 + if not pos: + return False + substring = string[pos:-1] if string.endswith("*") else string[pos:] + return substring.isdigit() + + def unescape(text: str, *, chars: str = "".join(map(re.escape, CHAR))) -> str: + return re.sub(f"\\\\([{chars}])", "\\1", text) + + if not header: + return None, {} + + disptype, *parts = header.split(";") + if not is_token(disptype): + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + params: Dict[str, str] = {} + while parts: + item = parts.pop(0) + + if "=" not in item: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + key, value = item.split("=", 1) + key = key.lower().strip() + value = value.lstrip() + + if key in params: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + if not is_token(key): + warnings.warn(BadContentDispositionParam(item)) + continue + + elif is_continuous_param(key): + if is_quoted(value): + value = unescape(value[1:-1]) + elif not is_token(value): + warnings.warn(BadContentDispositionParam(item)) + continue + + elif is_extended_param(key): + if is_rfc5987(value): + encoding, _, value = value.split("'", 2) + encoding = encoding or "utf-8" + else: + warnings.warn(BadContentDispositionParam(item)) + continue + + try: + value = unquote(value, encoding, "strict") + except UnicodeDecodeError: # pragma: nocover + warnings.warn(BadContentDispositionParam(item)) + continue + + else: + failed = True + if is_quoted(value): + failed = False + value = unescape(value[1:-1].lstrip("\\/")) + elif is_token(value): + failed = False + elif parts: + # maybe just ; in filename, in any case this is just + # one case fix, for proper fix we need to redesign parser + _value = f"{value};{parts[0]}" + if is_quoted(_value): + parts.pop(0) + value = unescape(_value[1:-1].lstrip("\\/")) + failed = False + + if failed: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + params[key] = value + + return disptype.lower(), params + + +def content_disposition_filename( + params: Mapping[str, str], name: str = "filename" +) -> Optional[str]: + name_suf = "%s*" % name + if not params: + return None + elif name_suf in params: + return params[name_suf] + elif name in params: + return params[name] + else: + parts = [] + fnparams = sorted( + (key, value) for key, value in params.items() if key.startswith(name_suf) + ) + for num, (key, value) in enumerate(fnparams): + _, tail = key.split("*", 1) + if tail.endswith("*"): + tail = tail[:-1] + if tail == str(num): + parts.append(value) + else: + break + if not parts: + return None + value = "".join(parts) + if "'" in value: + encoding, _, value = value.split("'", 2) + encoding = encoding or "utf-8" + return unquote(value, encoding, "strict") + return value + + +class MultipartResponseWrapper: + """Wrapper around the MultipartReader. + + It takes care about + underlying connection and close it when it needs in. + """ + + def __init__( + self, + resp: "ClientResponse", + stream: "MultipartReader", + ) -> None: + self.resp = resp + self.stream = stream + + def __aiter__(self) -> "MultipartResponseWrapper": + return self + + async def __anext__( + self, + ) -> Union["MultipartReader", "BodyPartReader"]: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + def at_eof(self) -> bool: + """Returns True when all response data had been read.""" + return self.resp.content.at_eof() + + async def next( + self, + ) -> Optional[Union["MultipartReader", "BodyPartReader"]]: + """Emits next multipart reader object.""" + item = await self.stream.next() + if self.stream.at_eof(): + await self.release() + return item + + async def release(self) -> None: + """Release the connection gracefully. + + All remaining content is read to the void. + """ + await self.resp.release() + + +class BodyPartReader: + """Multipart reader for single body part.""" + + chunk_size = 8192 + + def __init__( + self, boundary: bytes, headers: "CIMultiDictProxy[str]", content: StreamReader + ) -> None: + self.headers = headers + self._boundary = boundary + self._content = content + self._at_eof = False + length = self.headers.get(CONTENT_LENGTH, None) + self._length = int(length) if length is not None else None + self._read_bytes = 0 + # TODO: typeing.Deque is not supported by Python 3.5 + self._unread: Deque[bytes] = deque() + self._prev_chunk: Optional[bytes] = None + self._content_eof = 0 + self._cache: Dict[str, Any] = {} + + def __aiter__(self) -> AsyncIterator["BodyPartReader"]: + return self # type: ignore[return-value] + + async def __anext__(self) -> bytes: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + async def next(self) -> Optional[bytes]: + item = await self.read() + if not item: + return None + return item + + async def read(self, *, decode: bool = False) -> bytes: + """Reads body part data. + + decode: Decodes data following by encoding + method from Content-Encoding header. If it missed + data remains untouched + """ + if self._at_eof: + return b"" + data = bytearray() + while not self._at_eof: + data.extend(await self.read_chunk(self.chunk_size)) + if decode: + return self.decode(data) + return data + + async def read_chunk(self, size: int = chunk_size) -> bytes: + """Reads body part content chunk of the specified size. + + size: chunk size + """ + if self._at_eof: + return b"" + if self._length: + chunk = await self._read_chunk_from_length(size) + else: + chunk = await self._read_chunk_from_stream(size) + + self._read_bytes += len(chunk) + if self._read_bytes == self._length: + self._at_eof = True + if self._at_eof: + clrf = await self._content.readline() + assert ( + b"\r\n" == clrf + ), "reader did not read all the data or it is malformed" + return chunk + + async def _read_chunk_from_length(self, size: int) -> bytes: + # Reads body part content chunk of the specified size. + # The body part must has Content-Length header with proper value. + assert self._length is not None, "Content-Length required for chunked read" + chunk_size = min(size, self._length - self._read_bytes) + chunk = await self._content.read(chunk_size) + return chunk + + async def _read_chunk_from_stream(self, size: int) -> bytes: + # Reads content chunk of body part with unknown length. + # The Content-Length header for body part is not necessary. + assert ( + size >= len(self._boundary) + 2 + ), "Chunk size must be greater or equal than boundary length + 2" + first_chunk = self._prev_chunk is None + if first_chunk: + self._prev_chunk = await self._content.read(size) + + chunk = await self._content.read(size) + self._content_eof += int(self._content.at_eof()) + assert self._content_eof < 3, "Reading after EOF" + assert self._prev_chunk is not None + window = self._prev_chunk + chunk + sub = b"\r\n" + self._boundary + if first_chunk: + idx = window.find(sub) + else: + idx = window.find(sub, max(0, len(self._prev_chunk) - len(sub))) + if idx >= 0: + # pushing boundary back to content + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + self._content.unread_data(window[idx:]) + if size > idx: + self._prev_chunk = self._prev_chunk[:idx] + chunk = window[len(self._prev_chunk) : idx] + if not chunk: + self._at_eof = True + result = self._prev_chunk + self._prev_chunk = chunk + return result + + async def readline(self) -> bytes: + """Reads body part by line by line.""" + if self._at_eof: + return b"" + + if self._unread: + line = self._unread.popleft() + else: + line = await self._content.readline() + + if line.startswith(self._boundary): + # the very last boundary may not come with \r\n, + # so set single rules for everyone + sline = line.rstrip(b"\r\n") + boundary = self._boundary + last_boundary = self._boundary + b"--" + # ensure that we read exactly the boundary, not something alike + if sline == boundary or sline == last_boundary: + self._at_eof = True + self._unread.append(line) + return b"" + else: + next_line = await self._content.readline() + if next_line.startswith(self._boundary): + line = line[:-2] # strip CRLF but only once + self._unread.append(next_line) + + return line + + async def release(self) -> None: + """Like read(), but reads all the data to the void.""" + if self._at_eof: + return + while not self._at_eof: + await self.read_chunk(self.chunk_size) + + async def text(self, *, encoding: Optional[str] = None) -> str: + """Like read(), but assumes that body part contains text data.""" + data = await self.read(decode=True) + # see https://www.w3.org/TR/html5/forms.html#multipart/form-data-encoding-algorithm # NOQA + # and https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-send # NOQA + encoding = encoding or self.get_charset(default="utf-8") + return data.decode(encoding) + + async def json(self, *, encoding: Optional[str] = None) -> Optional[Dict[str, Any]]: + """Like read(), but assumes that body parts contains JSON data.""" + data = await self.read(decode=True) + if not data: + return None + encoding = encoding or self.get_charset(default="utf-8") + return cast(Dict[str, Any], json.loads(data.decode(encoding))) + + async def form(self, *, encoding: Optional[str] = None) -> List[Tuple[str, str]]: + """Like read(), but assumes that body parts contain form urlencoded data.""" + data = await self.read(decode=True) + if not data: + return [] + if encoding is not None: + real_encoding = encoding + else: + real_encoding = self.get_charset(default="utf-8") + return parse_qsl( + data.rstrip().decode(real_encoding), + keep_blank_values=True, + encoding=real_encoding, + ) + + def at_eof(self) -> bool: + """Returns True if the boundary was reached or False otherwise.""" + return self._at_eof + + def decode(self, data: bytes) -> bytes: + """Decodes data. + + Decoding is done according the specified Content-Encoding + or Content-Transfer-Encoding headers value. + """ + if CONTENT_TRANSFER_ENCODING in self.headers: + data = self._decode_content_transfer(data) + if CONTENT_ENCODING in self.headers: + return self._decode_content(data) + return data + + def _decode_content(self, data: bytes) -> bytes: + encoding = self.headers.get(CONTENT_ENCODING, "").lower() + + if encoding == "deflate": + return zlib.decompress(data, -zlib.MAX_WBITS) + elif encoding == "gzip": + return zlib.decompress(data, 16 + zlib.MAX_WBITS) + elif encoding == "identity": + return data + else: + raise RuntimeError(f"unknown content encoding: {encoding}") + + def _decode_content_transfer(self, data: bytes) -> bytes: + encoding = self.headers.get(CONTENT_TRANSFER_ENCODING, "").lower() + + if encoding == "base64": + return base64.b64decode(data) + elif encoding == "quoted-printable": + return binascii.a2b_qp(data) + elif encoding in ("binary", "8bit", "7bit"): + return data + else: + raise RuntimeError( + "unknown content transfer encoding: {}" "".format(encoding) + ) + + def get_charset(self, default: str) -> str: + """Returns charset parameter from Content-Type header or default.""" + ctype = self.headers.get(CONTENT_TYPE, "") + mimetype = parse_mimetype(ctype) + return mimetype.parameters.get("charset", default) + + @reify + def name(self) -> Optional[str]: + """Returns name specified in Content-Disposition header. + + If the header is missing or malformed, returns None. + """ + _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) + return content_disposition_filename(params, "name") + + @reify + def filename(self) -> Optional[str]: + """Returns filename specified in Content-Disposition header. + + Returns None if the header is missing or malformed. + """ + _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) + return content_disposition_filename(params, "filename") + + +@payload_type(BodyPartReader, order=Order.try_first) +class BodyPartReaderPayload(Payload): + def __init__(self, value: BodyPartReader, *args: Any, **kwargs: Any) -> None: + super().__init__(value, *args, **kwargs) + + params: Dict[str, str] = {} + if value.name is not None: + params["name"] = value.name + if value.filename is not None: + params["filename"] = value.filename + + if params: + self.set_content_disposition("attachment", True, **params) + + async def write(self, writer: Any) -> None: + field = self._value + chunk = await field.read_chunk(size=2**16) + while chunk: + await writer.write(field.decode(chunk)) + chunk = await field.read_chunk(size=2**16) + + +class MultipartReader: + """Multipart body reader.""" + + #: Response wrapper, used when multipart readers constructs from response. + response_wrapper_cls = MultipartResponseWrapper + #: Multipart reader class, used to handle multipart/* body parts. + #: None points to type(self) + multipart_reader_cls = None + #: Body part reader class for non multipart/* content types. + part_reader_cls = BodyPartReader + + def __init__(self, headers: Mapping[str, str], content: StreamReader) -> None: + self.headers = headers + self._boundary = ("--" + self._get_boundary()).encode() + self._content = content + self._last_part: Optional[Union["MultipartReader", BodyPartReader]] = None + self._at_eof = False + self._at_bof = True + self._unread: List[bytes] = [] + + def __aiter__( + self, + ) -> AsyncIterator["BodyPartReader"]: + return self # type: ignore[return-value] + + async def __anext__( + self, + ) -> Optional[Union["MultipartReader", BodyPartReader]]: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + @classmethod + def from_response( + cls, + response: "ClientResponse", + ) -> MultipartResponseWrapper: + """Constructs reader instance from HTTP response. + + :param response: :class:`~aiohttp.client.ClientResponse` instance + """ + obj = cls.response_wrapper_cls( + response, cls(response.headers, response.content) + ) + return obj + + def at_eof(self) -> bool: + """Returns True if the final boundary was reached, false otherwise.""" + return self._at_eof + + async def next( + self, + ) -> Optional[Union["MultipartReader", BodyPartReader]]: + """Emits the next multipart body part.""" + # So, if we're at BOF, we need to skip till the boundary. + if self._at_eof: + return None + await self._maybe_release_last_part() + if self._at_bof: + await self._read_until_first_boundary() + self._at_bof = False + else: + await self._read_boundary() + if self._at_eof: # we just read the last boundary, nothing to do there + return None + self._last_part = await self.fetch_next_part() + return self._last_part + + async def release(self) -> None: + """Reads all the body parts to the void till the final boundary.""" + while not self._at_eof: + item = await self.next() + if item is None: + break + await item.release() + + async def fetch_next_part( + self, + ) -> Union["MultipartReader", BodyPartReader]: + """Returns the next body part reader.""" + headers = await self._read_headers() + return self._get_part_reader(headers) + + def _get_part_reader( + self, + headers: "CIMultiDictProxy[str]", + ) -> Union["MultipartReader", BodyPartReader]: + """Dispatches the response by the `Content-Type` header. + + Returns a suitable reader instance. + + :param dict headers: Response headers + """ + ctype = headers.get(CONTENT_TYPE, "") + mimetype = parse_mimetype(ctype) + + if mimetype.type == "multipart": + if self.multipart_reader_cls is None: + return type(self)(headers, self._content) + return self.multipart_reader_cls(headers, self._content) + else: + return self.part_reader_cls(self._boundary, headers, self._content) + + def _get_boundary(self) -> str: + mimetype = parse_mimetype(self.headers[CONTENT_TYPE]) + + assert mimetype.type == "multipart", "multipart/* content type expected" + + if "boundary" not in mimetype.parameters: + raise ValueError( + "boundary missed for Content-Type: %s" % self.headers[CONTENT_TYPE] + ) + + boundary = mimetype.parameters["boundary"] + if len(boundary) > 70: + raise ValueError("boundary %r is too long (70 chars max)" % boundary) + + return boundary + + async def _readline(self) -> bytes: + if self._unread: + return self._unread.pop() + return await self._content.readline() + + async def _read_until_first_boundary(self) -> None: + while True: + chunk = await self._readline() + if chunk == b"": + raise ValueError( + "Could not find starting boundary %r" % (self._boundary) + ) + chunk = chunk.rstrip() + if chunk == self._boundary: + return + elif chunk == self._boundary + b"--": + self._at_eof = True + return + + async def _read_boundary(self) -> None: + chunk = (await self._readline()).rstrip() + if chunk == self._boundary: + pass + elif chunk == self._boundary + b"--": + self._at_eof = True + epilogue = await self._readline() + next_line = await self._readline() + + # the epilogue is expected and then either the end of input or the + # parent multipart boundary, if the parent boundary is found then + # it should be marked as unread and handed to the parent for + # processing + if next_line[:2] == b"--": + self._unread.append(next_line) + # otherwise the request is likely missing an epilogue and both + # lines should be passed to the parent for processing + # (this handles the old behavior gracefully) + else: + self._unread.extend([next_line, epilogue]) + else: + raise ValueError(f"Invalid boundary {chunk!r}, expected {self._boundary!r}") + + async def _read_headers(self) -> "CIMultiDictProxy[str]": + lines = [b""] + while True: + chunk = await self._content.readline() + chunk = chunk.strip() + lines.append(chunk) + if not chunk: + break + parser = HeadersParser() + headers, raw_headers = parser.parse_headers(lines) + return headers + + async def _maybe_release_last_part(self) -> None: + """Ensures that the last read body part is read completely.""" + if self._last_part is not None: + if not self._last_part.at_eof(): + await self._last_part.release() + self._unread.extend(self._last_part._unread) + self._last_part = None + + +_Part = Tuple[Payload, str, str] + + +class MultipartWriter(Payload): + """Multipart body writer.""" + + def __init__(self, subtype: str = "mixed", boundary: Optional[str] = None) -> None: + boundary = boundary if boundary is not None else uuid.uuid4().hex + # The underlying Payload API demands a str (utf-8), not bytes, + # so we need to ensure we don't lose anything during conversion. + # As a result, require the boundary to be ASCII only. + # In both situations. + + try: + self._boundary = boundary.encode("ascii") + except UnicodeEncodeError: + raise ValueError("boundary should contain ASCII only chars") from None + ctype = f"multipart/{subtype}; boundary={self._boundary_value}" + + super().__init__(None, content_type=ctype) + + self._parts: List[_Part] = [] + + def __enter__(self) -> "MultipartWriter": + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + pass + + def __iter__(self) -> Iterator[_Part]: + return iter(self._parts) + + def __len__(self) -> int: + return len(self._parts) + + def __bool__(self) -> bool: + return True + + _valid_tchar_regex = re.compile(rb"\A[!#$%&'*+\-.^_`|~\w]+\Z") + _invalid_qdtext_char_regex = re.compile(rb"[\x00-\x08\x0A-\x1F\x7F]") + + @property + def _boundary_value(self) -> str: + """Wrap boundary parameter value in quotes, if necessary. + + Reads self.boundary and returns a unicode sting. + """ + # Refer to RFCs 7231, 7230, 5234. + # + # parameter = token "=" ( token / quoted-string ) + # token = 1*tchar + # quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + # qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text + # obs-text = %x80-FF + # quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + # / DIGIT / ALPHA + # ; any VCHAR, except delimiters + # VCHAR = %x21-7E + value = self._boundary + if re.match(self._valid_tchar_regex, value): + return value.decode("ascii") # cannot fail + + if re.search(self._invalid_qdtext_char_regex, value): + raise ValueError("boundary value contains invalid characters") + + # escape %x5C and %x22 + quoted_value_content = value.replace(b"\\", b"\\\\") + quoted_value_content = quoted_value_content.replace(b'"', b'\\"') + + return '"' + quoted_value_content.decode("ascii") + '"' + + @property + def boundary(self) -> str: + return self._boundary.decode("ascii") + + def append(self, obj: Any, headers: Optional[MultiMapping[str]] = None) -> Payload: + if headers is None: + headers = CIMultiDict() + + if isinstance(obj, Payload): + obj.headers.update(headers) + return self.append_payload(obj) + else: + try: + payload = get_payload(obj, headers=headers) + except LookupError: + raise TypeError("Cannot create payload from %r" % obj) + else: + return self.append_payload(payload) + + def append_payload(self, payload: Payload) -> Payload: + """Adds a new body part to multipart writer.""" + # compression + encoding: Optional[str] = payload.headers.get( + CONTENT_ENCODING, + "", + ).lower() + if encoding and encoding not in ("deflate", "gzip", "identity"): + raise RuntimeError(f"unknown content encoding: {encoding}") + if encoding == "identity": + encoding = None + + # te encoding + te_encoding: Optional[str] = payload.headers.get( + CONTENT_TRANSFER_ENCODING, + "", + ).lower() + if te_encoding not in ("", "base64", "quoted-printable", "binary"): + raise RuntimeError( + "unknown content transfer encoding: {}" "".format(te_encoding) + ) + if te_encoding == "binary": + te_encoding = None + + # size + size = payload.size + if size is not None and not (encoding or te_encoding): + payload.headers[CONTENT_LENGTH] = str(size) + + self._parts.append((payload, encoding, te_encoding)) # type: ignore[arg-type] + return payload + + def append_json( + self, obj: Any, headers: Optional[MultiMapping[str]] = None + ) -> Payload: + """Helper to append JSON part.""" + if headers is None: + headers = CIMultiDict() + + return self.append_payload(JsonPayload(obj, headers=headers)) + + def append_form( + self, + obj: Union[Sequence[Tuple[str, str]], Mapping[str, str]], + headers: Optional[MultiMapping[str]] = None, + ) -> Payload: + """Helper to append form urlencoded part.""" + assert isinstance(obj, (Sequence, Mapping)) + + if headers is None: + headers = CIMultiDict() + + if isinstance(obj, Mapping): + obj = list(obj.items()) + data = urlencode(obj, doseq=True) + + return self.append_payload( + StringPayload( + data, headers=headers, content_type="application/x-www-form-urlencoded" + ) + ) + + @property + def size(self) -> Optional[int]: + """Size of the payload.""" + total = 0 + for part, encoding, te_encoding in self._parts: + if encoding or te_encoding or part.size is None: + return None + + total += int( + 2 + + len(self._boundary) + + 2 + + part.size # b'--'+self._boundary+b'\r\n' + + len(part._binary_headers) + + 2 # b'\r\n' + ) + + total += 2 + len(self._boundary) + 4 # b'--'+self._boundary+b'--\r\n' + return total + + async def write(self, writer: Any, close_boundary: bool = True) -> None: + """Write body.""" + for part, encoding, te_encoding in self._parts: + await writer.write(b"--" + self._boundary + b"\r\n") + await writer.write(part._binary_headers) + + if encoding or te_encoding: + w = MultipartPayloadWriter(writer) + if encoding: + w.enable_compression(encoding) + if te_encoding: + w.enable_encoding(te_encoding) + await part.write(w) # type: ignore[arg-type] + await w.write_eof() + else: + await part.write(writer) + + await writer.write(b"\r\n") + + if close_boundary: + await writer.write(b"--" + self._boundary + b"--\r\n") + + +class MultipartPayloadWriter: + def __init__(self, writer: Any) -> None: + self._writer = writer + self._encoding: Optional[str] = None + self._compress: Any = None + self._encoding_buffer: Optional[bytearray] = None + + def enable_encoding(self, encoding: str) -> None: + if encoding == "base64": + self._encoding = encoding + self._encoding_buffer = bytearray() + elif encoding == "quoted-printable": + self._encoding = "quoted-printable" + + def enable_compression( + self, encoding: str = "deflate", strategy: int = zlib.Z_DEFAULT_STRATEGY + ) -> None: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else -zlib.MAX_WBITS + self._compress = zlib.compressobj(wbits=zlib_mode, strategy=strategy) + + async def write_eof(self) -> None: + if self._compress is not None: + chunk = self._compress.flush() + if chunk: + self._compress = None + await self.write(chunk) + + if self._encoding == "base64": + if self._encoding_buffer: + await self._writer.write(base64.b64encode(self._encoding_buffer)) + + async def write(self, chunk: bytes) -> None: + if self._compress is not None: + if chunk: + chunk = self._compress.compress(chunk) + if not chunk: + return + + if self._encoding == "base64": + buf = self._encoding_buffer + assert buf is not None + buf.extend(chunk) + + if buf: + div, mod = divmod(len(buf), 3) + enc_chunk, self._encoding_buffer = (buf[: div * 3], buf[div * 3 :]) + if enc_chunk: + b64chunk = base64.b64encode(enc_chunk) + await self._writer.write(b64chunk) + elif self._encoding == "quoted-printable": + await self._writer.write(binascii.b2a_qp(chunk)) + else: + await self._writer.write(chunk) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/payload.py b/.venv/lib/python3.7/site-packages/aiohttp/payload.py new file mode 100644 index 0000000..a2340e2 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/payload.py @@ -0,0 +1,465 @@ +import asyncio +import enum +import io +import json +import mimetypes +import os +import warnings +from abc import ABC, abstractmethod +from itertools import chain +from typing import ( + IO, + TYPE_CHECKING, + Any, + ByteString, + Dict, + Iterable, + Optional, + TextIO, + Tuple, + Type, + Union, +) + +from multidict import CIMultiDict + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import ( + PY_36, + content_disposition_header, + guess_filename, + parse_mimetype, + sentinel, +) +from .streams import StreamReader +from .typedefs import Final, JSONEncoder, _CIMultiDict + +__all__ = ( + "PAYLOAD_REGISTRY", + "get_payload", + "payload_type", + "Payload", + "BytesPayload", + "StringPayload", + "IOBasePayload", + "BytesIOPayload", + "BufferedReaderPayload", + "TextIOPayload", + "StringIOPayload", + "JsonPayload", + "AsyncIterablePayload", +) + +TOO_LARGE_BYTES_BODY: Final[int] = 2**20 # 1 MB + +if TYPE_CHECKING: # pragma: no cover + from typing import List + + +class LookupError(Exception): + pass + + +class Order(str, enum.Enum): + normal = "normal" + try_first = "try_first" + try_last = "try_last" + + +def get_payload(data: Any, *args: Any, **kwargs: Any) -> "Payload": + return PAYLOAD_REGISTRY.get(data, *args, **kwargs) + + +def register_payload( + factory: Type["Payload"], type: Any, *, order: Order = Order.normal +) -> None: + PAYLOAD_REGISTRY.register(factory, type, order=order) + + +class payload_type: + def __init__(self, type: Any, *, order: Order = Order.normal) -> None: + self.type = type + self.order = order + + def __call__(self, factory: Type["Payload"]) -> Type["Payload"]: + register_payload(factory, self.type, order=self.order) + return factory + + +PayloadType = Type["Payload"] +_PayloadRegistryItem = Tuple[PayloadType, Any] + + +class PayloadRegistry: + """Payload registry. + + note: we need zope.interface for more efficient adapter search + """ + + def __init__(self) -> None: + self._first: List[_PayloadRegistryItem] = [] + self._normal: List[_PayloadRegistryItem] = [] + self._last: List[_PayloadRegistryItem] = [] + + def get( + self, + data: Any, + *args: Any, + _CHAIN: "Type[chain[_PayloadRegistryItem]]" = chain, + **kwargs: Any, + ) -> "Payload": + if isinstance(data, Payload): + return data + for factory, type in _CHAIN(self._first, self._normal, self._last): + if isinstance(data, type): + return factory(data, *args, **kwargs) + + raise LookupError() + + def register( + self, factory: PayloadType, type: Any, *, order: Order = Order.normal + ) -> None: + if order is Order.try_first: + self._first.append((factory, type)) + elif order is Order.normal: + self._normal.append((factory, type)) + elif order is Order.try_last: + self._last.append((factory, type)) + else: + raise ValueError(f"Unsupported order {order!r}") + + +class Payload(ABC): + + _default_content_type: str = "application/octet-stream" + _size: Optional[int] = None + + def __init__( + self, + value: Any, + headers: Optional[ + Union[_CIMultiDict, Dict[str, str], Iterable[Tuple[str, str]]] + ] = None, + content_type: Optional[str] = sentinel, + filename: Optional[str] = None, + encoding: Optional[str] = None, + **kwargs: Any, + ) -> None: + self._encoding = encoding + self._filename = filename + self._headers: _CIMultiDict = CIMultiDict() + self._value = value + if content_type is not sentinel and content_type is not None: + self._headers[hdrs.CONTENT_TYPE] = content_type + elif self._filename is not None: + content_type = mimetypes.guess_type(self._filename)[0] + if content_type is None: + content_type = self._default_content_type + self._headers[hdrs.CONTENT_TYPE] = content_type + else: + self._headers[hdrs.CONTENT_TYPE] = self._default_content_type + self._headers.update(headers or {}) + + @property + def size(self) -> Optional[int]: + """Size of the payload.""" + return self._size + + @property + def filename(self) -> Optional[str]: + """Filename of the payload.""" + return self._filename + + @property + def headers(self) -> _CIMultiDict: + """Custom item headers""" + return self._headers + + @property + def _binary_headers(self) -> bytes: + return ( + "".join([k + ": " + v + "\r\n" for k, v in self.headers.items()]).encode( + "utf-8" + ) + + b"\r\n" + ) + + @property + def encoding(self) -> Optional[str]: + """Payload encoding""" + return self._encoding + + @property + def content_type(self) -> str: + """Content type""" + return self._headers[hdrs.CONTENT_TYPE] + + def set_content_disposition( + self, + disptype: str, + quote_fields: bool = True, + _charset: str = "utf-8", + **params: Any, + ) -> None: + """Sets ``Content-Disposition`` header.""" + self._headers[hdrs.CONTENT_DISPOSITION] = content_disposition_header( + disptype, quote_fields=quote_fields, _charset=_charset, **params + ) + + @abstractmethod + async def write(self, writer: AbstractStreamWriter) -> None: + """Write payload. + + writer is an AbstractStreamWriter instance: + """ + + +class BytesPayload(Payload): + def __init__(self, value: ByteString, *args: Any, **kwargs: Any) -> None: + if not isinstance(value, (bytes, bytearray, memoryview)): + raise TypeError(f"value argument must be byte-ish, not {type(value)!r}") + + if "content_type" not in kwargs: + kwargs["content_type"] = "application/octet-stream" + + super().__init__(value, *args, **kwargs) + + if isinstance(value, memoryview): + self._size = value.nbytes + else: + self._size = len(value) + + if self._size > TOO_LARGE_BYTES_BODY: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + warnings.warn( + "Sending a large body directly with raw bytes might" + " lock the event loop. You should probably pass an " + "io.BytesIO object instead", + ResourceWarning, + **kwargs, + ) + + async def write(self, writer: AbstractStreamWriter) -> None: + await writer.write(self._value) + + +class StringPayload(BytesPayload): + def __init__( + self, + value: str, + *args: Any, + encoding: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, + ) -> None: + + if encoding is None: + if content_type is None: + real_encoding = "utf-8" + content_type = "text/plain; charset=utf-8" + else: + mimetype = parse_mimetype(content_type) + real_encoding = mimetype.parameters.get("charset", "utf-8") + else: + if content_type is None: + content_type = "text/plain; charset=%s" % encoding + real_encoding = encoding + + super().__init__( + value.encode(real_encoding), + encoding=real_encoding, + content_type=content_type, + *args, + **kwargs, + ) + + +class StringIOPayload(StringPayload): + def __init__(self, value: IO[str], *args: Any, **kwargs: Any) -> None: + super().__init__(value.read(), *args, **kwargs) + + +class IOBasePayload(Payload): + _value: IO[Any] + + def __init__( + self, value: IO[Any], disposition: str = "attachment", *args: Any, **kwargs: Any + ) -> None: + if "filename" not in kwargs: + kwargs["filename"] = guess_filename(value) + + super().__init__(value, *args, **kwargs) + + if self._filename is not None and disposition is not None: + if hdrs.CONTENT_DISPOSITION not in self.headers: + self.set_content_disposition(disposition, filename=self._filename) + + async def write(self, writer: AbstractStreamWriter) -> None: + loop = asyncio.get_event_loop() + try: + chunk = await loop.run_in_executor(None, self._value.read, 2**16) + while chunk: + await writer.write(chunk) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) + finally: + await loop.run_in_executor(None, self._value.close) + + +class TextIOPayload(IOBasePayload): + _value: TextIO + + def __init__( + self, + value: TextIO, + *args: Any, + encoding: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, + ) -> None: + + if encoding is None: + if content_type is None: + encoding = "utf-8" + content_type = "text/plain; charset=utf-8" + else: + mimetype = parse_mimetype(content_type) + encoding = mimetype.parameters.get("charset", "utf-8") + else: + if content_type is None: + content_type = "text/plain; charset=%s" % encoding + + super().__init__( + value, + content_type=content_type, + encoding=encoding, + *args, + **kwargs, + ) + + @property + def size(self) -> Optional[int]: + try: + return os.fstat(self._value.fileno()).st_size - self._value.tell() + except OSError: + return None + + async def write(self, writer: AbstractStreamWriter) -> None: + loop = asyncio.get_event_loop() + try: + chunk = await loop.run_in_executor(None, self._value.read, 2**16) + while chunk: + data = ( + chunk.encode(encoding=self._encoding) + if self._encoding + else chunk.encode() + ) + await writer.write(data) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) + finally: + await loop.run_in_executor(None, self._value.close) + + +class BytesIOPayload(IOBasePayload): + @property + def size(self) -> int: + position = self._value.tell() + end = self._value.seek(0, os.SEEK_END) + self._value.seek(position) + return end - position + + +class BufferedReaderPayload(IOBasePayload): + @property + def size(self) -> Optional[int]: + try: + return os.fstat(self._value.fileno()).st_size - self._value.tell() + except OSError: + # data.fileno() is not supported, e.g. + # io.BufferedReader(io.BytesIO(b'data')) + return None + + +class JsonPayload(BytesPayload): + def __init__( + self, + value: Any, + encoding: str = "utf-8", + content_type: str = "application/json", + dumps: JSONEncoder = json.dumps, + *args: Any, + **kwargs: Any, + ) -> None: + + super().__init__( + dumps(value).encode(encoding), + content_type=content_type, + encoding=encoding, + *args, + **kwargs, + ) + + +if TYPE_CHECKING: # pragma: no cover + from typing import AsyncIterable, AsyncIterator + + _AsyncIterator = AsyncIterator[bytes] + _AsyncIterable = AsyncIterable[bytes] +else: + from collections.abc import AsyncIterable, AsyncIterator + + _AsyncIterator = AsyncIterator + _AsyncIterable = AsyncIterable + + +class AsyncIterablePayload(Payload): + + _iter: Optional[_AsyncIterator] = None + + def __init__(self, value: _AsyncIterable, *args: Any, **kwargs: Any) -> None: + if not isinstance(value, AsyncIterable): + raise TypeError( + "value argument must support " + "collections.abc.AsyncIterable interface, " + "got {!r}".format(type(value)) + ) + + if "content_type" not in kwargs: + kwargs["content_type"] = "application/octet-stream" + + super().__init__(value, *args, **kwargs) + + self._iter = value.__aiter__() + + async def write(self, writer: AbstractStreamWriter) -> None: + if self._iter: + try: + # iter is not None check prevents rare cases + # when the case iterable is used twice + while True: + chunk = await self._iter.__anext__() + await writer.write(chunk) + except StopAsyncIteration: + self._iter = None + + +class StreamReaderPayload(AsyncIterablePayload): + def __init__(self, value: StreamReader, *args: Any, **kwargs: Any) -> None: + super().__init__(value.iter_any(), *args, **kwargs) + + +PAYLOAD_REGISTRY = PayloadRegistry() +PAYLOAD_REGISTRY.register(BytesPayload, (bytes, bytearray, memoryview)) +PAYLOAD_REGISTRY.register(StringPayload, str) +PAYLOAD_REGISTRY.register(StringIOPayload, io.StringIO) +PAYLOAD_REGISTRY.register(TextIOPayload, io.TextIOBase) +PAYLOAD_REGISTRY.register(BytesIOPayload, io.BytesIO) +PAYLOAD_REGISTRY.register(BufferedReaderPayload, (io.BufferedReader, io.BufferedRandom)) +PAYLOAD_REGISTRY.register(IOBasePayload, io.IOBase) +PAYLOAD_REGISTRY.register(StreamReaderPayload, StreamReader) +# try_last for giving a chance to more specialized async interables like +# multidict.BodyPartReaderPayload override the default +PAYLOAD_REGISTRY.register(AsyncIterablePayload, AsyncIterable, order=Order.try_last) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/payload_streamer.py b/.venv/lib/python3.7/site-packages/aiohttp/payload_streamer.py new file mode 100644 index 0000000..9f8b8bc --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/payload_streamer.py @@ -0,0 +1,75 @@ +""" +Payload implemenation for coroutines as data provider. + +As a simple case, you can upload data from file:: + + @aiohttp.streamer + async def file_sender(writer, file_name=None): + with open(file_name, 'rb') as f: + chunk = f.read(2**16) + while chunk: + await writer.write(chunk) + + chunk = f.read(2**16) + +Then you can use `file_sender` like this: + + async with session.post('http://httpbin.org/post', + data=file_sender(file_name='huge_file')) as resp: + print(await resp.text()) + +..note:: Coroutine must accept `writer` as first argument + +""" + +import types +import warnings +from typing import Any, Awaitable, Callable, Dict, Tuple + +from .abc import AbstractStreamWriter +from .payload import Payload, payload_type + +__all__ = ("streamer",) + + +class _stream_wrapper: + def __init__( + self, + coro: Callable[..., Awaitable[None]], + args: Tuple[Any, ...], + kwargs: Dict[str, Any], + ) -> None: + self.coro = types.coroutine(coro) + self.args = args + self.kwargs = kwargs + + async def __call__(self, writer: AbstractStreamWriter) -> None: + await self.coro(writer, *self.args, **self.kwargs) # type: ignore[operator] + + +class streamer: + def __init__(self, coro: Callable[..., Awaitable[None]]) -> None: + warnings.warn( + "@streamer is deprecated, use async generators instead", + DeprecationWarning, + stacklevel=2, + ) + self.coro = coro + + def __call__(self, *args: Any, **kwargs: Any) -> _stream_wrapper: + return _stream_wrapper(self.coro, args, kwargs) + + +@payload_type(_stream_wrapper) +class StreamWrapperPayload(Payload): + async def write(self, writer: AbstractStreamWriter) -> None: + await self._value(writer) + + +@payload_type(streamer) +class StreamPayload(StreamWrapperPayload): + def __init__(self, value: Any, *args: Any, **kwargs: Any) -> None: + super().__init__(value(), *args, **kwargs) + + async def write(self, writer: AbstractStreamWriter) -> None: + await self._value(writer) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/py.typed b/.venv/lib/python3.7/site-packages/aiohttp/py.typed new file mode 100644 index 0000000..f5642f7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/py.typed @@ -0,0 +1 @@ +Marker diff --git a/.venv/lib/python3.7/site-packages/aiohttp/pytest_plugin.py b/.venv/lib/python3.7/site-packages/aiohttp/pytest_plugin.py new file mode 100644 index 0000000..dd9a9f6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/pytest_plugin.py @@ -0,0 +1,391 @@ +import asyncio +import contextlib +import warnings +from collections.abc import Callable +from typing import Any, Awaitable, Callable, Dict, Generator, Optional, Union + +import pytest + +from aiohttp.helpers import PY_37, isasyncgenfunction +from aiohttp.web import Application + +from .test_utils import ( + BaseTestServer, + RawTestServer, + TestClient, + TestServer, + loop_context, + setup_test_loop, + teardown_test_loop, + unused_port as _unused_port, +) + +try: + import uvloop +except ImportError: # pragma: no cover + uvloop = None + +try: + import tokio +except ImportError: # pragma: no cover + tokio = None + +AiohttpClient = Callable[[Union[Application, BaseTestServer]], Awaitable[TestClient]] + + +def pytest_addoption(parser): # type: ignore[no-untyped-def] + parser.addoption( + "--aiohttp-fast", + action="store_true", + default=False, + help="run tests faster by disabling extra checks", + ) + parser.addoption( + "--aiohttp-loop", + action="store", + default="pyloop", + help="run tests with specific loop: pyloop, uvloop, tokio or all", + ) + parser.addoption( + "--aiohttp-enable-loop-debug", + action="store_true", + default=False, + help="enable event loop debug mode", + ) + + +def pytest_fixture_setup(fixturedef): # type: ignore[no-untyped-def] + """Set up pytest fixture. + + Allow fixtures to be coroutines. Run coroutine fixtures in an event loop. + """ + func = fixturedef.func + + if isasyncgenfunction(func): + # async generator fixture + is_async_gen = True + elif asyncio.iscoroutinefunction(func): + # regular async fixture + is_async_gen = False + else: + # not an async fixture, nothing to do + return + + strip_request = False + if "request" not in fixturedef.argnames: + fixturedef.argnames += ("request",) + strip_request = True + + def wrapper(*args, **kwargs): # type: ignore[no-untyped-def] + request = kwargs["request"] + if strip_request: + del kwargs["request"] + + # if neither the fixture nor the test use the 'loop' fixture, + # 'getfixturevalue' will fail because the test is not parameterized + # (this can be removed someday if 'loop' is no longer parameterized) + if "loop" not in request.fixturenames: + raise Exception( + "Asynchronous fixtures must depend on the 'loop' fixture or " + "be used in tests depending from it." + ) + + _loop = request.getfixturevalue("loop") + + if is_async_gen: + # for async generators, we need to advance the generator once, + # then advance it again in a finalizer + gen = func(*args, **kwargs) + + def finalizer(): # type: ignore[no-untyped-def] + try: + return _loop.run_until_complete(gen.__anext__()) + except StopAsyncIteration: + pass + + request.addfinalizer(finalizer) + return _loop.run_until_complete(gen.__anext__()) + else: + return _loop.run_until_complete(func(*args, **kwargs)) + + fixturedef.func = wrapper + + +@pytest.fixture +def fast(request): # type: ignore[no-untyped-def] + """--fast config option""" + return request.config.getoption("--aiohttp-fast") + + +@pytest.fixture +def loop_debug(request): # type: ignore[no-untyped-def] + """--enable-loop-debug config option""" + return request.config.getoption("--aiohttp-enable-loop-debug") + + +@contextlib.contextmanager +def _runtime_warning_context(): # type: ignore[no-untyped-def] + """Context manager which checks for RuntimeWarnings. + + This exists specifically to + avoid "coroutine 'X' was never awaited" warnings being missed. + + If RuntimeWarnings occur in the context a RuntimeError is raised. + """ + with warnings.catch_warnings(record=True) as _warnings: + yield + rw = [ + "{w.filename}:{w.lineno}:{w.message}".format(w=w) + for w in _warnings + if w.category == RuntimeWarning + ] + if rw: + raise RuntimeError( + "{} Runtime Warning{},\n{}".format( + len(rw), "" if len(rw) == 1 else "s", "\n".join(rw) + ) + ) + + +@contextlib.contextmanager +def _passthrough_loop_context(loop, fast=False): # type: ignore[no-untyped-def] + """Passthrough loop context. + + Sets up and tears down a loop unless one is passed in via the loop + argument when it's passed straight through. + """ + if loop: + # loop already exists, pass it straight through + yield loop + else: + # this shadows loop_context's standard behavior + loop = setup_test_loop() + yield loop + teardown_test_loop(loop, fast=fast) + + +def pytest_pycollect_makeitem(collector, name, obj): # type: ignore[no-untyped-def] + """Fix pytest collecting for coroutines.""" + if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj): + return list(collector._genfunctions(name, obj)) + + +def pytest_pyfunc_call(pyfuncitem): # type: ignore[no-untyped-def] + """Run coroutines in an event loop instead of a normal function call.""" + fast = pyfuncitem.config.getoption("--aiohttp-fast") + if asyncio.iscoroutinefunction(pyfuncitem.function): + existing_loop = pyfuncitem.funcargs.get( + "proactor_loop" + ) or pyfuncitem.funcargs.get("loop", None) + with _runtime_warning_context(): + with _passthrough_loop_context(existing_loop, fast=fast) as _loop: + testargs = { + arg: pyfuncitem.funcargs[arg] + for arg in pyfuncitem._fixtureinfo.argnames + } + _loop.run_until_complete(pyfuncitem.obj(**testargs)) + + return True + + +def pytest_generate_tests(metafunc): # type: ignore[no-untyped-def] + if "loop_factory" not in metafunc.fixturenames: + return + + loops = metafunc.config.option.aiohttp_loop + avail_factories = {"pyloop": asyncio.DefaultEventLoopPolicy} + + if uvloop is not None: # pragma: no cover + avail_factories["uvloop"] = uvloop.EventLoopPolicy + + if tokio is not None: # pragma: no cover + avail_factories["tokio"] = tokio.EventLoopPolicy + + if loops == "all": + loops = "pyloop,uvloop?,tokio?" + + factories = {} # type: ignore[var-annotated] + for name in loops.split(","): + required = not name.endswith("?") + name = name.strip(" ?") + if name not in avail_factories: # pragma: no cover + if required: + raise ValueError( + "Unknown loop '%s', available loops: %s" + % (name, list(factories.keys())) + ) + else: + continue + factories[name] = avail_factories[name] + metafunc.parametrize( + "loop_factory", list(factories.values()), ids=list(factories.keys()) + ) + + +@pytest.fixture +def loop(loop_factory, fast, loop_debug): # type: ignore[no-untyped-def] + """Return an instance of the event loop.""" + policy = loop_factory() + asyncio.set_event_loop_policy(policy) + with loop_context(fast=fast) as _loop: + if loop_debug: + _loop.set_debug(True) # pragma: no cover + asyncio.set_event_loop(_loop) + yield _loop + + +@pytest.fixture +def proactor_loop(): # type: ignore[no-untyped-def] + if not PY_37: + policy = asyncio.get_event_loop_policy() + policy._loop_factory = asyncio.ProactorEventLoop # type: ignore[attr-defined] + else: + policy = asyncio.WindowsProactorEventLoopPolicy() # type: ignore[attr-defined] + asyncio.set_event_loop_policy(policy) + + with loop_context(policy.new_event_loop) as _loop: + asyncio.set_event_loop(_loop) + yield _loop + + +@pytest.fixture +def unused_port(aiohttp_unused_port): # type: ignore[no-untyped-def] # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_unused_port fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_unused_port + + +@pytest.fixture +def aiohttp_unused_port(): # type: ignore[no-untyped-def] + """Return a port that is unused on the current host.""" + return _unused_port + + +@pytest.fixture +def aiohttp_server(loop): # type: ignore[no-untyped-def] + """Factory to create a TestServer instance, given an app. + + aiohttp_server(app, **kwargs) + """ + servers = [] + + async def go(app, *, port=None, **kwargs): # type: ignore[no-untyped-def] + server = TestServer(app, port=port) + await server.start_server(loop=loop, **kwargs) + servers.append(server) + return server + + yield go + + async def finalize() -> None: + while servers: + await servers.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def test_server(aiohttp_server): # type: ignore[no-untyped-def] # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_server fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_server + + +@pytest.fixture +def aiohttp_raw_server(loop): # type: ignore[no-untyped-def] + """Factory to create a RawTestServer instance, given a web handler. + + aiohttp_raw_server(handler, **kwargs) + """ + servers = [] + + async def go(handler, *, port=None, **kwargs): # type: ignore[no-untyped-def] + server = RawTestServer(handler, port=port) + await server.start_server(loop=loop, **kwargs) + servers.append(server) + return server + + yield go + + async def finalize() -> None: + while servers: + await servers.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def raw_test_server( # type: ignore[no-untyped-def] # pragma: no cover + aiohttp_raw_server, +): + warnings.warn( + "Deprecated, use aiohttp_raw_server fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_raw_server + + +@pytest.fixture +def aiohttp_client( + loop: asyncio.AbstractEventLoop, +) -> Generator[AiohttpClient, None, None]: + """Factory to create a TestClient instance. + + aiohttp_client(app, **kwargs) + aiohttp_client(server, **kwargs) + aiohttp_client(raw_server, **kwargs) + """ + clients = [] + + async def go( + __param: Union[Application, BaseTestServer], + *args: Any, + server_kwargs: Optional[Dict[str, Any]] = None, + **kwargs: Any + ) -> TestClient: + + if isinstance(__param, Callable) and not isinstance( # type: ignore[arg-type] + __param, (Application, BaseTestServer) + ): + __param = __param(loop, *args, **kwargs) + kwargs = {} + else: + assert not args, "args should be empty" + + if isinstance(__param, Application): + server_kwargs = server_kwargs or {} + server = TestServer(__param, loop=loop, **server_kwargs) + client = TestClient(server, loop=loop, **kwargs) + elif isinstance(__param, BaseTestServer): + client = TestClient(__param, loop=loop, **kwargs) + else: + raise ValueError("Unknown argument type: %r" % type(__param)) + + await client.start_server() + clients.append(client) + return client + + yield go + + async def finalize() -> None: + while clients: + await clients.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def test_client(aiohttp_client): # type: ignore[no-untyped-def] # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_client fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_client diff --git a/.venv/lib/python3.7/site-packages/aiohttp/resolver.py b/.venv/lib/python3.7/site-packages/aiohttp/resolver.py new file mode 100644 index 0000000..531ce93 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/resolver.py @@ -0,0 +1,160 @@ +import asyncio +import socket +from typing import Any, Dict, List, Optional, Type, Union + +from .abc import AbstractResolver +from .helpers import get_running_loop + +__all__ = ("ThreadedResolver", "AsyncResolver", "DefaultResolver") + +try: + import aiodns + + # aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname') +except ImportError: # pragma: no cover + aiodns = None + +aiodns_default = False + + +class ThreadedResolver(AbstractResolver): + """Threaded resolver. + + Uses an Executor for synchronous getaddrinfo() calls. + concurrent.futures.ThreadPoolExecutor is used by default. + """ + + def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + self._loop = get_running_loop(loop) + + async def resolve( + self, hostname: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + infos = await self._loop.getaddrinfo( + hostname, + port, + type=socket.SOCK_STREAM, + family=family, + flags=socket.AI_ADDRCONFIG, + ) + + hosts = [] + for family, _, proto, _, address in infos: + if family == socket.AF_INET6: + if len(address) < 3: + # IPv6 is not supported by Python build, + # or IPv6 is not enabled in the host + continue + if address[3]: # type: ignore[misc] + # This is essential for link-local IPv6 addresses. + # LL IPv6 is a VERY rare case. Strictly speaking, we should use + # getnameinfo() unconditionally, but performance makes sense. + host, _port = socket.getnameinfo( + address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV + ) + port = int(_port) + else: + host, port = address[:2] + else: # IPv4 + assert family == socket.AF_INET + host, port = address # type: ignore[misc] + hosts.append( + { + "hostname": hostname, + "host": host, + "port": port, + "family": family, + "proto": proto, + "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV, + } + ) + + return hosts + + async def close(self) -> None: + pass + + +class AsyncResolver(AbstractResolver): + """Use the `aiodns` package to make asynchronous DNS lookups""" + + def __init__( + self, + loop: Optional[asyncio.AbstractEventLoop] = None, + *args: Any, + **kwargs: Any + ) -> None: + if aiodns is None: + raise RuntimeError("Resolver requires aiodns library") + + self._loop = get_running_loop(loop) + self._resolver = aiodns.DNSResolver(*args, loop=loop, **kwargs) + + if not hasattr(self._resolver, "gethostbyname"): + # aiodns 1.1 is not available, fallback to DNSResolver.query + self.resolve = self._resolve_with_query # type: ignore + + async def resolve( + self, host: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + try: + resp = await self._resolver.gethostbyname(host, family) + except aiodns.error.DNSError as exc: + msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" + raise OSError(msg) from exc + hosts = [] + for address in resp.addresses: + hosts.append( + { + "hostname": host, + "host": address, + "port": port, + "family": family, + "proto": 0, + "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV, + } + ) + + if not hosts: + raise OSError("DNS lookup failed") + + return hosts + + async def _resolve_with_query( + self, host: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + if family == socket.AF_INET6: + qtype = "AAAA" + else: + qtype = "A" + + try: + resp = await self._resolver.query(host, qtype) + except aiodns.error.DNSError as exc: + msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" + raise OSError(msg) from exc + + hosts = [] + for rr in resp: + hosts.append( + { + "hostname": host, + "host": rr.host, + "port": port, + "family": family, + "proto": 0, + "flags": socket.AI_NUMERICHOST, + } + ) + + if not hosts: + raise OSError("DNS lookup failed") + + return hosts + + async def close(self) -> None: + self._resolver.cancel() + + +_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]] +DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver diff --git a/.venv/lib/python3.7/site-packages/aiohttp/streams.py b/.venv/lib/python3.7/site-packages/aiohttp/streams.py new file mode 100644 index 0000000..726b023 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/streams.py @@ -0,0 +1,660 @@ +import asyncio +import collections +import warnings +from typing import Awaitable, Callable, Deque, Generic, List, Optional, Tuple, TypeVar + +from .base_protocol import BaseProtocol +from .helpers import BaseTimerContext, set_exception, set_result +from .log import internal_logger +from .typedefs import Final + +__all__ = ( + "EMPTY_PAYLOAD", + "EofStream", + "StreamReader", + "DataQueue", + "FlowControlDataQueue", +) + +_T = TypeVar("_T") + + +class EofStream(Exception): + """eof stream indication.""" + + +class AsyncStreamIterator(Generic[_T]): + def __init__(self, read_func: Callable[[], Awaitable[_T]]) -> None: + self.read_func = read_func + + def __aiter__(self) -> "AsyncStreamIterator[_T]": + return self + + async def __anext__(self) -> _T: + try: + rv = await self.read_func() + except EofStream: + raise StopAsyncIteration + if rv == b"": + raise StopAsyncIteration + return rv + + +class ChunkTupleAsyncStreamIterator: + def __init__(self, stream: "StreamReader") -> None: + self._stream = stream + + def __aiter__(self) -> "ChunkTupleAsyncStreamIterator": + return self + + async def __anext__(self) -> Tuple[bytes, bool]: + rv = await self._stream.readchunk() + if rv == (b"", False): + raise StopAsyncIteration + return rv + + +class AsyncStreamReaderMixin: + def __aiter__(self) -> AsyncStreamIterator[bytes]: + return AsyncStreamIterator(self.readline) # type: ignore[attr-defined] + + def iter_chunked(self, n: int) -> AsyncStreamIterator[bytes]: + """Returns an asynchronous iterator that yields chunks of size n. + + Python-3.5 available for Python 3.5+ only + """ + return AsyncStreamIterator( + lambda: self.read(n) # type: ignore[attr-defined,no-any-return] + ) + + def iter_any(self) -> AsyncStreamIterator[bytes]: + """Yield all available data as soon as it is received. + + Python-3.5 available for Python 3.5+ only + """ + return AsyncStreamIterator(self.readany) # type: ignore[attr-defined] + + def iter_chunks(self) -> ChunkTupleAsyncStreamIterator: + """Yield chunks of data as they are received by the server. + + The yielded objects are tuples + of (bytes, bool) as returned by the StreamReader.readchunk method. + + Python-3.5 available for Python 3.5+ only + """ + return ChunkTupleAsyncStreamIterator(self) # type: ignore[arg-type] + + +class StreamReader(AsyncStreamReaderMixin): + """An enhancement of asyncio.StreamReader. + + Supports asynchronous iteration by line, chunk or as available:: + + async for line in reader: + ... + async for chunk in reader.iter_chunked(1024): + ... + async for slice in reader.iter_any(): + ... + + """ + + total_bytes = 0 + + def __init__( + self, + protocol: BaseProtocol, + limit: int, + *, + timer: Optional[BaseTimerContext] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + self._protocol = protocol + self._low_water = limit + self._high_water = limit * 2 + if loop is None: + loop = asyncio.get_event_loop() + self._loop = loop + self._size = 0 + self._cursor = 0 + self._http_chunk_splits: Optional[List[int]] = None + self._buffer: Deque[bytes] = collections.deque() + self._buffer_offset = 0 + self._eof = False + self._waiter: Optional[asyncio.Future[None]] = None + self._eof_waiter: Optional[asyncio.Future[None]] = None + self._exception: Optional[BaseException] = None + self._timer = timer + self._eof_callbacks: List[Callable[[], None]] = [] + + def __repr__(self) -> str: + info = [self.__class__.__name__] + if self._size: + info.append("%d bytes" % self._size) + if self._eof: + info.append("eof") + if self._low_water != 2**16: # default limit + info.append("low=%d high=%d" % (self._low_water, self._high_water)) + if self._waiter: + info.append("w=%r" % self._waiter) + if self._exception: + info.append("e=%r" % self._exception) + return "<%s>" % " ".join(info) + + def get_read_buffer_limits(self) -> Tuple[int, int]: + return (self._low_water, self._high_water) + + def exception(self) -> Optional[BaseException]: + return self._exception + + def set_exception(self, exc: BaseException) -> None: + self._exception = exc + self._eof_callbacks.clear() + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_exception(waiter, exc) + + waiter = self._eof_waiter + if waiter is not None: + self._eof_waiter = None + set_exception(waiter, exc) + + def on_eof(self, callback: Callable[[], None]) -> None: + if self._eof: + try: + callback() + except Exception: + internal_logger.exception("Exception in eof callback") + else: + self._eof_callbacks.append(callback) + + def feed_eof(self) -> None: + self._eof = True + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + waiter = self._eof_waiter + if waiter is not None: + self._eof_waiter = None + set_result(waiter, None) + + for cb in self._eof_callbacks: + try: + cb() + except Exception: + internal_logger.exception("Exception in eof callback") + + self._eof_callbacks.clear() + + def is_eof(self) -> bool: + """Return True if 'feed_eof' was called.""" + return self._eof + + def at_eof(self) -> bool: + """Return True if the buffer is empty and 'feed_eof' was called.""" + return self._eof and not self._buffer + + async def wait_eof(self) -> None: + if self._eof: + return + + assert self._eof_waiter is None + self._eof_waiter = self._loop.create_future() + try: + await self._eof_waiter + finally: + self._eof_waiter = None + + def unread_data(self, data: bytes) -> None: + """rollback reading some data from stream, inserting it to buffer head.""" + warnings.warn( + "unread_data() is deprecated " + "and will be removed in future releases (#3260)", + DeprecationWarning, + stacklevel=2, + ) + if not data: + return + + if self._buffer_offset: + self._buffer[0] = self._buffer[0][self._buffer_offset :] + self._buffer_offset = 0 + self._size += len(data) + self._cursor -= len(data) + self._buffer.appendleft(data) + self._eof_counter = 0 + + # TODO: size is ignored, remove the param later + def feed_data(self, data: bytes, size: int = 0) -> None: + assert not self._eof, "feed_data after feed_eof" + + if not data: + return + + self._size += len(data) + self._buffer.append(data) + self.total_bytes += len(data) + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + if self._size > self._high_water and not self._protocol._reading_paused: + self._protocol.pause_reading() + + def begin_http_chunk_receiving(self) -> None: + if self._http_chunk_splits is None: + if self.total_bytes: + raise RuntimeError( + "Called begin_http_chunk_receiving when" "some data was already fed" + ) + self._http_chunk_splits = [] + + def end_http_chunk_receiving(self) -> None: + if self._http_chunk_splits is None: + raise RuntimeError( + "Called end_chunk_receiving without calling " + "begin_chunk_receiving first" + ) + + # self._http_chunk_splits contains logical byte offsets from start of + # the body transfer. Each offset is the offset of the end of a chunk. + # "Logical" means bytes, accessible for a user. + # If no chunks containig logical data were received, current position + # is difinitely zero. + pos = self._http_chunk_splits[-1] if self._http_chunk_splits else 0 + + if self.total_bytes == pos: + # We should not add empty chunks here. So we check for that. + # Note, when chunked + gzip is used, we can receive a chunk + # of compressed data, but that data may not be enough for gzip FSM + # to yield any uncompressed data. That's why current position may + # not change after receiving a chunk. + return + + self._http_chunk_splits.append(self.total_bytes) + + # wake up readchunk when end of http chunk received + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + async def _wait(self, func_name: str) -> None: + # StreamReader uses a future to link the protocol feed_data() method + # to a read coroutine. Running two read coroutines at the same time + # would have an unexpected behaviour. It would not possible to know + # which coroutine would get the next data. + if self._waiter is not None: + raise RuntimeError( + "%s() called while another coroutine is " + "already waiting for incoming data" % func_name + ) + + waiter = self._waiter = self._loop.create_future() + try: + if self._timer: + with self._timer: + await waiter + else: + await waiter + finally: + self._waiter = None + + async def readline(self) -> bytes: + return await self.readuntil() + + async def readuntil(self, separator: bytes = b"\n") -> bytes: + seplen = len(separator) + if seplen == 0: + raise ValueError("Separator should be at least one-byte string") + + if self._exception is not None: + raise self._exception + + chunk = b"" + chunk_size = 0 + not_enough = True + + while not_enough: + while self._buffer and not_enough: + offset = self._buffer_offset + ichar = self._buffer[0].find(separator, offset) + 1 + # Read from current offset to found separator or to the end. + data = self._read_nowait_chunk(ichar - offset if ichar else -1) + chunk += data + chunk_size += len(data) + if ichar: + not_enough = False + + if chunk_size > self._high_water: + raise ValueError("Chunk too big") + + if self._eof: + break + + if not_enough: + await self._wait("readuntil") + + return chunk + + async def read(self, n: int = -1) -> bytes: + if self._exception is not None: + raise self._exception + + # migration problem; with DataQueue you have to catch + # EofStream exception, so common way is to run payload.read() inside + # infinite loop. what can cause real infinite loop with StreamReader + # lets keep this code one major release. + if __debug__: + if self._eof and not self._buffer: + self._eof_counter = getattr(self, "_eof_counter", 0) + 1 + if self._eof_counter > 5: + internal_logger.warning( + "Multiple access to StreamReader in eof state, " + "might be infinite loop.", + stack_info=True, + ) + + if not n: + return b"" + + if n < 0: + # This used to just loop creating a new waiter hoping to + # collect everything in self._buffer, but that would + # deadlock if the subprocess sends more than self.limit + # bytes. So just call self.readany() until EOF. + blocks = [] + while True: + block = await self.readany() + if not block: + break + blocks.append(block) + return b"".join(blocks) + + # TODO: should be `if` instead of `while` + # because waiter maybe triggered on chunk end, + # without feeding any data + while not self._buffer and not self._eof: + await self._wait("read") + + return self._read_nowait(n) + + async def readany(self) -> bytes: + if self._exception is not None: + raise self._exception + + # TODO: should be `if` instead of `while` + # because waiter maybe triggered on chunk end, + # without feeding any data + while not self._buffer and not self._eof: + await self._wait("readany") + + return self._read_nowait(-1) + + async def readchunk(self) -> Tuple[bytes, bool]: + """Returns a tuple of (data, end_of_http_chunk). + + When chunked transfer + encoding is used, end_of_http_chunk is a boolean indicating if the end + of the data corresponds to the end of a HTTP chunk , otherwise it is + always False. + """ + while True: + if self._exception is not None: + raise self._exception + + while self._http_chunk_splits: + pos = self._http_chunk_splits.pop(0) + if pos == self._cursor: + return (b"", True) + if pos > self._cursor: + return (self._read_nowait(pos - self._cursor), True) + internal_logger.warning( + "Skipping HTTP chunk end due to data " + "consumption beyond chunk boundary" + ) + + if self._buffer: + return (self._read_nowait_chunk(-1), False) + # return (self._read_nowait(-1), False) + + if self._eof: + # Special case for signifying EOF. + # (b'', True) is not a final return value actually. + return (b"", False) + + await self._wait("readchunk") + + async def readexactly(self, n: int) -> bytes: + if self._exception is not None: + raise self._exception + + blocks: List[bytes] = [] + while n > 0: + block = await self.read(n) + if not block: + partial = b"".join(blocks) + raise asyncio.IncompleteReadError(partial, len(partial) + n) + blocks.append(block) + n -= len(block) + + return b"".join(blocks) + + def read_nowait(self, n: int = -1) -> bytes: + # default was changed to be consistent with .read(-1) + # + # I believe the most users don't know about the method and + # they are not affected. + if self._exception is not None: + raise self._exception + + if self._waiter and not self._waiter.done(): + raise RuntimeError( + "Called while some coroutine is waiting for incoming data." + ) + + return self._read_nowait(n) + + def _read_nowait_chunk(self, n: int) -> bytes: + first_buffer = self._buffer[0] + offset = self._buffer_offset + if n != -1 and len(first_buffer) - offset > n: + data = first_buffer[offset : offset + n] + self._buffer_offset += n + + elif offset: + self._buffer.popleft() + data = first_buffer[offset:] + self._buffer_offset = 0 + + else: + data = self._buffer.popleft() + + self._size -= len(data) + self._cursor += len(data) + + chunk_splits = self._http_chunk_splits + # Prevent memory leak: drop useless chunk splits + while chunk_splits and chunk_splits[0] < self._cursor: + chunk_splits.pop(0) + + if self._size < self._low_water and self._protocol._reading_paused: + self._protocol.resume_reading() + return data + + def _read_nowait(self, n: int) -> bytes: + """Read not more than n bytes, or whole buffer if n == -1""" + chunks = [] + + while self._buffer: + chunk = self._read_nowait_chunk(n) + chunks.append(chunk) + if n != -1: + n -= len(chunk) + if n == 0: + break + + return b"".join(chunks) if chunks else b"" + + +class EmptyStreamReader(StreamReader): # lgtm [py/missing-call-to-init] + def __init__(self) -> None: + pass + + def exception(self) -> Optional[BaseException]: + return None + + def set_exception(self, exc: BaseException) -> None: + pass + + def on_eof(self, callback: Callable[[], None]) -> None: + try: + callback() + except Exception: + internal_logger.exception("Exception in eof callback") + + def feed_eof(self) -> None: + pass + + def is_eof(self) -> bool: + return True + + def at_eof(self) -> bool: + return True + + async def wait_eof(self) -> None: + return + + def feed_data(self, data: bytes, n: int = 0) -> None: + pass + + async def readline(self) -> bytes: + return b"" + + async def read(self, n: int = -1) -> bytes: + return b"" + + # TODO add async def readuntil + + async def readany(self) -> bytes: + return b"" + + async def readchunk(self) -> Tuple[bytes, bool]: + return (b"", True) + + async def readexactly(self, n: int) -> bytes: + raise asyncio.IncompleteReadError(b"", n) + + def read_nowait(self, n: int = -1) -> bytes: + return b"" + + +EMPTY_PAYLOAD: Final[StreamReader] = EmptyStreamReader() + + +class DataQueue(Generic[_T]): + """DataQueue is a general-purpose blocking queue with one reader.""" + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._eof = False + self._waiter: Optional[asyncio.Future[None]] = None + self._exception: Optional[BaseException] = None + self._size = 0 + self._buffer: Deque[Tuple[_T, int]] = collections.deque() + + def __len__(self) -> int: + return len(self._buffer) + + def is_eof(self) -> bool: + return self._eof + + def at_eof(self) -> bool: + return self._eof and not self._buffer + + def exception(self) -> Optional[BaseException]: + return self._exception + + def set_exception(self, exc: BaseException) -> None: + self._eof = True + self._exception = exc + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_exception(waiter, exc) + + def feed_data(self, data: _T, size: int = 0) -> None: + self._size += size + self._buffer.append((data, size)) + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + def feed_eof(self) -> None: + self._eof = True + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + async def read(self) -> _T: + if not self._buffer and not self._eof: + assert not self._waiter + self._waiter = self._loop.create_future() + try: + await self._waiter + except (asyncio.CancelledError, asyncio.TimeoutError): + self._waiter = None + raise + + if self._buffer: + data, size = self._buffer.popleft() + self._size -= size + return data + else: + if self._exception is not None: + raise self._exception + else: + raise EofStream + + def __aiter__(self) -> AsyncStreamIterator[_T]: + return AsyncStreamIterator(self.read) + + +class FlowControlDataQueue(DataQueue[_T]): + """FlowControlDataQueue resumes and pauses an underlying stream. + + It is a destination for parsed data. + """ + + def __init__( + self, protocol: BaseProtocol, limit: int, *, loop: asyncio.AbstractEventLoop + ) -> None: + super().__init__(loop=loop) + + self._protocol = protocol + self._limit = limit * 2 + + def feed_data(self, data: _T, size: int = 0) -> None: + super().feed_data(data, size) + + if self._size > self._limit and not self._protocol._reading_paused: + self._protocol.pause_reading() + + async def read(self) -> _T: + try: + return await super().read() + finally: + if self._size < self._limit and self._protocol._reading_paused: + self._protocol.resume_reading() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/tcp_helpers.py b/.venv/lib/python3.7/site-packages/aiohttp/tcp_helpers.py new file mode 100644 index 0000000..88b2442 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/tcp_helpers.py @@ -0,0 +1,37 @@ +"""Helper methods to tune a TCP connection""" + +import asyncio +import socket +from contextlib import suppress +from typing import Optional # noqa + +__all__ = ("tcp_keepalive", "tcp_nodelay") + + +if hasattr(socket, "SO_KEEPALIVE"): + + def tcp_keepalive(transport: asyncio.Transport) -> None: + sock = transport.get_extra_info("socket") + if sock is not None: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) + +else: + + def tcp_keepalive(transport: asyncio.Transport) -> None: # pragma: no cover + pass + + +def tcp_nodelay(transport: asyncio.Transport, value: bool) -> None: + sock = transport.get_extra_info("socket") + + if sock is None: + return + + if sock.family not in (socket.AF_INET, socket.AF_INET6): + return + + value = bool(value) + + # socket may be closed already, on windows OSError get raised + with suppress(OSError): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, value) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/test_utils.py b/.venv/lib/python3.7/site-packages/aiohttp/test_utils.py new file mode 100644 index 0000000..fcda2f3 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/test_utils.py @@ -0,0 +1,706 @@ +"""Utilities shared by tests.""" + +import asyncio +import contextlib +import gc +import inspect +import ipaddress +import os +import socket +import sys +import warnings +from abc import ABC, abstractmethod +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Iterator, + List, + Optional, + Type, + Union, + cast, +) +from unittest import mock + +from aiosignal import Signal +from multidict import CIMultiDict, CIMultiDictProxy +from yarl import URL + +import aiohttp +from aiohttp.client import _RequestContextManager, _WSRequestContextManager + +from . import ClientSession, hdrs +from .abc import AbstractCookieJar +from .client_reqrep import ClientResponse +from .client_ws import ClientWebSocketResponse +from .helpers import PY_38, sentinel +from .http import HttpVersion, RawRequestMessage +from .web import ( + Application, + AppRunner, + BaseRunner, + Request, + Server, + ServerRunner, + SockSite, + UrlMappingMatchInfo, +) +from .web_protocol import _RequestHandler + +if TYPE_CHECKING: # pragma: no cover + from ssl import SSLContext +else: + SSLContext = None + +if PY_38: + from unittest import IsolatedAsyncioTestCase as TestCase +else: + from asynctest import TestCase # type: ignore[no-redef] + +REUSE_ADDRESS = os.name == "posix" and sys.platform != "cygwin" + + +def get_unused_port_socket( + host: str, family: socket.AddressFamily = socket.AF_INET +) -> socket.socket: + return get_port_socket(host, 0, family) + + +def get_port_socket( + host: str, port: int, family: socket.AddressFamily +) -> socket.socket: + s = socket.socket(family, socket.SOCK_STREAM) + if REUSE_ADDRESS: + # Windows has different semantics for SO_REUSEADDR, + # so don't set it. Ref: + # https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((host, port)) + return s + + +def unused_port() -> int: + """Return a port that is unused on the current host.""" + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(("127.0.0.1", 0)) + return cast(int, s.getsockname()[1]) + + +class BaseTestServer(ABC): + __test__ = False + + def __init__( + self, + *, + scheme: Union[str, object] = sentinel, + loop: Optional[asyncio.AbstractEventLoop] = None, + host: str = "127.0.0.1", + port: Optional[int] = None, + skip_url_asserts: bool = False, + socket_factory: Callable[ + [str, int, socket.AddressFamily], socket.socket + ] = get_port_socket, + **kwargs: Any, + ) -> None: + self._loop = loop + self.runner: Optional[BaseRunner] = None + self._root: Optional[URL] = None + self.host = host + self.port = port + self._closed = False + self.scheme = scheme + self.skip_url_asserts = skip_url_asserts + self.socket_factory = socket_factory + + async def start_server( + self, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any + ) -> None: + if self.runner: + return + self._loop = loop + self._ssl = kwargs.pop("ssl", None) + self.runner = await self._make_runner(**kwargs) + await self.runner.setup() + if not self.port: + self.port = 0 + try: + version = ipaddress.ip_address(self.host).version + except ValueError: + version = 4 + family = socket.AF_INET6 if version == 6 else socket.AF_INET + _sock = self.socket_factory(self.host, self.port, family) + self.host, self.port = _sock.getsockname()[:2] + site = SockSite(self.runner, sock=_sock, ssl_context=self._ssl) + await site.start() + server = site._server + assert server is not None + sockets = server.sockets + assert sockets is not None + self.port = sockets[0].getsockname()[1] + if self.scheme is sentinel: + if self._ssl: + scheme = "https" + else: + scheme = "http" + self.scheme = scheme + self._root = URL(f"{self.scheme}://{self.host}:{self.port}") + + @abstractmethod # pragma: no cover + async def _make_runner(self, **kwargs: Any) -> BaseRunner: + pass + + def make_url(self, path: str) -> URL: + assert self._root is not None + url = URL(path) + if not self.skip_url_asserts: + assert not url.is_absolute() + return self._root.join(url) + else: + return URL(str(self._root) + path) + + @property + def started(self) -> bool: + return self.runner is not None + + @property + def closed(self) -> bool: + return self._closed + + @property + def handler(self) -> Server: + # for backward compatibility + # web.Server instance + runner = self.runner + assert runner is not None + assert runner.server is not None + return runner.server + + async def close(self) -> None: + """Close all fixtures created by the test client. + + After that point, the TestClient is no longer usable. + + This is an idempotent function: running close multiple times + will not have any additional effects. + + close is also run when the object is garbage collected, and on + exit when used as a context manager. + + """ + if self.started and not self.closed: + assert self.runner is not None + await self.runner.cleanup() + self._root = None + self.port = None + self._closed = True + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "BaseTestServer": + await self.start_server(loop=self._loop) + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + await self.close() + + +class TestServer(BaseTestServer): + def __init__( + self, + app: Application, + *, + scheme: Union[str, object] = sentinel, + host: str = "127.0.0.1", + port: Optional[int] = None, + **kwargs: Any, + ): + self.app = app + super().__init__(scheme=scheme, host=host, port=port, **kwargs) + + async def _make_runner(self, **kwargs: Any) -> BaseRunner: + return AppRunner(self.app, **kwargs) + + +class RawTestServer(BaseTestServer): + def __init__( + self, + handler: _RequestHandler, + *, + scheme: Union[str, object] = sentinel, + host: str = "127.0.0.1", + port: Optional[int] = None, + **kwargs: Any, + ) -> None: + self._handler = handler + super().__init__(scheme=scheme, host=host, port=port, **kwargs) + + async def _make_runner(self, debug: bool = True, **kwargs: Any) -> ServerRunner: + srv = Server(self._handler, loop=self._loop, debug=debug, **kwargs) + return ServerRunner(srv, debug=debug, **kwargs) + + +class TestClient: + """ + A test client implementation. + + To write functional tests for aiohttp based servers. + + """ + + __test__ = False + + def __init__( + self, + server: BaseTestServer, + *, + cookie_jar: Optional[AbstractCookieJar] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + **kwargs: Any, + ) -> None: + if not isinstance(server, BaseTestServer): + raise TypeError( + "server must be TestServer " "instance, found type: %r" % type(server) + ) + self._server = server + self._loop = loop + if cookie_jar is None: + cookie_jar = aiohttp.CookieJar(unsafe=True, loop=loop) + self._session = ClientSession(loop=loop, cookie_jar=cookie_jar, **kwargs) + self._closed = False + self._responses: List[ClientResponse] = [] + self._websockets: List[ClientWebSocketResponse] = [] + + async def start_server(self) -> None: + await self._server.start_server(loop=self._loop) + + @property + def host(self) -> str: + return self._server.host + + @property + def port(self) -> Optional[int]: + return self._server.port + + @property + def server(self) -> BaseTestServer: + return self._server + + @property + def app(self) -> Optional[Application]: + return cast(Optional[Application], getattr(self._server, "app", None)) + + @property + def session(self) -> ClientSession: + """An internal aiohttp.ClientSession. + + Unlike the methods on the TestClient, client session requests + do not automatically include the host in the url queried, and + will require an absolute path to the resource. + + """ + return self._session + + def make_url(self, path: str) -> URL: + return self._server.make_url(path) + + async def _request(self, method: str, path: str, **kwargs: Any) -> ClientResponse: + resp = await self._session.request(method, self.make_url(path), **kwargs) + # save it to close later + self._responses.append(resp) + return resp + + def request(self, method: str, path: str, **kwargs: Any) -> _RequestContextManager: + """Routes a request to tested http server. + + The interface is identical to aiohttp.ClientSession.request, + except the loop kwarg is overridden by the instance used by the + test server. + + """ + return _RequestContextManager(self._request(method, path, **kwargs)) + + def get(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP GET request.""" + return _RequestContextManager(self._request(hdrs.METH_GET, path, **kwargs)) + + def post(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP POST request.""" + return _RequestContextManager(self._request(hdrs.METH_POST, path, **kwargs)) + + def options(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP OPTIONS request.""" + return _RequestContextManager(self._request(hdrs.METH_OPTIONS, path, **kwargs)) + + def head(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP HEAD request.""" + return _RequestContextManager(self._request(hdrs.METH_HEAD, path, **kwargs)) + + def put(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PUT request.""" + return _RequestContextManager(self._request(hdrs.METH_PUT, path, **kwargs)) + + def patch(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PATCH request.""" + return _RequestContextManager(self._request(hdrs.METH_PATCH, path, **kwargs)) + + def delete(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PATCH request.""" + return _RequestContextManager(self._request(hdrs.METH_DELETE, path, **kwargs)) + + def ws_connect(self, path: str, **kwargs: Any) -> _WSRequestContextManager: + """Initiate websocket connection. + + The api corresponds to aiohttp.ClientSession.ws_connect. + + """ + return _WSRequestContextManager(self._ws_connect(path, **kwargs)) + + async def _ws_connect(self, path: str, **kwargs: Any) -> ClientWebSocketResponse: + ws = await self._session.ws_connect(self.make_url(path), **kwargs) + self._websockets.append(ws) + return ws + + async def close(self) -> None: + """Close all fixtures created by the test client. + + After that point, the TestClient is no longer usable. + + This is an idempotent function: running close multiple times + will not have any additional effects. + + close is also run on exit when used as a(n) (asynchronous) + context manager. + + """ + if not self._closed: + for resp in self._responses: + resp.close() + for ws in self._websockets: + await ws.close() + await self._session.close() + await self._server.close() + self._closed = True + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "TestClient": + await self.start_server() + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + await self.close() + + +class AioHTTPTestCase(TestCase): + """A base class to allow for unittest web applications using aiohttp. + + Provides the following: + + * self.client (aiohttp.test_utils.TestClient): an aiohttp test client. + * self.loop (asyncio.BaseEventLoop): the event loop in which the + application and server are running. + * self.app (aiohttp.web.Application): the application returned by + self.get_application() + + Note that the TestClient's methods are asynchronous: you have to + execute function on the test client using asynchronous methods. + """ + + async def get_application(self) -> Application: + """Get application. + + This method should be overridden + to return the aiohttp.web.Application + object to test. + """ + return self.get_app() + + def get_app(self) -> Application: + """Obsolete method used to constructing web application. + + Use .get_application() coroutine instead. + """ + raise RuntimeError("Did you forget to define get_application()?") + + def setUp(self) -> None: + if not PY_38: + asyncio.get_event_loop().run_until_complete(self.asyncSetUp()) + + async def asyncSetUp(self) -> None: + try: + self.loop = asyncio.get_running_loop() + except (AttributeError, RuntimeError): # AttributeError->py36 + self.loop = asyncio.get_event_loop_policy().get_event_loop() + + return await self.setUpAsync() + + async def setUpAsync(self) -> None: + self.app = await self.get_application() + self.server = await self.get_server(self.app) + self.client = await self.get_client(self.server) + + await self.client.start_server() + + def tearDown(self) -> None: + if not PY_38: + self.loop.run_until_complete(self.asyncTearDown()) + + async def asyncTearDown(self) -> None: + return await self.tearDownAsync() + + async def tearDownAsync(self) -> None: + await self.client.close() + + async def get_server(self, app: Application) -> TestServer: + """Return a TestServer instance.""" + return TestServer(app, loop=self.loop) + + async def get_client(self, server: TestServer) -> TestClient: + """Return a TestClient instance.""" + return TestClient(server, loop=self.loop) + + +def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: + """ + A decorator dedicated to use with asynchronous AioHTTPTestCase test methods. + + In 3.8+, this does nothing. + """ + warnings.warn( + "Decorator `@unittest_run_loop` is no longer needed in aiohttp 3.8+", + DeprecationWarning, + stacklevel=2, + ) + return func + + +_LOOP_FACTORY = Callable[[], asyncio.AbstractEventLoop] + + +@contextlib.contextmanager +def loop_context( + loop_factory: _LOOP_FACTORY = asyncio.new_event_loop, fast: bool = False +) -> Iterator[asyncio.AbstractEventLoop]: + """A contextmanager that creates an event_loop, for test purposes. + + Handles the creation and cleanup of a test loop. + """ + loop = setup_test_loop(loop_factory) + yield loop + teardown_test_loop(loop, fast=fast) + + +def setup_test_loop( + loop_factory: _LOOP_FACTORY = asyncio.new_event_loop, +) -> asyncio.AbstractEventLoop: + """Create and return an asyncio.BaseEventLoop instance. + + The caller should also call teardown_test_loop, + once they are done with the loop. + """ + loop = loop_factory() + try: + module = loop.__class__.__module__ + skip_watcher = "uvloop" in module + except AttributeError: # pragma: no cover + # Just in case + skip_watcher = True + asyncio.set_event_loop(loop) + if sys.platform != "win32" and not skip_watcher: + policy = asyncio.get_event_loop_policy() + watcher: asyncio.AbstractChildWatcher + try: # Python >= 3.8 + # Refs: + # * https://github.com/pytest-dev/pytest-xdist/issues/620 + # * https://stackoverflow.com/a/58614689/595220 + # * https://bugs.python.org/issue35621 + # * https://github.com/python/cpython/pull/14344 + watcher = asyncio.ThreadedChildWatcher() + except AttributeError: # Python < 3.8 + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(loop) + with contextlib.suppress(NotImplementedError): + policy.set_child_watcher(watcher) + return loop + + +def teardown_test_loop(loop: asyncio.AbstractEventLoop, fast: bool = False) -> None: + """Teardown and cleanup an event_loop created by setup_test_loop.""" + closed = loop.is_closed() + if not closed: + loop.call_soon(loop.stop) + loop.run_forever() + loop.close() + + if not fast: + gc.collect() + + asyncio.set_event_loop(None) + + +def _create_app_mock() -> mock.MagicMock: + def get_dict(app: Any, key: str) -> Any: + return app.__app_dict[key] + + def set_dict(app: Any, key: str, value: Any) -> None: + app.__app_dict[key] = value + + app = mock.MagicMock(spec=Application) + app.__app_dict = {} + app.__getitem__ = get_dict + app.__setitem__ = set_dict + + app._debug = False + app.on_response_prepare = Signal(app) + app.on_response_prepare.freeze() + return app + + +def _create_transport(sslcontext: Optional[SSLContext] = None) -> mock.Mock: + transport = mock.Mock() + + def get_extra_info(key: str) -> Optional[SSLContext]: + if key == "sslcontext": + return sslcontext + else: + return None + + transport.get_extra_info.side_effect = get_extra_info + return transport + + +def make_mocked_request( + method: str, + path: str, + headers: Any = None, + *, + match_info: Any = sentinel, + version: HttpVersion = HttpVersion(1, 1), + closing: bool = False, + app: Any = None, + writer: Any = sentinel, + protocol: Any = sentinel, + transport: Any = sentinel, + payload: Any = sentinel, + sslcontext: Optional[SSLContext] = None, + client_max_size: int = 1024**2, + loop: Any = ..., +) -> Request: + """Creates mocked web.Request testing purposes. + + Useful in unit tests, when spinning full web server is overkill or + specific conditions and errors are hard to trigger. + """ + task = mock.Mock() + if loop is ...: + loop = mock.Mock() + loop.create_future.return_value = () + + if version < HttpVersion(1, 1): + closing = True + + if headers: + headers = CIMultiDictProxy(CIMultiDict(headers)) + raw_hdrs = tuple( + (k.encode("utf-8"), v.encode("utf-8")) for k, v in headers.items() + ) + else: + headers = CIMultiDictProxy(CIMultiDict()) + raw_hdrs = () + + chunked = "chunked" in headers.get(hdrs.TRANSFER_ENCODING, "").lower() + + message = RawRequestMessage( + method, + path, + version, + headers, + raw_hdrs, + closing, + None, + False, + chunked, + URL(path), + ) + if app is None: + app = _create_app_mock() + + if transport is sentinel: + transport = _create_transport(sslcontext) + + if protocol is sentinel: + protocol = mock.Mock() + protocol.transport = transport + + if writer is sentinel: + writer = mock.Mock() + writer.write_headers = make_mocked_coro(None) + writer.write = make_mocked_coro(None) + writer.write_eof = make_mocked_coro(None) + writer.drain = make_mocked_coro(None) + writer.transport = transport + + protocol.transport = transport + protocol.writer = writer + + if payload is sentinel: + payload = mock.Mock() + + req = Request( + message, payload, protocol, writer, task, loop, client_max_size=client_max_size + ) + + match_info = UrlMappingMatchInfo( + {} if match_info is sentinel else match_info, mock.Mock() + ) + match_info.add_app(app) + req._match_info = match_info + + return req + + +def make_mocked_coro( + return_value: Any = sentinel, raise_exception: Any = sentinel +) -> Any: + """Creates a coroutine mock.""" + + async def mock_coro(*args: Any, **kwargs: Any) -> Any: + if raise_exception is not sentinel: + raise raise_exception + if not inspect.isawaitable(return_value): + return return_value + await return_value + + return mock.Mock(wraps=mock_coro) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/tracing.py b/.venv/lib/python3.7/site-packages/aiohttp/tracing.py new file mode 100644 index 0000000..d5596a4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/tracing.py @@ -0,0 +1,472 @@ +from types import SimpleNamespace +from typing import TYPE_CHECKING, Awaitable, Optional, Type, TypeVar + +import attr +from aiosignal import Signal +from multidict import CIMultiDict +from yarl import URL + +from .client_reqrep import ClientResponse + +if TYPE_CHECKING: # pragma: no cover + from .client import ClientSession + from .typedefs import Protocol + + _ParamT_contra = TypeVar("_ParamT_contra", contravariant=True) + + class _SignalCallback(Protocol[_ParamT_contra]): + def __call__( + self, + __client_session: ClientSession, + __trace_config_ctx: SimpleNamespace, + __params: _ParamT_contra, + ) -> Awaitable[None]: + ... + + +__all__ = ( + "TraceConfig", + "TraceRequestStartParams", + "TraceRequestEndParams", + "TraceRequestExceptionParams", + "TraceConnectionQueuedStartParams", + "TraceConnectionQueuedEndParams", + "TraceConnectionCreateStartParams", + "TraceConnectionCreateEndParams", + "TraceConnectionReuseconnParams", + "TraceDnsResolveHostStartParams", + "TraceDnsResolveHostEndParams", + "TraceDnsCacheHitParams", + "TraceDnsCacheMissParams", + "TraceRequestRedirectParams", + "TraceRequestChunkSentParams", + "TraceResponseChunkReceivedParams", + "TraceRequestHeadersSentParams", +) + + +class TraceConfig: + """First-class used to trace requests launched via ClientSession objects.""" + + def __init__( + self, trace_config_ctx_factory: Type[SimpleNamespace] = SimpleNamespace + ) -> None: + self._on_request_start: Signal[ + _SignalCallback[TraceRequestStartParams] + ] = Signal(self) + self._on_request_chunk_sent: Signal[ + _SignalCallback[TraceRequestChunkSentParams] + ] = Signal(self) + self._on_response_chunk_received: Signal[ + _SignalCallback[TraceResponseChunkReceivedParams] + ] = Signal(self) + self._on_request_end: Signal[_SignalCallback[TraceRequestEndParams]] = Signal( + self + ) + self._on_request_exception: Signal[ + _SignalCallback[TraceRequestExceptionParams] + ] = Signal(self) + self._on_request_redirect: Signal[ + _SignalCallback[TraceRequestRedirectParams] + ] = Signal(self) + self._on_connection_queued_start: Signal[ + _SignalCallback[TraceConnectionQueuedStartParams] + ] = Signal(self) + self._on_connection_queued_end: Signal[ + _SignalCallback[TraceConnectionQueuedEndParams] + ] = Signal(self) + self._on_connection_create_start: Signal[ + _SignalCallback[TraceConnectionCreateStartParams] + ] = Signal(self) + self._on_connection_create_end: Signal[ + _SignalCallback[TraceConnectionCreateEndParams] + ] = Signal(self) + self._on_connection_reuseconn: Signal[ + _SignalCallback[TraceConnectionReuseconnParams] + ] = Signal(self) + self._on_dns_resolvehost_start: Signal[ + _SignalCallback[TraceDnsResolveHostStartParams] + ] = Signal(self) + self._on_dns_resolvehost_end: Signal[ + _SignalCallback[TraceDnsResolveHostEndParams] + ] = Signal(self) + self._on_dns_cache_hit: Signal[ + _SignalCallback[TraceDnsCacheHitParams] + ] = Signal(self) + self._on_dns_cache_miss: Signal[ + _SignalCallback[TraceDnsCacheMissParams] + ] = Signal(self) + self._on_request_headers_sent: Signal[ + _SignalCallback[TraceRequestHeadersSentParams] + ] = Signal(self) + + self._trace_config_ctx_factory = trace_config_ctx_factory + + def trace_config_ctx( + self, trace_request_ctx: Optional[SimpleNamespace] = None + ) -> SimpleNamespace: + """Return a new trace_config_ctx instance""" + return self._trace_config_ctx_factory(trace_request_ctx=trace_request_ctx) + + def freeze(self) -> None: + self._on_request_start.freeze() + self._on_request_chunk_sent.freeze() + self._on_response_chunk_received.freeze() + self._on_request_end.freeze() + self._on_request_exception.freeze() + self._on_request_redirect.freeze() + self._on_connection_queued_start.freeze() + self._on_connection_queued_end.freeze() + self._on_connection_create_start.freeze() + self._on_connection_create_end.freeze() + self._on_connection_reuseconn.freeze() + self._on_dns_resolvehost_start.freeze() + self._on_dns_resolvehost_end.freeze() + self._on_dns_cache_hit.freeze() + self._on_dns_cache_miss.freeze() + self._on_request_headers_sent.freeze() + + @property + def on_request_start(self) -> "Signal[_SignalCallback[TraceRequestStartParams]]": + return self._on_request_start + + @property + def on_request_chunk_sent( + self, + ) -> "Signal[_SignalCallback[TraceRequestChunkSentParams]]": + return self._on_request_chunk_sent + + @property + def on_response_chunk_received( + self, + ) -> "Signal[_SignalCallback[TraceResponseChunkReceivedParams]]": + return self._on_response_chunk_received + + @property + def on_request_end(self) -> "Signal[_SignalCallback[TraceRequestEndParams]]": + return self._on_request_end + + @property + def on_request_exception( + self, + ) -> "Signal[_SignalCallback[TraceRequestExceptionParams]]": + return self._on_request_exception + + @property + def on_request_redirect( + self, + ) -> "Signal[_SignalCallback[TraceRequestRedirectParams]]": + return self._on_request_redirect + + @property + def on_connection_queued_start( + self, + ) -> "Signal[_SignalCallback[TraceConnectionQueuedStartParams]]": + return self._on_connection_queued_start + + @property + def on_connection_queued_end( + self, + ) -> "Signal[_SignalCallback[TraceConnectionQueuedEndParams]]": + return self._on_connection_queued_end + + @property + def on_connection_create_start( + self, + ) -> "Signal[_SignalCallback[TraceConnectionCreateStartParams]]": + return self._on_connection_create_start + + @property + def on_connection_create_end( + self, + ) -> "Signal[_SignalCallback[TraceConnectionCreateEndParams]]": + return self._on_connection_create_end + + @property + def on_connection_reuseconn( + self, + ) -> "Signal[_SignalCallback[TraceConnectionReuseconnParams]]": + return self._on_connection_reuseconn + + @property + def on_dns_resolvehost_start( + self, + ) -> "Signal[_SignalCallback[TraceDnsResolveHostStartParams]]": + return self._on_dns_resolvehost_start + + @property + def on_dns_resolvehost_end( + self, + ) -> "Signal[_SignalCallback[TraceDnsResolveHostEndParams]]": + return self._on_dns_resolvehost_end + + @property + def on_dns_cache_hit(self) -> "Signal[_SignalCallback[TraceDnsCacheHitParams]]": + return self._on_dns_cache_hit + + @property + def on_dns_cache_miss(self) -> "Signal[_SignalCallback[TraceDnsCacheMissParams]]": + return self._on_dns_cache_miss + + @property + def on_request_headers_sent( + self, + ) -> "Signal[_SignalCallback[TraceRequestHeadersSentParams]]": + return self._on_request_headers_sent + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestStartParams: + """Parameters sent by the `on_request_start` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestChunkSentParams: + """Parameters sent by the `on_request_chunk_sent` signal""" + + method: str + url: URL + chunk: bytes + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceResponseChunkReceivedParams: + """Parameters sent by the `on_response_chunk_received` signal""" + + method: str + url: URL + chunk: bytes + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestEndParams: + """Parameters sent by the `on_request_end` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + response: ClientResponse + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestExceptionParams: + """Parameters sent by the `on_request_exception` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + exception: BaseException + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestRedirectParams: + """Parameters sent by the `on_request_redirect` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + response: ClientResponse + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionQueuedStartParams: + """Parameters sent by the `on_connection_queued_start` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionQueuedEndParams: + """Parameters sent by the `on_connection_queued_end` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionCreateStartParams: + """Parameters sent by the `on_connection_create_start` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionCreateEndParams: + """Parameters sent by the `on_connection_create_end` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionReuseconnParams: + """Parameters sent by the `on_connection_reuseconn` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsResolveHostStartParams: + """Parameters sent by the `on_dns_resolvehost_start` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsResolveHostEndParams: + """Parameters sent by the `on_dns_resolvehost_end` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsCacheHitParams: + """Parameters sent by the `on_dns_cache_hit` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsCacheMissParams: + """Parameters sent by the `on_dns_cache_miss` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestHeadersSentParams: + """Parameters sent by the `on_request_headers_sent` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + + +class Trace: + """Internal dependency holder class. + + Used to keep together the main dependencies used + at the moment of send a signal. + """ + + def __init__( + self, + session: "ClientSession", + trace_config: TraceConfig, + trace_config_ctx: SimpleNamespace, + ) -> None: + self._trace_config = trace_config + self._trace_config_ctx = trace_config_ctx + self._session = session + + async def send_request_start( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + return await self._trace_config.on_request_start.send( + self._session, + self._trace_config_ctx, + TraceRequestStartParams(method, url, headers), + ) + + async def send_request_chunk_sent( + self, method: str, url: URL, chunk: bytes + ) -> None: + return await self._trace_config.on_request_chunk_sent.send( + self._session, + self._trace_config_ctx, + TraceRequestChunkSentParams(method, url, chunk), + ) + + async def send_response_chunk_received( + self, method: str, url: URL, chunk: bytes + ) -> None: + return await self._trace_config.on_response_chunk_received.send( + self._session, + self._trace_config_ctx, + TraceResponseChunkReceivedParams(method, url, chunk), + ) + + async def send_request_end( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + response: ClientResponse, + ) -> None: + return await self._trace_config.on_request_end.send( + self._session, + self._trace_config_ctx, + TraceRequestEndParams(method, url, headers, response), + ) + + async def send_request_exception( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + exception: BaseException, + ) -> None: + return await self._trace_config.on_request_exception.send( + self._session, + self._trace_config_ctx, + TraceRequestExceptionParams(method, url, headers, exception), + ) + + async def send_request_redirect( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + response: ClientResponse, + ) -> None: + return await self._trace_config._on_request_redirect.send( + self._session, + self._trace_config_ctx, + TraceRequestRedirectParams(method, url, headers, response), + ) + + async def send_connection_queued_start(self) -> None: + return await self._trace_config.on_connection_queued_start.send( + self._session, self._trace_config_ctx, TraceConnectionQueuedStartParams() + ) + + async def send_connection_queued_end(self) -> None: + return await self._trace_config.on_connection_queued_end.send( + self._session, self._trace_config_ctx, TraceConnectionQueuedEndParams() + ) + + async def send_connection_create_start(self) -> None: + return await self._trace_config.on_connection_create_start.send( + self._session, self._trace_config_ctx, TraceConnectionCreateStartParams() + ) + + async def send_connection_create_end(self) -> None: + return await self._trace_config.on_connection_create_end.send( + self._session, self._trace_config_ctx, TraceConnectionCreateEndParams() + ) + + async def send_connection_reuseconn(self) -> None: + return await self._trace_config.on_connection_reuseconn.send( + self._session, self._trace_config_ctx, TraceConnectionReuseconnParams() + ) + + async def send_dns_resolvehost_start(self, host: str) -> None: + return await self._trace_config.on_dns_resolvehost_start.send( + self._session, self._trace_config_ctx, TraceDnsResolveHostStartParams(host) + ) + + async def send_dns_resolvehost_end(self, host: str) -> None: + return await self._trace_config.on_dns_resolvehost_end.send( + self._session, self._trace_config_ctx, TraceDnsResolveHostEndParams(host) + ) + + async def send_dns_cache_hit(self, host: str) -> None: + return await self._trace_config.on_dns_cache_hit.send( + self._session, self._trace_config_ctx, TraceDnsCacheHitParams(host) + ) + + async def send_dns_cache_miss(self, host: str) -> None: + return await self._trace_config.on_dns_cache_miss.send( + self._session, self._trace_config_ctx, TraceDnsCacheMissParams(host) + ) + + async def send_request_headers( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + return await self._trace_config._on_request_headers_sent.send( + self._session, + self._trace_config_ctx, + TraceRequestHeadersSentParams(method, url, headers), + ) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/typedefs.py b/.venv/lib/python3.7/site-packages/aiohttp/typedefs.py new file mode 100644 index 0000000..84283d9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/typedefs.py @@ -0,0 +1,64 @@ +import json +import os +import sys +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Iterable, + Mapping, + Tuple, + Union, +) + +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr +from yarl import URL + +# These are for other modules to use (to avoid repeating the conditional import). +if sys.version_info >= (3, 8): + from typing import Final as Final, Protocol as Protocol, TypedDict as TypedDict +else: + from typing_extensions import ( # noqa: F401 + Final, + Protocol as Protocol, + TypedDict as TypedDict, + ) + +DEFAULT_JSON_ENCODER = json.dumps +DEFAULT_JSON_DECODER = json.loads + +if TYPE_CHECKING: # pragma: no cover + _CIMultiDict = CIMultiDict[str] + _CIMultiDictProxy = CIMultiDictProxy[str] + _MultiDict = MultiDict[str] + _MultiDictProxy = MultiDictProxy[str] + from http.cookies import BaseCookie, Morsel + + from .web import Request, StreamResponse +else: + _CIMultiDict = CIMultiDict + _CIMultiDictProxy = CIMultiDictProxy + _MultiDict = MultiDict + _MultiDictProxy = MultiDictProxy + +Byteish = Union[bytes, bytearray, memoryview] +JSONEncoder = Callable[[Any], str] +JSONDecoder = Callable[[str], Any] +LooseHeaders = Union[Mapping[Union[str, istr], str], _CIMultiDict, _CIMultiDictProxy] +RawHeaders = Tuple[Tuple[bytes, bytes], ...] +StrOrURL = Union[str, URL] + +LooseCookiesMappings = Mapping[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] +LooseCookiesIterables = Iterable[ + Tuple[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] +] +LooseCookies = Union[ + LooseCookiesMappings, + LooseCookiesIterables, + "BaseCookie[str]", +] + +Handler = Callable[["Request"], Awaitable["StreamResponse"]] + +PathLike = Union[str, "os.PathLike[str]"] diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web.py b/.venv/lib/python3.7/site-packages/aiohttp/web.py new file mode 100644 index 0000000..cefae2b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web.py @@ -0,0 +1,588 @@ +import asyncio +import logging +import socket +import sys +from argparse import ArgumentParser +from collections.abc import Iterable +from importlib import import_module +from typing import ( + Any, + Awaitable, + Callable, + Iterable as TypingIterable, + List, + Optional, + Set, + Type, + Union, + cast, +) + +from .abc import AbstractAccessLogger +from .helpers import all_tasks +from .log import access_logger +from .web_app import Application as Application, CleanupError as CleanupError +from .web_exceptions import ( + HTTPAccepted as HTTPAccepted, + HTTPBadGateway as HTTPBadGateway, + HTTPBadRequest as HTTPBadRequest, + HTTPClientError as HTTPClientError, + HTTPConflict as HTTPConflict, + HTTPCreated as HTTPCreated, + HTTPError as HTTPError, + HTTPException as HTTPException, + HTTPExpectationFailed as HTTPExpectationFailed, + HTTPFailedDependency as HTTPFailedDependency, + HTTPForbidden as HTTPForbidden, + HTTPFound as HTTPFound, + HTTPGatewayTimeout as HTTPGatewayTimeout, + HTTPGone as HTTPGone, + HTTPInsufficientStorage as HTTPInsufficientStorage, + HTTPInternalServerError as HTTPInternalServerError, + HTTPLengthRequired as HTTPLengthRequired, + HTTPMethodNotAllowed as HTTPMethodNotAllowed, + HTTPMisdirectedRequest as HTTPMisdirectedRequest, + HTTPMovedPermanently as HTTPMovedPermanently, + HTTPMultipleChoices as HTTPMultipleChoices, + HTTPNetworkAuthenticationRequired as HTTPNetworkAuthenticationRequired, + HTTPNoContent as HTTPNoContent, + HTTPNonAuthoritativeInformation as HTTPNonAuthoritativeInformation, + HTTPNotAcceptable as HTTPNotAcceptable, + HTTPNotExtended as HTTPNotExtended, + HTTPNotFound as HTTPNotFound, + HTTPNotImplemented as HTTPNotImplemented, + HTTPNotModified as HTTPNotModified, + HTTPOk as HTTPOk, + HTTPPartialContent as HTTPPartialContent, + HTTPPaymentRequired as HTTPPaymentRequired, + HTTPPermanentRedirect as HTTPPermanentRedirect, + HTTPPreconditionFailed as HTTPPreconditionFailed, + HTTPPreconditionRequired as HTTPPreconditionRequired, + HTTPProxyAuthenticationRequired as HTTPProxyAuthenticationRequired, + HTTPRedirection as HTTPRedirection, + HTTPRequestEntityTooLarge as HTTPRequestEntityTooLarge, + HTTPRequestHeaderFieldsTooLarge as HTTPRequestHeaderFieldsTooLarge, + HTTPRequestRangeNotSatisfiable as HTTPRequestRangeNotSatisfiable, + HTTPRequestTimeout as HTTPRequestTimeout, + HTTPRequestURITooLong as HTTPRequestURITooLong, + HTTPResetContent as HTTPResetContent, + HTTPSeeOther as HTTPSeeOther, + HTTPServerError as HTTPServerError, + HTTPServiceUnavailable as HTTPServiceUnavailable, + HTTPSuccessful as HTTPSuccessful, + HTTPTemporaryRedirect as HTTPTemporaryRedirect, + HTTPTooManyRequests as HTTPTooManyRequests, + HTTPUnauthorized as HTTPUnauthorized, + HTTPUnavailableForLegalReasons as HTTPUnavailableForLegalReasons, + HTTPUnprocessableEntity as HTTPUnprocessableEntity, + HTTPUnsupportedMediaType as HTTPUnsupportedMediaType, + HTTPUpgradeRequired as HTTPUpgradeRequired, + HTTPUseProxy as HTTPUseProxy, + HTTPVariantAlsoNegotiates as HTTPVariantAlsoNegotiates, + HTTPVersionNotSupported as HTTPVersionNotSupported, +) +from .web_fileresponse import FileResponse as FileResponse +from .web_log import AccessLogger +from .web_middlewares import ( + middleware as middleware, + normalize_path_middleware as normalize_path_middleware, +) +from .web_protocol import ( + PayloadAccessError as PayloadAccessError, + RequestHandler as RequestHandler, + RequestPayloadError as RequestPayloadError, +) +from .web_request import ( + BaseRequest as BaseRequest, + FileField as FileField, + Request as Request, +) +from .web_response import ( + ContentCoding as ContentCoding, + Response as Response, + StreamResponse as StreamResponse, + json_response as json_response, +) +from .web_routedef import ( + AbstractRouteDef as AbstractRouteDef, + RouteDef as RouteDef, + RouteTableDef as RouteTableDef, + StaticDef as StaticDef, + delete as delete, + get as get, + head as head, + options as options, + patch as patch, + post as post, + put as put, + route as route, + static as static, + view as view, +) +from .web_runner import ( + AppRunner as AppRunner, + BaseRunner as BaseRunner, + BaseSite as BaseSite, + GracefulExit as GracefulExit, + NamedPipeSite as NamedPipeSite, + ServerRunner as ServerRunner, + SockSite as SockSite, + TCPSite as TCPSite, + UnixSite as UnixSite, +) +from .web_server import Server as Server +from .web_urldispatcher import ( + AbstractResource as AbstractResource, + AbstractRoute as AbstractRoute, + DynamicResource as DynamicResource, + PlainResource as PlainResource, + PrefixedSubAppResource as PrefixedSubAppResource, + Resource as Resource, + ResourceRoute as ResourceRoute, + StaticResource as StaticResource, + UrlDispatcher as UrlDispatcher, + UrlMappingMatchInfo as UrlMappingMatchInfo, + View as View, +) +from .web_ws import ( + WebSocketReady as WebSocketReady, + WebSocketResponse as WebSocketResponse, + WSMsgType as WSMsgType, +) + +__all__ = ( + # web_app + "Application", + "CleanupError", + # web_exceptions + "HTTPAccepted", + "HTTPBadGateway", + "HTTPBadRequest", + "HTTPClientError", + "HTTPConflict", + "HTTPCreated", + "HTTPError", + "HTTPException", + "HTTPExpectationFailed", + "HTTPFailedDependency", + "HTTPForbidden", + "HTTPFound", + "HTTPGatewayTimeout", + "HTTPGone", + "HTTPInsufficientStorage", + "HTTPInternalServerError", + "HTTPLengthRequired", + "HTTPMethodNotAllowed", + "HTTPMisdirectedRequest", + "HTTPMovedPermanently", + "HTTPMultipleChoices", + "HTTPNetworkAuthenticationRequired", + "HTTPNoContent", + "HTTPNonAuthoritativeInformation", + "HTTPNotAcceptable", + "HTTPNotExtended", + "HTTPNotFound", + "HTTPNotImplemented", + "HTTPNotModified", + "HTTPOk", + "HTTPPartialContent", + "HTTPPaymentRequired", + "HTTPPermanentRedirect", + "HTTPPreconditionFailed", + "HTTPPreconditionRequired", + "HTTPProxyAuthenticationRequired", + "HTTPRedirection", + "HTTPRequestEntityTooLarge", + "HTTPRequestHeaderFieldsTooLarge", + "HTTPRequestRangeNotSatisfiable", + "HTTPRequestTimeout", + "HTTPRequestURITooLong", + "HTTPResetContent", + "HTTPSeeOther", + "HTTPServerError", + "HTTPServiceUnavailable", + "HTTPSuccessful", + "HTTPTemporaryRedirect", + "HTTPTooManyRequests", + "HTTPUnauthorized", + "HTTPUnavailableForLegalReasons", + "HTTPUnprocessableEntity", + "HTTPUnsupportedMediaType", + "HTTPUpgradeRequired", + "HTTPUseProxy", + "HTTPVariantAlsoNegotiates", + "HTTPVersionNotSupported", + # web_fileresponse + "FileResponse", + # web_middlewares + "middleware", + "normalize_path_middleware", + # web_protocol + "PayloadAccessError", + "RequestHandler", + "RequestPayloadError", + # web_request + "BaseRequest", + "FileField", + "Request", + # web_response + "ContentCoding", + "Response", + "StreamResponse", + "json_response", + # web_routedef + "AbstractRouteDef", + "RouteDef", + "RouteTableDef", + "StaticDef", + "delete", + "get", + "head", + "options", + "patch", + "post", + "put", + "route", + "static", + "view", + # web_runner + "AppRunner", + "BaseRunner", + "BaseSite", + "GracefulExit", + "ServerRunner", + "SockSite", + "TCPSite", + "UnixSite", + "NamedPipeSite", + # web_server + "Server", + # web_urldispatcher + "AbstractResource", + "AbstractRoute", + "DynamicResource", + "PlainResource", + "PrefixedSubAppResource", + "Resource", + "ResourceRoute", + "StaticResource", + "UrlDispatcher", + "UrlMappingMatchInfo", + "View", + # web_ws + "WebSocketReady", + "WebSocketResponse", + "WSMsgType", + # web + "run_app", +) + + +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = Any # type: ignore[misc,assignment] + +HostSequence = TypingIterable[str] + + +async def _run_app( + app: Union[Application, Awaitable[Application]], + *, + host: Optional[Union[str, HostSequence]] = None, + port: Optional[int] = None, + path: Optional[str] = None, + sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None, + shutdown_timeout: float = 60.0, + keepalive_timeout: float = 75.0, + ssl_context: Optional[SSLContext] = None, + print: Callable[..., None] = print, + backlog: int = 128, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log_format: str = AccessLogger.LOG_FORMAT, + access_log: Optional[logging.Logger] = access_logger, + handle_signals: bool = True, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, +) -> None: + # A internal functio to actually do all dirty job for application running + if asyncio.iscoroutine(app): + app = await app # type: ignore[misc] + + app = cast(Application, app) + + runner = AppRunner( + app, + handle_signals=handle_signals, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + keepalive_timeout=keepalive_timeout, + ) + + await runner.setup() + + sites: List[BaseSite] = [] + + try: + if host is not None: + if isinstance(host, (str, bytes, bytearray, memoryview)): + sites.append( + TCPSite( + runner, + host, + port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + else: + for h in host: + sites.append( + TCPSite( + runner, + h, + port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + elif path is None and sock is None or port is not None: + sites.append( + TCPSite( + runner, + port=port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + + if path is not None: + if isinstance(path, (str, bytes, bytearray, memoryview)): + sites.append( + UnixSite( + runner, + path, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + else: + for p in path: + sites.append( + UnixSite( + runner, + p, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + + if sock is not None: + if not isinstance(sock, Iterable): + sites.append( + SockSite( + runner, + sock, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + else: + for s in sock: + sites.append( + SockSite( + runner, + s, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + for site in sites: + await site.start() + + if print: # pragma: no branch + names = sorted(str(s.name) for s in runner.sites) + print( + "======== Running on {} ========\n" + "(Press CTRL+C to quit)".format(", ".join(names)) + ) + + # sleep forever by 1 hour intervals, + # on Windows before Python 3.8 wake up every 1 second to handle + # Ctrl+C smoothly + if sys.platform == "win32" and sys.version_info < (3, 8): + delay = 1 + else: + delay = 3600 + + while True: + await asyncio.sleep(delay) + finally: + await runner.cleanup() + + +def _cancel_tasks( + to_cancel: Set["asyncio.Task[Any]"], loop: asyncio.AbstractEventLoop +) -> None: + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True)) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "unhandled exception during asyncio.run() shutdown", + "exception": task.exception(), + "task": task, + } + ) + + +def run_app( + app: Union[Application, Awaitable[Application]], + *, + host: Optional[Union[str, HostSequence]] = None, + port: Optional[int] = None, + path: Optional[str] = None, + sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None, + shutdown_timeout: float = 60.0, + keepalive_timeout: float = 75.0, + ssl_context: Optional[SSLContext] = None, + print: Callable[..., None] = print, + backlog: int = 128, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log_format: str = AccessLogger.LOG_FORMAT, + access_log: Optional[logging.Logger] = access_logger, + handle_signals: bool = True, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> None: + """Run an app locally""" + if loop is None: + loop = asyncio.new_event_loop() + + # Configure if and only if in debugging mode and using the default logger + if loop.get_debug() and access_log and access_log.name == "aiohttp.access": + if access_log.level == logging.NOTSET: + access_log.setLevel(logging.DEBUG) + if not access_log.hasHandlers(): + access_log.addHandler(logging.StreamHandler()) + + main_task = loop.create_task( + _run_app( + app, + host=host, + port=port, + path=path, + sock=sock, + shutdown_timeout=shutdown_timeout, + keepalive_timeout=keepalive_timeout, + ssl_context=ssl_context, + print=print, + backlog=backlog, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + handle_signals=handle_signals, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + + try: + asyncio.set_event_loop(loop) + loop.run_until_complete(main_task) + except (GracefulExit, KeyboardInterrupt): # pragma: no cover + pass + finally: + _cancel_tasks({main_task}, loop) + _cancel_tasks(all_tasks(loop), loop) + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.close() + + +def main(argv: List[str]) -> None: + arg_parser = ArgumentParser( + description="aiohttp.web Application server", prog="aiohttp.web" + ) + arg_parser.add_argument( + "entry_func", + help=( + "Callable returning the `aiohttp.web.Application` instance to " + "run. Should be specified in the 'module:function' syntax." + ), + metavar="entry-func", + ) + arg_parser.add_argument( + "-H", + "--hostname", + help="TCP/IP hostname to serve on (default: %(default)r)", + default="localhost", + ) + arg_parser.add_argument( + "-P", + "--port", + help="TCP/IP port to serve on (default: %(default)r)", + type=int, + default="8080", + ) + arg_parser.add_argument( + "-U", + "--path", + help="Unix file system path to serve on. Specifying a path will cause " + "hostname and port arguments to be ignored.", + ) + args, extra_argv = arg_parser.parse_known_args(argv) + + # Import logic + mod_str, _, func_str = args.entry_func.partition(":") + if not func_str or not mod_str: + arg_parser.error("'entry-func' not in 'module:function' syntax") + if mod_str.startswith("."): + arg_parser.error("relative module names not supported") + try: + module = import_module(mod_str) + except ImportError as ex: + arg_parser.error(f"unable to import {mod_str}: {ex}") + try: + func = getattr(module, func_str) + except AttributeError: + arg_parser.error(f"module {mod_str!r} has no attribute {func_str!r}") + + # Compatibility logic + if args.path is not None and not hasattr(socket, "AF_UNIX"): + arg_parser.error( + "file system paths not supported by your operating" " environment" + ) + + logging.basicConfig(level=logging.DEBUG) + + app = func(extra_argv) + run_app(app, host=args.hostname, port=args.port, path=args.path) + arg_parser.exit(message="Stopped\n") + + +if __name__ == "__main__": # pragma: no branch + main(sys.argv[1:]) # pragma: no cover diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_app.py b/.venv/lib/python3.7/site-packages/aiohttp/web_app.py new file mode 100644 index 0000000..8fd4471 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_app.py @@ -0,0 +1,557 @@ +import asyncio +import logging +import warnings +from functools import partial, update_wrapper +from typing import ( + TYPE_CHECKING, + Any, + AsyncIterator, + Awaitable, + Callable, + Dict, + Iterable, + Iterator, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +from aiosignal import Signal +from frozenlist import FrozenList + +from . import hdrs +from .abc import ( + AbstractAccessLogger, + AbstractMatchInfo, + AbstractRouter, + AbstractStreamWriter, +) +from .helpers import DEBUG +from .http_parser import RawRequestMessage +from .log import web_logger +from .streams import StreamReader +from .web_log import AccessLogger +from .web_middlewares import _fix_request_current_app +from .web_protocol import RequestHandler +from .web_request import Request +from .web_response import StreamResponse +from .web_routedef import AbstractRouteDef +from .web_server import Server +from .web_urldispatcher import ( + AbstractResource, + AbstractRoute, + Domain, + MaskDomain, + MatchedSubAppResource, + PrefixedSubAppResource, + UrlDispatcher, +) + +__all__ = ("Application", "CleanupError") + + +if TYPE_CHECKING: # pragma: no cover + from .typedefs import Handler + + _AppSignal = Signal[Callable[["Application"], Awaitable[None]]] + _RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]] + _Middleware = Union[ + Callable[[Request, Handler], Awaitable[StreamResponse]], + Callable[["Application", Handler], Awaitable[Handler]], # old-style + ] + _Middlewares = FrozenList[_Middleware] + _MiddlewaresHandlers = Optional[Sequence[Tuple[_Middleware, bool]]] + _Subapps = List["Application"] +else: + # No type checker mode, skip types + _AppSignal = Signal + _RespPrepareSignal = Signal + _Middleware = Callable + _Middlewares = FrozenList + _MiddlewaresHandlers = Optional[Sequence] + _Subapps = List + + +class Application(MutableMapping[str, Any]): + ATTRS = frozenset( + [ + "logger", + "_debug", + "_router", + "_loop", + "_handler_args", + "_middlewares", + "_middlewares_handlers", + "_run_middlewares", + "_state", + "_frozen", + "_pre_frozen", + "_subapps", + "_on_response_prepare", + "_on_startup", + "_on_shutdown", + "_on_cleanup", + "_client_max_size", + "_cleanup_ctx", + ] + ) + + def __init__( + self, + *, + logger: logging.Logger = web_logger, + router: Optional[UrlDispatcher] = None, + middlewares: Iterable[_Middleware] = (), + handler_args: Optional[Mapping[str, Any]] = None, + client_max_size: int = 1024**2, + loop: Optional[asyncio.AbstractEventLoop] = None, + debug: Any = ..., # mypy doesn't support ellipsis + ) -> None: + if router is None: + router = UrlDispatcher() + else: + warnings.warn( + "router argument is deprecated", DeprecationWarning, stacklevel=2 + ) + assert isinstance(router, AbstractRouter), router + + if loop is not None: + warnings.warn( + "loop argument is deprecated", DeprecationWarning, stacklevel=2 + ) + + if debug is not ...: + warnings.warn( + "debug argument is deprecated", DeprecationWarning, stacklevel=2 + ) + self._debug = debug + self._router: UrlDispatcher = router + self._loop = loop + self._handler_args = handler_args + self.logger = logger + + self._middlewares: _Middlewares = FrozenList(middlewares) + + # initialized on freezing + self._middlewares_handlers: _MiddlewaresHandlers = None + # initialized on freezing + self._run_middlewares: Optional[bool] = None + + self._state: Dict[str, Any] = {} + self._frozen = False + self._pre_frozen = False + self._subapps: _Subapps = [] + + self._on_response_prepare: _RespPrepareSignal = Signal(self) + self._on_startup: _AppSignal = Signal(self) + self._on_shutdown: _AppSignal = Signal(self) + self._on_cleanup: _AppSignal = Signal(self) + self._cleanup_ctx = CleanupContext() + self._on_startup.append(self._cleanup_ctx._on_startup) + self._on_cleanup.append(self._cleanup_ctx._on_cleanup) + self._client_max_size = client_max_size + + def __init_subclass__(cls: Type["Application"]) -> None: + warnings.warn( + "Inheritance class {} from web.Application " + "is discouraged".format(cls.__name__), + DeprecationWarning, + stacklevel=2, + ) + + if DEBUG: # pragma: no cover + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom web.Application.{} attribute " + "is discouraged".format(name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + # MutableMapping API + + def __eq__(self, other: object) -> bool: + return self is other + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def _check_frozen(self) -> None: + if self._frozen: + warnings.warn( + "Changing state of started or joined " "application is deprecated", + DeprecationWarning, + stacklevel=3, + ) + + def __setitem__(self, key: str, value: Any) -> None: + self._check_frozen() + self._state[key] = value + + def __delitem__(self, key: str) -> None: + self._check_frozen() + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + ######## + @property + def loop(self) -> asyncio.AbstractEventLoop: + # Technically the loop can be None + # but we mask it by explicit type cast + # to provide more convinient type annotation + warnings.warn("loop property is deprecated", DeprecationWarning, stacklevel=2) + return cast(asyncio.AbstractEventLoop, self._loop) + + def _set_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: + if loop is None: + loop = asyncio.get_event_loop() + if self._loop is not None and self._loop is not loop: + raise RuntimeError( + "web.Application instance initialized with different loop" + ) + + self._loop = loop + + # set loop debug + if self._debug is ...: + self._debug = loop.get_debug() + + # set loop to sub applications + for subapp in self._subapps: + subapp._set_loop(loop) + + @property + def pre_frozen(self) -> bool: + return self._pre_frozen + + def pre_freeze(self) -> None: + if self._pre_frozen: + return + + self._pre_frozen = True + self._middlewares.freeze() + self._router.freeze() + self._on_response_prepare.freeze() + self._cleanup_ctx.freeze() + self._on_startup.freeze() + self._on_shutdown.freeze() + self._on_cleanup.freeze() + self._middlewares_handlers = tuple(self._prepare_middleware()) + + # If current app and any subapp do not have middlewares avoid run all + # of the code footprint that it implies, which have a middleware + # hardcoded per app that sets up the current_app attribute. If no + # middlewares are configured the handler will receive the proper + # current_app without needing all of this code. + self._run_middlewares = True if self.middlewares else False + + for subapp in self._subapps: + subapp.pre_freeze() + self._run_middlewares = self._run_middlewares or subapp._run_middlewares + + @property + def frozen(self) -> bool: + return self._frozen + + def freeze(self) -> None: + if self._frozen: + return + + self.pre_freeze() + self._frozen = True + for subapp in self._subapps: + subapp.freeze() + + @property + def debug(self) -> bool: + warnings.warn("debug property is deprecated", DeprecationWarning, stacklevel=2) + return self._debug # type: ignore[no-any-return] + + def _reg_subapp_signals(self, subapp: "Application") -> None: + def reg_handler(signame: str) -> None: + subsig = getattr(subapp, signame) + + async def handler(app: "Application") -> None: + await subsig.send(subapp) + + appsig = getattr(self, signame) + appsig.append(handler) + + reg_handler("on_startup") + reg_handler("on_shutdown") + reg_handler("on_cleanup") + + def add_subapp(self, prefix: str, subapp: "Application") -> AbstractResource: + if not isinstance(prefix, str): + raise TypeError("Prefix must be str") + prefix = prefix.rstrip("/") + if not prefix: + raise ValueError("Prefix cannot be empty") + factory = partial(PrefixedSubAppResource, prefix, subapp) + return self._add_subapp(factory, subapp) + + def _add_subapp( + self, resource_factory: Callable[[], AbstractResource], subapp: "Application" + ) -> AbstractResource: + if self.frozen: + raise RuntimeError("Cannot add sub application to frozen application") + if subapp.frozen: + raise RuntimeError("Cannot add frozen application") + resource = resource_factory() + self.router.register_resource(resource) + self._reg_subapp_signals(subapp) + self._subapps.append(subapp) + subapp.pre_freeze() + if self._loop is not None: + subapp._set_loop(self._loop) + return resource + + def add_domain(self, domain: str, subapp: "Application") -> AbstractResource: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + elif "*" in domain: + rule: Domain = MaskDomain(domain) + else: + rule = Domain(domain) + factory = partial(MatchedSubAppResource, rule, subapp) + return self._add_subapp(factory, subapp) + + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]: + return self.router.add_routes(routes) + + @property + def on_response_prepare(self) -> _RespPrepareSignal: + return self._on_response_prepare + + @property + def on_startup(self) -> _AppSignal: + return self._on_startup + + @property + def on_shutdown(self) -> _AppSignal: + return self._on_shutdown + + @property + def on_cleanup(self) -> _AppSignal: + return self._on_cleanup + + @property + def cleanup_ctx(self) -> "CleanupContext": + return self._cleanup_ctx + + @property + def router(self) -> UrlDispatcher: + return self._router + + @property + def middlewares(self) -> _Middlewares: + return self._middlewares + + def _make_handler( + self, + *, + loop: Optional[asyncio.AbstractEventLoop] = None, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + **kwargs: Any, + ) -> Server: + + if not issubclass(access_log_class, AbstractAccessLogger): + raise TypeError( + "access_log_class must be subclass of " + "aiohttp.abc.AbstractAccessLogger, got {}".format(access_log_class) + ) + + self._set_loop(loop) + self.freeze() + + kwargs["debug"] = self._debug + kwargs["access_log_class"] = access_log_class + if self._handler_args: + for k, v in self._handler_args.items(): + kwargs[k] = v + + return Server( + self._handle, # type: ignore[arg-type] + request_factory=self._make_request, + loop=self._loop, + **kwargs, + ) + + def make_handler( + self, + *, + loop: Optional[asyncio.AbstractEventLoop] = None, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + **kwargs: Any, + ) -> Server: + + warnings.warn( + "Application.make_handler(...) is deprecated, " "use AppRunner API instead", + DeprecationWarning, + stacklevel=2, + ) + + return self._make_handler( + loop=loop, access_log_class=access_log_class, **kwargs + ) + + async def startup(self) -> None: + """Causes on_startup signal + + Should be called in the event loop along with the request handler. + """ + await self.on_startup.send(self) + + async def shutdown(self) -> None: + """Causes on_shutdown signal + + Should be called before cleanup() + """ + await self.on_shutdown.send(self) + + async def cleanup(self) -> None: + """Causes on_cleanup signal + + Should be called after shutdown() + """ + if self.on_cleanup.frozen: + await self.on_cleanup.send(self) + else: + # If an exception occurs in startup, ensure cleanup contexts are completed. + await self._cleanup_ctx._on_cleanup(self) + + def _make_request( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + _cls: Type[Request] = Request, + ) -> Request: + return _cls( + message, + payload, + protocol, + writer, + task, + self._loop, + client_max_size=self._client_max_size, + ) + + def _prepare_middleware(self) -> Iterator[Tuple[_Middleware, bool]]: + for m in reversed(self._middlewares): + if getattr(m, "__middleware_version__", None) == 1: + yield m, True + else: + warnings.warn( + 'old-style middleware "{!r}" deprecated, ' "see #2252".format(m), + DeprecationWarning, + stacklevel=2, + ) + yield m, False + + yield _fix_request_current_app(self), True + + async def _handle(self, request: Request) -> StreamResponse: + loop = asyncio.get_event_loop() + debug = loop.get_debug() + match_info = await self._router.resolve(request) + if debug: # pragma: no cover + if not isinstance(match_info, AbstractMatchInfo): + raise TypeError( + "match_info should be AbstractMatchInfo " + "instance, not {!r}".format(match_info) + ) + match_info.add_app(self) + + match_info.freeze() + + resp = None + request._match_info = match_info + expect = request.headers.get(hdrs.EXPECT) + if expect: + resp = await match_info.expect_handler(request) + await request.writer.drain() + + if resp is None: + handler = match_info.handler + + if self._run_middlewares: + for app in match_info.apps[::-1]: + for m, new_style in app._middlewares_handlers: # type: ignore[union-attr] # noqa + if new_style: + handler = update_wrapper( + partial(m, handler=handler), handler + ) + else: + handler = await m(app, handler) # type: ignore[arg-type] + + resp = await handler(request) + + return resp + + def __call__(self) -> "Application": + """gunicorn compatibility""" + return self + + def __repr__(self) -> str: + return f"" + + def __bool__(self) -> bool: + return True + + +class CleanupError(RuntimeError): + @property + def exceptions(self) -> List[BaseException]: + return cast(List[BaseException], self.args[1]) + + +if TYPE_CHECKING: # pragma: no cover + _CleanupContextBase = FrozenList[Callable[[Application], AsyncIterator[None]]] +else: + _CleanupContextBase = FrozenList + + +class CleanupContext(_CleanupContextBase): + def __init__(self) -> None: + super().__init__() + self._exits: List[AsyncIterator[None]] = [] + + async def _on_startup(self, app: Application) -> None: + for cb in self: + it = cb(app).__aiter__() + await it.__anext__() + self._exits.append(it) + + async def _on_cleanup(self, app: Application) -> None: + errors = [] + for it in reversed(self._exits): + try: + await it.__anext__() + except StopAsyncIteration: + pass + except Exception as exc: + errors.append(exc) + else: + errors.append(RuntimeError(f"{it!r} has more than one 'yield'")) + if errors: + if len(errors) == 1: + raise errors[0] + else: + raise CleanupError("Multiple errors on cleanup stage", errors) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_exceptions.py b/.venv/lib/python3.7/site-packages/aiohttp/web_exceptions.py new file mode 100644 index 0000000..ae706a1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_exceptions.py @@ -0,0 +1,441 @@ +import warnings +from typing import Any, Dict, Iterable, List, Optional, Set # noqa + +from yarl import URL + +from .typedefs import LooseHeaders, StrOrURL +from .web_response import Response + +__all__ = ( + "HTTPException", + "HTTPError", + "HTTPRedirection", + "HTTPSuccessful", + "HTTPOk", + "HTTPCreated", + "HTTPAccepted", + "HTTPNonAuthoritativeInformation", + "HTTPNoContent", + "HTTPResetContent", + "HTTPPartialContent", + "HTTPMultipleChoices", + "HTTPMovedPermanently", + "HTTPFound", + "HTTPSeeOther", + "HTTPNotModified", + "HTTPUseProxy", + "HTTPTemporaryRedirect", + "HTTPPermanentRedirect", + "HTTPClientError", + "HTTPBadRequest", + "HTTPUnauthorized", + "HTTPPaymentRequired", + "HTTPForbidden", + "HTTPNotFound", + "HTTPMethodNotAllowed", + "HTTPNotAcceptable", + "HTTPProxyAuthenticationRequired", + "HTTPRequestTimeout", + "HTTPConflict", + "HTTPGone", + "HTTPLengthRequired", + "HTTPPreconditionFailed", + "HTTPRequestEntityTooLarge", + "HTTPRequestURITooLong", + "HTTPUnsupportedMediaType", + "HTTPRequestRangeNotSatisfiable", + "HTTPExpectationFailed", + "HTTPMisdirectedRequest", + "HTTPUnprocessableEntity", + "HTTPFailedDependency", + "HTTPUpgradeRequired", + "HTTPPreconditionRequired", + "HTTPTooManyRequests", + "HTTPRequestHeaderFieldsTooLarge", + "HTTPUnavailableForLegalReasons", + "HTTPServerError", + "HTTPInternalServerError", + "HTTPNotImplemented", + "HTTPBadGateway", + "HTTPServiceUnavailable", + "HTTPGatewayTimeout", + "HTTPVersionNotSupported", + "HTTPVariantAlsoNegotiates", + "HTTPInsufficientStorage", + "HTTPNotExtended", + "HTTPNetworkAuthenticationRequired", +) + + +############################################################ +# HTTP Exceptions +############################################################ + + +class HTTPException(Response, Exception): + + # You should set in subclasses: + # status = 200 + + status_code = -1 + empty_body = False + + __http_exception__ = True + + def __init__( + self, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + if body is not None: + warnings.warn( + "body argument is deprecated for http web exceptions", + DeprecationWarning, + ) + Response.__init__( + self, + status=self.status_code, + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + Exception.__init__(self, self.reason) + if self.body is None and not self.empty_body: + self.text = f"{self.status}: {self.reason}" + + def __bool__(self) -> bool: + return True + + +class HTTPError(HTTPException): + """Base class for exceptions with status codes in the 400s and 500s.""" + + +class HTTPRedirection(HTTPException): + """Base class for exceptions with status codes in the 300s.""" + + +class HTTPSuccessful(HTTPException): + """Base class for exceptions with status codes in the 200s.""" + + +class HTTPOk(HTTPSuccessful): + status_code = 200 + + +class HTTPCreated(HTTPSuccessful): + status_code = 201 + + +class HTTPAccepted(HTTPSuccessful): + status_code = 202 + + +class HTTPNonAuthoritativeInformation(HTTPSuccessful): + status_code = 203 + + +class HTTPNoContent(HTTPSuccessful): + status_code = 204 + empty_body = True + + +class HTTPResetContent(HTTPSuccessful): + status_code = 205 + empty_body = True + + +class HTTPPartialContent(HTTPSuccessful): + status_code = 206 + + +############################################################ +# 3xx redirection +############################################################ + + +class _HTTPMove(HTTPRedirection): + def __init__( + self, + location: StrOrURL, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + if not location: + raise ValueError("HTTP redirects need a location to redirect to.") + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Location"] = str(URL(location)) + self.location = location + + +class HTTPMultipleChoices(_HTTPMove): + status_code = 300 + + +class HTTPMovedPermanently(_HTTPMove): + status_code = 301 + + +class HTTPFound(_HTTPMove): + status_code = 302 + + +# This one is safe after a POST (the redirected location will be +# retrieved with GET): +class HTTPSeeOther(_HTTPMove): + status_code = 303 + + +class HTTPNotModified(HTTPRedirection): + # FIXME: this should include a date or etag header + status_code = 304 + empty_body = True + + +class HTTPUseProxy(_HTTPMove): + # Not a move, but looks a little like one + status_code = 305 + + +class HTTPTemporaryRedirect(_HTTPMove): + status_code = 307 + + +class HTTPPermanentRedirect(_HTTPMove): + status_code = 308 + + +############################################################ +# 4xx client error +############################################################ + + +class HTTPClientError(HTTPError): + pass + + +class HTTPBadRequest(HTTPClientError): + status_code = 400 + + +class HTTPUnauthorized(HTTPClientError): + status_code = 401 + + +class HTTPPaymentRequired(HTTPClientError): + status_code = 402 + + +class HTTPForbidden(HTTPClientError): + status_code = 403 + + +class HTTPNotFound(HTTPClientError): + status_code = 404 + + +class HTTPMethodNotAllowed(HTTPClientError): + status_code = 405 + + def __init__( + self, + method: str, + allowed_methods: Iterable[str], + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + allow = ",".join(sorted(allowed_methods)) + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Allow"] = allow + self.allowed_methods: Set[str] = set(allowed_methods) + self.method = method.upper() + + +class HTTPNotAcceptable(HTTPClientError): + status_code = 406 + + +class HTTPProxyAuthenticationRequired(HTTPClientError): + status_code = 407 + + +class HTTPRequestTimeout(HTTPClientError): + status_code = 408 + + +class HTTPConflict(HTTPClientError): + status_code = 409 + + +class HTTPGone(HTTPClientError): + status_code = 410 + + +class HTTPLengthRequired(HTTPClientError): + status_code = 411 + + +class HTTPPreconditionFailed(HTTPClientError): + status_code = 412 + + +class HTTPRequestEntityTooLarge(HTTPClientError): + status_code = 413 + + def __init__(self, max_size: float, actual_size: float, **kwargs: Any) -> None: + kwargs.setdefault( + "text", + "Maximum request body size {} exceeded, " + "actual body size {}".format(max_size, actual_size), + ) + super().__init__(**kwargs) + + +class HTTPRequestURITooLong(HTTPClientError): + status_code = 414 + + +class HTTPUnsupportedMediaType(HTTPClientError): + status_code = 415 + + +class HTTPRequestRangeNotSatisfiable(HTTPClientError): + status_code = 416 + + +class HTTPExpectationFailed(HTTPClientError): + status_code = 417 + + +class HTTPMisdirectedRequest(HTTPClientError): + status_code = 421 + + +class HTTPUnprocessableEntity(HTTPClientError): + status_code = 422 + + +class HTTPFailedDependency(HTTPClientError): + status_code = 424 + + +class HTTPUpgradeRequired(HTTPClientError): + status_code = 426 + + +class HTTPPreconditionRequired(HTTPClientError): + status_code = 428 + + +class HTTPTooManyRequests(HTTPClientError): + status_code = 429 + + +class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): + status_code = 431 + + +class HTTPUnavailableForLegalReasons(HTTPClientError): + status_code = 451 + + def __init__( + self, + link: str, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Link"] = '<%s>; rel="blocked-by"' % link + self.link = link + + +############################################################ +# 5xx Server Error +############################################################ +# Response status codes beginning with the digit "5" indicate cases in +# which the server is aware that it has erred or is incapable of +# performing the request. Except when responding to a HEAD request, the +# server SHOULD include an entity containing an explanation of the error +# situation, and whether it is a temporary or permanent condition. User +# agents SHOULD display any included entity to the user. These response +# codes are applicable to any request method. + + +class HTTPServerError(HTTPError): + pass + + +class HTTPInternalServerError(HTTPServerError): + status_code = 500 + + +class HTTPNotImplemented(HTTPServerError): + status_code = 501 + + +class HTTPBadGateway(HTTPServerError): + status_code = 502 + + +class HTTPServiceUnavailable(HTTPServerError): + status_code = 503 + + +class HTTPGatewayTimeout(HTTPServerError): + status_code = 504 + + +class HTTPVersionNotSupported(HTTPServerError): + status_code = 505 + + +class HTTPVariantAlsoNegotiates(HTTPServerError): + status_code = 506 + + +class HTTPInsufficientStorage(HTTPServerError): + status_code = 507 + + +class HTTPNotExtended(HTTPServerError): + status_code = 510 + + +class HTTPNetworkAuthenticationRequired(HTTPServerError): + status_code = 511 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_fileresponse.py b/.venv/lib/python3.7/site-packages/aiohttp/web_fileresponse.py new file mode 100644 index 0000000..f41ed3f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_fileresponse.py @@ -0,0 +1,288 @@ +import asyncio +import mimetypes +import os +import pathlib +import sys +from typing import ( # noqa + IO, + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Iterator, + List, + Optional, + Tuple, + Union, + cast, +) + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import ETAG_ANY, ETag +from .typedefs import Final, LooseHeaders +from .web_exceptions import ( + HTTPNotModified, + HTTPPartialContent, + HTTPPreconditionFailed, + HTTPRequestRangeNotSatisfiable, +) +from .web_response import StreamResponse + +__all__ = ("FileResponse",) + +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest + + +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] + + +NOSENDFILE: Final[bool] = bool(os.environ.get("AIOHTTP_NOSENDFILE")) + + +class FileResponse(StreamResponse): + """A response object can be used to send files.""" + + def __init__( + self, + path: Union[str, pathlib.Path], + chunk_size: int = 256 * 1024, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + ) -> None: + super().__init__(status=status, reason=reason, headers=headers) + + if isinstance(path, str): + path = pathlib.Path(path) + + self._path = path + self._chunk_size = chunk_size + + async def _sendfile_fallback( + self, writer: AbstractStreamWriter, fobj: IO[Any], offset: int, count: int + ) -> AbstractStreamWriter: + # To keep memory usage low,fobj is transferred in chunks + # controlled by the constructor's chunk_size argument. + + chunk_size = self._chunk_size + loop = asyncio.get_event_loop() + + await loop.run_in_executor(None, fobj.seek, offset) + + chunk = await loop.run_in_executor(None, fobj.read, chunk_size) + while chunk: + await writer.write(chunk) + count = count - chunk_size + if count <= 0: + break + chunk = await loop.run_in_executor(None, fobj.read, min(chunk_size, count)) + + await writer.drain() + return writer + + async def _sendfile( + self, request: "BaseRequest", fobj: IO[Any], offset: int, count: int + ) -> AbstractStreamWriter: + writer = await super().prepare(request) + assert writer is not None + + if NOSENDFILE or sys.version_info < (3, 7) or self.compression: + return await self._sendfile_fallback(writer, fobj, offset, count) + + loop = request._loop + transport = request.transport + assert transport is not None + + try: + await loop.sendfile(transport, fobj, offset, count) + except NotImplementedError: + return await self._sendfile_fallback(writer, fobj, offset, count) + + await super().write_eof() + return writer + + @staticmethod + def _strong_etag_match(etag_value: str, etags: Tuple[ETag, ...]) -> bool: + if len(etags) == 1 and etags[0].value == ETAG_ANY: + return True + return any(etag.value == etag_value for etag in etags if not etag.is_weak) + + async def _not_modified( + self, request: "BaseRequest", etag_value: str, last_modified: float + ) -> Optional[AbstractStreamWriter]: + self.set_status(HTTPNotModified.status_code) + self._length_check = False + self.etag = etag_value # type: ignore[assignment] + self.last_modified = last_modified # type: ignore[assignment] + # Delete any Content-Length headers provided by user. HTTP 304 + # should always have empty response body + return await super().prepare(request) + + async def _precondition_failed( + self, request: "BaseRequest" + ) -> Optional[AbstractStreamWriter]: + self.set_status(HTTPPreconditionFailed.status_code) + self.content_length = 0 + return await super().prepare(request) + + async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: + filepath = self._path + + gzip = False + if "gzip" in request.headers.get(hdrs.ACCEPT_ENCODING, ""): + gzip_path = filepath.with_name(filepath.name + ".gz") + + if gzip_path.is_file(): + filepath = gzip_path + gzip = True + + loop = asyncio.get_event_loop() + st: os.stat_result = await loop.run_in_executor(None, filepath.stat) + + etag_value = f"{st.st_mtime_ns:x}-{st.st_size:x}" + last_modified = st.st_mtime + + # https://tools.ietf.org/html/rfc7232#section-6 + ifmatch = request.if_match + if ifmatch is not None and not self._strong_etag_match(etag_value, ifmatch): + return await self._precondition_failed(request) + + unmodsince = request.if_unmodified_since + if ( + unmodsince is not None + and ifmatch is None + and st.st_mtime > unmodsince.timestamp() + ): + return await self._precondition_failed(request) + + ifnonematch = request.if_none_match + if ifnonematch is not None and self._strong_etag_match(etag_value, ifnonematch): + return await self._not_modified(request, etag_value, last_modified) + + modsince = request.if_modified_since + if ( + modsince is not None + and ifnonematch is None + and st.st_mtime <= modsince.timestamp() + ): + return await self._not_modified(request, etag_value, last_modified) + + if hdrs.CONTENT_TYPE not in self.headers: + ct, encoding = mimetypes.guess_type(str(filepath)) + if not ct: + ct = "application/octet-stream" + should_set_ct = True + else: + encoding = "gzip" if gzip else None + should_set_ct = False + + status = self._status + file_size = st.st_size + count = file_size + + start = None + + ifrange = request.if_range + if ifrange is None or st.st_mtime <= ifrange.timestamp(): + # If-Range header check: + # condition = cached date >= last modification date + # return 206 if True else 200. + # if False: + # Range header would not be processed, return 200 + # if True but Range header missing + # return 200 + try: + rng = request.http_range + start = rng.start + end = rng.stop + except ValueError: + # https://tools.ietf.org/html/rfc7233: + # A server generating a 416 (Range Not Satisfiable) response to + # a byte-range request SHOULD send a Content-Range header field + # with an unsatisfied-range value. + # The complete-length in a 416 response indicates the current + # length of the selected representation. + # + # Will do the same below. Many servers ignore this and do not + # send a Content-Range header with HTTP 416 + self.headers[hdrs.CONTENT_RANGE] = f"bytes */{file_size}" + self.set_status(HTTPRequestRangeNotSatisfiable.status_code) + return await super().prepare(request) + + # If a range request has been made, convert start, end slice + # notation into file pointer offset and count + if start is not None or end is not None: + if start < 0 and end is None: # return tail of file + start += file_size + if start < 0: + # if Range:bytes=-1000 in request header but file size + # is only 200, there would be trouble without this + start = 0 + count = file_size - start + else: + # rfc7233:If the last-byte-pos value is + # absent, or if the value is greater than or equal to + # the current length of the representation data, + # the byte range is interpreted as the remainder + # of the representation (i.e., the server replaces the + # value of last-byte-pos with a value that is one less than + # the current length of the selected representation). + count = ( + min(end if end is not None else file_size, file_size) - start + ) + + if start >= file_size: + # HTTP 416 should be returned in this case. + # + # According to https://tools.ietf.org/html/rfc7233: + # If a valid byte-range-set includes at least one + # byte-range-spec with a first-byte-pos that is less than + # the current length of the representation, or at least one + # suffix-byte-range-spec with a non-zero suffix-length, + # then the byte-range-set is satisfiable. Otherwise, the + # byte-range-set is unsatisfiable. + self.headers[hdrs.CONTENT_RANGE] = f"bytes */{file_size}" + self.set_status(HTTPRequestRangeNotSatisfiable.status_code) + return await super().prepare(request) + + status = HTTPPartialContent.status_code + # Even though you are sending the whole file, you should still + # return a HTTP 206 for a Range request. + self.set_status(status) + + if should_set_ct: + self.content_type = ct # type: ignore[assignment] + if encoding: + self.headers[hdrs.CONTENT_ENCODING] = encoding + if gzip: + self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING + + self.etag = etag_value # type: ignore[assignment] + self.last_modified = st.st_mtime # type: ignore[assignment] + self.content_length = count + + self.headers[hdrs.ACCEPT_RANGES] = "bytes" + + real_start = cast(int, start) + + if status == HTTPPartialContent.status_code: + self.headers[hdrs.CONTENT_RANGE] = "bytes {}-{}/{}".format( + real_start, real_start + count - 1, file_size + ) + + # If we are sending 0 bytes calling sendfile() will throw a ValueError + if count == 0 or request.method == hdrs.METH_HEAD or self.status in [204, 304]: + return await super().prepare(request) + + fobj = await loop.run_in_executor(None, filepath.open, "rb") + if start: # be aware that start could be None or int=0 here. + offset = start + else: + offset = 0 + + try: + return await self._sendfile(request, fobj, offset, count) + finally: + await loop.run_in_executor(None, fobj.close) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_log.py b/.venv/lib/python3.7/site-packages/aiohttp/web_log.py new file mode 100644 index 0000000..bc6e3b5 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_log.py @@ -0,0 +1,208 @@ +import datetime +import functools +import logging +import os +import re +from collections import namedtuple +from typing import Any, Callable, Dict, Iterable, List, Tuple # noqa + +from .abc import AbstractAccessLogger +from .web_request import BaseRequest +from .web_response import StreamResponse + +KeyMethod = namedtuple("KeyMethod", "key method") + + +class AccessLogger(AbstractAccessLogger): + """Helper object to log access. + + Usage: + log = logging.getLogger("spam") + log_format = "%a %{User-Agent}i" + access_logger = AccessLogger(log, log_format) + access_logger.log(request, response, time) + + Format: + %% The percent sign + %a Remote IP-address (IP-address of proxy if using reverse proxy) + %t Time when the request was started to process + %P The process ID of the child that serviced the request + %r First line of request + %s Response status code + %b Size of response in bytes, including HTTP headers + %T Time taken to serve the request, in seconds + %Tf Time taken to serve the request, in seconds with floating fraction + in .06f format + %D Time taken to serve the request, in microseconds + %{FOO}i request.headers['FOO'] + %{FOO}o response.headers['FOO'] + %{FOO}e os.environ['FOO'] + + """ + + LOG_FORMAT_MAP = { + "a": "remote_address", + "t": "request_start_time", + "P": "process_id", + "r": "first_request_line", + "s": "response_status", + "b": "response_size", + "T": "request_time", + "Tf": "request_time_frac", + "D": "request_time_micro", + "i": "request_header", + "o": "response_header", + } + + LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' + FORMAT_RE = re.compile(r"%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)") + CLEANUP_RE = re.compile(r"(%[^s])") + _FORMAT_CACHE: Dict[str, Tuple[str, List[KeyMethod]]] = {} + + def __init__(self, logger: logging.Logger, log_format: str = LOG_FORMAT) -> None: + """Initialise the logger. + + logger is a logger object to be used for logging. + log_format is a string with apache compatible log format description. + + """ + super().__init__(logger, log_format=log_format) + + _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format) + if not _compiled_format: + _compiled_format = self.compile_format(log_format) + AccessLogger._FORMAT_CACHE[log_format] = _compiled_format + + self._log_format, self._methods = _compiled_format + + def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]: + """Translate log_format into form usable by modulo formatting + + All known atoms will be replaced with %s + Also methods for formatting of those atoms will be added to + _methods in appropriate order + + For example we have log_format = "%a %t" + This format will be translated to "%s %s" + Also contents of _methods will be + [self._format_a, self._format_t] + These method will be called and results will be passed + to translated string format. + + Each _format_* method receive 'args' which is list of arguments + given to self.log + + Exceptions are _format_e, _format_i and _format_o methods which + also receive key name (by functools.partial) + + """ + # list of (key, method) tuples, we don't use an OrderedDict as users + # can repeat the same key more than once + methods = list() + + for atom in self.FORMAT_RE.findall(log_format): + if atom[1] == "": + format_key1 = self.LOG_FORMAT_MAP[atom[0]] + m = getattr(AccessLogger, "_format_%s" % atom[0]) + key_method = KeyMethod(format_key1, m) + else: + format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1]) + m = getattr(AccessLogger, "_format_%s" % atom[2]) + key_method = KeyMethod(format_key2, functools.partial(m, atom[1])) + + methods.append(key_method) + + log_format = self.FORMAT_RE.sub(r"%s", log_format) + log_format = self.CLEANUP_RE.sub(r"%\1", log_format) + return log_format, methods + + @staticmethod + def _format_i( + key: str, request: BaseRequest, response: StreamResponse, time: float + ) -> str: + if request is None: + return "(no headers)" + + # suboptimal, make istr(key) once + return request.headers.get(key, "-") + + @staticmethod + def _format_o( + key: str, request: BaseRequest, response: StreamResponse, time: float + ) -> str: + # suboptimal, make istr(key) once + return response.headers.get(key, "-") + + @staticmethod + def _format_a(request: BaseRequest, response: StreamResponse, time: float) -> str: + if request is None: + return "-" + ip = request.remote + return ip if ip is not None else "-" + + @staticmethod + def _format_t(request: BaseRequest, response: StreamResponse, time: float) -> str: + now = datetime.datetime.utcnow() + start_time = now - datetime.timedelta(seconds=time) + return start_time.strftime("[%d/%b/%Y:%H:%M:%S +0000]") + + @staticmethod + def _format_P(request: BaseRequest, response: StreamResponse, time: float) -> str: + return "<%s>" % os.getpid() + + @staticmethod + def _format_r(request: BaseRequest, response: StreamResponse, time: float) -> str: + if request is None: + return "-" + return "{} {} HTTP/{}.{}".format( + request.method, + request.path_qs, + request.version.major, + request.version.minor, + ) + + @staticmethod + def _format_s(request: BaseRequest, response: StreamResponse, time: float) -> int: + return response.status + + @staticmethod + def _format_b(request: BaseRequest, response: StreamResponse, time: float) -> int: + return response.body_length + + @staticmethod + def _format_T(request: BaseRequest, response: StreamResponse, time: float) -> str: + return str(round(time)) + + @staticmethod + def _format_Tf(request: BaseRequest, response: StreamResponse, time: float) -> str: + return "%06f" % time + + @staticmethod + def _format_D(request: BaseRequest, response: StreamResponse, time: float) -> str: + return str(round(time * 1000000)) + + def _format_line( + self, request: BaseRequest, response: StreamResponse, time: float + ) -> Iterable[Tuple[str, Callable[[BaseRequest, StreamResponse, float], str]]]: + return [(key, method(request, response, time)) for key, method in self._methods] + + def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None: + try: + fmt_info = self._format_line(request, response, time) + + values = list() + extra = dict() + for key, value in fmt_info: + values.append(value) + + if key.__class__ is str: + extra[key] = value + else: + k1, k2 = key # type: ignore[misc] + dct = extra.get(k1, {}) # type: ignore[var-annotated,has-type] + dct[k2] = value # type: ignore[index,has-type] + extra[k1] = dct # type: ignore[has-type,assignment] + + self.logger.info(self._log_format % tuple(values), extra=extra) + except Exception: + self.logger.exception("Error in logging") diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_middlewares.py b/.venv/lib/python3.7/site-packages/aiohttp/web_middlewares.py new file mode 100644 index 0000000..fabcc44 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_middlewares.py @@ -0,0 +1,119 @@ +import re +from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar + +from .typedefs import Handler +from .web_exceptions import HTTPPermanentRedirect, _HTTPMove +from .web_request import Request +from .web_response import StreamResponse +from .web_urldispatcher import SystemRoute + +__all__ = ( + "middleware", + "normalize_path_middleware", +) + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + +_Func = TypeVar("_Func") + + +async def _check_request_resolves(request: Request, path: str) -> Tuple[bool, Request]: + alt_request = request.clone(rel_url=path) + + match_info = await request.app.router.resolve(alt_request) + alt_request._match_info = match_info + + if match_info.http_exception is None: + return True, alt_request + + return False, request + + +def middleware(f: _Func) -> _Func: + f.__middleware_version__ = 1 # type: ignore[attr-defined] + return f + + +_Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]] + + +def normalize_path_middleware( + *, + append_slash: bool = True, + remove_slash: bool = False, + merge_slashes: bool = True, + redirect_class: Type[_HTTPMove] = HTTPPermanentRedirect, +) -> _Middleware: + """Factory for producing a middleware that normalizes the path of a request. + + Normalizing means: + - Add or remove a trailing slash to the path. + - Double slashes are replaced by one. + + The middleware returns as soon as it finds a path that resolves + correctly. The order if both merge and append/remove are enabled is + 1) merge slashes + 2) append/remove slash + 3) both merge slashes and append/remove slash. + If the path resolves with at least one of those conditions, it will + redirect to the new path. + + Only one of `append_slash` and `remove_slash` can be enabled. If both + are `True` the factory will raise an assertion error + + If `append_slash` is `True` the middleware will append a slash when + needed. If a resource is defined with trailing slash and the request + comes without it, it will append it automatically. + + If `remove_slash` is `True`, `append_slash` must be `False`. When enabled + the middleware will remove trailing slashes and redirect if the resource + is defined + + If merge_slashes is True, merge multiple consecutive slashes in the + path into one. + """ + correct_configuration = not (append_slash and remove_slash) + assert correct_configuration, "Cannot both remove and append slash" + + @middleware + async def impl(request: Request, handler: Handler) -> StreamResponse: + if isinstance(request.match_info.route, SystemRoute): + paths_to_check = [] + if "?" in request.raw_path: + path, query = request.raw_path.split("?", 1) + query = "?" + query + else: + query = "" + path = request.raw_path + + if merge_slashes: + paths_to_check.append(re.sub("//+", "/", path)) + if append_slash and not request.path.endswith("/"): + paths_to_check.append(path + "/") + if remove_slash and request.path.endswith("/"): + paths_to_check.append(path[:-1]) + if merge_slashes and append_slash: + paths_to_check.append(re.sub("//+", "/", path + "/")) + if merge_slashes and remove_slash: + merged_slashes = re.sub("//+", "/", path) + paths_to_check.append(merged_slashes[:-1]) + + for path in paths_to_check: + path = re.sub("^//+", "/", path) # SECURITY: GHSA-v6wp-4m6f-gcjg + resolves, request = await _check_request_resolves(request, path) + if resolves: + raise redirect_class(request.raw_path + query) + + return await handler(request) + + return impl + + +def _fix_request_current_app(app: "Application") -> _Middleware: + @middleware + async def impl(request: Request, handler: Handler) -> StreamResponse: + with request.match_info.set_current_app(app): + return await handler(request) + + return impl diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_protocol.py b/.venv/lib/python3.7/site-packages/aiohttp/web_protocol.py new file mode 100644 index 0000000..10a9608 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_protocol.py @@ -0,0 +1,679 @@ +import asyncio +import asyncio.streams +import traceback +import warnings +from collections import deque +from contextlib import suppress +from html import escape as html_escape +from http import HTTPStatus +from logging import Logger +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Deque, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import attr +import yarl + +from .abc import AbstractAccessLogger, AbstractStreamWriter +from .base_protocol import BaseProtocol +from .helpers import ceil_timeout +from .http import ( + HttpProcessingError, + HttpRequestParser, + HttpVersion10, + RawRequestMessage, + StreamWriter, +) +from .log import access_logger, server_logger +from .streams import EMPTY_PAYLOAD, StreamReader +from .tcp_helpers import tcp_keepalive +from .web_exceptions import HTTPException +from .web_log import AccessLogger +from .web_request import BaseRequest +from .web_response import Response, StreamResponse + +__all__ = ("RequestHandler", "RequestPayloadError", "PayloadAccessError") + +if TYPE_CHECKING: # pragma: no cover + from .web_server import Server + + +_RequestFactory = Callable[ + [ + RawRequestMessage, + StreamReader, + "RequestHandler", + AbstractStreamWriter, + "asyncio.Task[None]", + ], + BaseRequest, +] + +_RequestHandler = Callable[[BaseRequest], Awaitable[StreamResponse]] + +ERROR = RawRequestMessage( + "UNKNOWN", + "/", + HttpVersion10, + {}, # type: ignore[arg-type] + {}, # type: ignore[arg-type] + True, + None, + False, + False, + yarl.URL("/"), +) + + +class RequestPayloadError(Exception): + """Payload parsing error.""" + + +class PayloadAccessError(Exception): + """Payload was accessed after response was sent.""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class _ErrInfo: + status: int + exc: BaseException + message: str + + +_MsgType = Tuple[Union[RawRequestMessage, _ErrInfo], StreamReader] + + +class RequestHandler(BaseProtocol): + """HTTP protocol implementation. + + RequestHandler handles incoming HTTP request. It reads request line, + request headers and request payload and calls handle_request() method. + By default it always returns with 404 response. + + RequestHandler handles errors in incoming request, like bad + status line, bad headers or incomplete payload. If any error occurs, + connection gets closed. + + keepalive_timeout -- number of seconds before closing + keep-alive connection + + tcp_keepalive -- TCP keep-alive is on, default is on + + debug -- enable debug mode + + logger -- custom logger object + + access_log_class -- custom class for access_logger + + access_log -- custom logging object + + access_log_format -- access log format string + + loop -- Optional event loop + + max_line_size -- Optional maximum header line size + + max_field_size -- Optional maximum header field size + + max_headers -- Optional maximum header size + + """ + + KEEPALIVE_RESCHEDULE_DELAY = 1 + + __slots__ = ( + "_request_count", + "_keepalive", + "_manager", + "_request_handler", + "_request_factory", + "_tcp_keepalive", + "_keepalive_time", + "_keepalive_handle", + "_keepalive_timeout", + "_lingering_time", + "_messages", + "_message_tail", + "_waiter", + "_task_handler", + "_upgrade", + "_payload_parser", + "_request_parser", + "_reading_paused", + "logger", + "debug", + "access_log", + "access_logger", + "_close", + "_force_close", + "_current_request", + ) + + def __init__( + self, + manager: "Server", + *, + loop: asyncio.AbstractEventLoop, + keepalive_timeout: float = 75.0, # NGINX default is 75 secs + tcp_keepalive: bool = True, + logger: Logger = server_logger, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log: Logger = access_logger, + access_log_format: str = AccessLogger.LOG_FORMAT, + debug: bool = False, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + lingering_time: float = 10.0, + read_bufsize: int = 2**16, + auto_decompress: bool = True, + ): + super().__init__(loop) + + self._request_count = 0 + self._keepalive = False + self._current_request: Optional[BaseRequest] = None + self._manager: Optional[Server] = manager + self._request_handler: Optional[_RequestHandler] = manager.request_handler + self._request_factory: Optional[_RequestFactory] = manager.request_factory + + self._tcp_keepalive = tcp_keepalive + # placeholder to be replaced on keepalive timeout setup + self._keepalive_time = 0.0 + self._keepalive_handle: Optional[asyncio.Handle] = None + self._keepalive_timeout = keepalive_timeout + self._lingering_time = float(lingering_time) + + self._messages: Deque[_MsgType] = deque() + self._message_tail = b"" + + self._waiter: Optional[asyncio.Future[None]] = None + self._task_handler: Optional[asyncio.Task[None]] = None + + self._upgrade = False + self._payload_parser: Any = None + self._request_parser: Optional[HttpRequestParser] = HttpRequestParser( + self, + loop, + read_bufsize, + max_line_size=max_line_size, + max_field_size=max_field_size, + max_headers=max_headers, + payload_exception=RequestPayloadError, + auto_decompress=auto_decompress, + ) + + self.logger = logger + self.debug = debug + self.access_log = access_log + if access_log: + self.access_logger: Optional[AbstractAccessLogger] = access_log_class( + access_log, access_log_format + ) + else: + self.access_logger = None + + self._close = False + self._force_close = False + + def __repr__(self) -> str: + return "<{} {}>".format( + self.__class__.__name__, + "connected" if self.transport is not None else "disconnected", + ) + + @property + def keepalive_timeout(self) -> float: + return self._keepalive_timeout + + async def shutdown(self, timeout: Optional[float] = 15.0) -> None: + """Do worker process exit preparations. + + We need to clean up everything and stop accepting requests. + It is especially important for keep-alive connections. + """ + self._force_close = True + + if self._keepalive_handle is not None: + self._keepalive_handle.cancel() + + if self._waiter: + self._waiter.cancel() + + # wait for handlers + with suppress(asyncio.CancelledError, asyncio.TimeoutError): + async with ceil_timeout(timeout): + if self._current_request is not None: + self._current_request._cancel(asyncio.CancelledError()) + + if self._task_handler is not None and not self._task_handler.done(): + await self._task_handler + + # force-close non-idle handler + if self._task_handler is not None: + self._task_handler.cancel() + + if self.transport is not None: + self.transport.close() + self.transport = None + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + super().connection_made(transport) + + real_transport = cast(asyncio.Transport, transport) + if self._tcp_keepalive: + tcp_keepalive(real_transport) + + self._task_handler = self._loop.create_task(self.start()) + assert self._manager is not None + self._manager.connection_made(self, real_transport) + + def connection_lost(self, exc: Optional[BaseException]) -> None: + if self._manager is None: + return + self._manager.connection_lost(self, exc) + + super().connection_lost(exc) + + self._manager = None + self._force_close = True + self._request_factory = None + self._request_handler = None + self._request_parser = None + + if self._keepalive_handle is not None: + self._keepalive_handle.cancel() + + if self._current_request is not None: + if exc is None: + exc = ConnectionResetError("Connection lost") + self._current_request._cancel(exc) + + if self._waiter is not None: + self._waiter.cancel() + + self._task_handler = None + + if self._payload_parser is not None: + self._payload_parser.feed_eof() + self._payload_parser = None + + def set_parser(self, parser: Any) -> None: + # Actual type is WebReader + assert self._payload_parser is None + + self._payload_parser = parser + + if self._message_tail: + self._payload_parser.feed_data(self._message_tail) + self._message_tail = b"" + + def eof_received(self) -> None: + pass + + def data_received(self, data: bytes) -> None: + if self._force_close or self._close: + return + # parse http messages + messages: Sequence[_MsgType] + if self._payload_parser is None and not self._upgrade: + assert self._request_parser is not None + try: + messages, upgraded, tail = self._request_parser.feed_data(data) + except HttpProcessingError as exc: + messages = [ + (_ErrInfo(status=400, exc=exc, message=exc.message), EMPTY_PAYLOAD) + ] + upgraded = False + tail = b"" + + for msg, payload in messages or (): + self._request_count += 1 + self._messages.append((msg, payload)) + + waiter = self._waiter + if messages and waiter is not None and not waiter.done(): + # don't set result twice + waiter.set_result(None) + + self._upgrade = upgraded + if upgraded and tail: + self._message_tail = tail + + # no parser, just store + elif self._payload_parser is None and self._upgrade and data: + self._message_tail += data + + # feed payload + elif data: + eof, tail = self._payload_parser.feed_data(data) + if eof: + self.close() + + def keep_alive(self, val: bool) -> None: + """Set keep-alive connection mode. + + :param bool val: new state. + """ + self._keepalive = val + if self._keepalive_handle: + self._keepalive_handle.cancel() + self._keepalive_handle = None + + def close(self) -> None: + """Close connection. + + Stop accepting new pipelining messages and close + connection when handlers done processing messages. + """ + self._close = True + if self._waiter: + self._waiter.cancel() + + def force_close(self) -> None: + """Forcefully close connection.""" + self._force_close = True + if self._waiter: + self._waiter.cancel() + if self.transport is not None: + self.transport.close() + self.transport = None + + def log_access( + self, request: BaseRequest, response: StreamResponse, time: float + ) -> None: + if self.access_logger is not None: + self.access_logger.log(request, response, self._loop.time() - time) + + def log_debug(self, *args: Any, **kw: Any) -> None: + if self.debug: + self.logger.debug(*args, **kw) + + def log_exception(self, *args: Any, **kw: Any) -> None: + self.logger.exception(*args, **kw) + + def _process_keepalive(self) -> None: + if self._force_close or not self._keepalive: + return + + next = self._keepalive_time + self._keepalive_timeout + + # handler in idle state + if self._waiter: + if self._loop.time() > next: + self.force_close() + return + + # not all request handlers are done, + # reschedule itself to next second + self._keepalive_handle = self._loop.call_later( + self.KEEPALIVE_RESCHEDULE_DELAY, self._process_keepalive + ) + + async def _handle_request( + self, + request: BaseRequest, + start_time: float, + request_handler: Callable[[BaseRequest], Awaitable[StreamResponse]], + ) -> Tuple[StreamResponse, bool]: + assert self._request_handler is not None + try: + try: + self._current_request = request + resp = await request_handler(request) + finally: + self._current_request = None + except HTTPException as exc: + resp = exc + reset = await self.finish_response(request, resp, start_time) + except asyncio.CancelledError: + raise + except asyncio.TimeoutError as exc: + self.log_debug("Request handler timed out.", exc_info=exc) + resp = self.handle_error(request, 504) + reset = await self.finish_response(request, resp, start_time) + except Exception as exc: + resp = self.handle_error(request, 500, exc) + reset = await self.finish_response(request, resp, start_time) + else: + # Deprecation warning (See #2415) + if getattr(resp, "__http_exception__", False): + warnings.warn( + "returning HTTPException object is deprecated " + "(#2415) and will be removed, " + "please raise the exception instead", + DeprecationWarning, + ) + + reset = await self.finish_response(request, resp, start_time) + + return resp, reset + + async def start(self) -> None: + """Process incoming request. + + It reads request line, request headers and request payload, then + calls handle_request() method. Subclass has to override + handle_request(). start() handles various exceptions in request + or response handling. Connection is being closed always unless + keep_alive(True) specified. + """ + loop = self._loop + handler = self._task_handler + assert handler is not None + manager = self._manager + assert manager is not None + keepalive_timeout = self._keepalive_timeout + resp = None + assert self._request_factory is not None + assert self._request_handler is not None + + while not self._force_close: + if not self._messages: + try: + # wait for next request + self._waiter = loop.create_future() + await self._waiter + except asyncio.CancelledError: + break + finally: + self._waiter = None + + message, payload = self._messages.popleft() + + start = loop.time() + + manager.requests_count += 1 + writer = StreamWriter(self, loop) + if isinstance(message, _ErrInfo): + # make request_factory work + request_handler = self._make_error_handler(message) + message = ERROR + else: + request_handler = self._request_handler + + request = self._request_factory(message, payload, self, writer, handler) + try: + # a new task is used for copy context vars (#3406) + task = self._loop.create_task( + self._handle_request(request, start, request_handler) + ) + try: + resp, reset = await task + except (asyncio.CancelledError, ConnectionError): + self.log_debug("Ignored premature client disconnection") + break + + # Drop the processed task from asyncio.Task.all_tasks() early + del task + if reset: + self.log_debug("Ignored premature client disconnection 2") + break + + # notify server about keep-alive + self._keepalive = bool(resp.keep_alive) + + # check payload + if not payload.is_eof(): + lingering_time = self._lingering_time + if not self._force_close and lingering_time: + self.log_debug( + "Start lingering close timer for %s sec.", lingering_time + ) + + now = loop.time() + end_t = now + lingering_time + + with suppress(asyncio.TimeoutError, asyncio.CancelledError): + while not payload.is_eof() and now < end_t: + async with ceil_timeout(end_t - now): + # read and ignore + await payload.readany() + now = loop.time() + + # if payload still uncompleted + if not payload.is_eof() and not self._force_close: + self.log_debug("Uncompleted request.") + self.close() + + payload.set_exception(PayloadAccessError()) + + except asyncio.CancelledError: + self.log_debug("Ignored premature client disconnection ") + break + except RuntimeError as exc: + if self.debug: + self.log_exception("Unhandled runtime exception", exc_info=exc) + self.force_close() + except Exception as exc: + self.log_exception("Unhandled exception", exc_info=exc) + self.force_close() + finally: + if self.transport is None and resp is not None: + self.log_debug("Ignored premature client disconnection.") + elif not self._force_close: + if self._keepalive and not self._close: + # start keep-alive timer + if keepalive_timeout is not None: + now = self._loop.time() + self._keepalive_time = now + if self._keepalive_handle is None: + self._keepalive_handle = loop.call_at( + now + keepalive_timeout, self._process_keepalive + ) + else: + break + + # remove handler, close transport if no handlers left + if not self._force_close: + self._task_handler = None + if self.transport is not None: + self.transport.close() + + async def finish_response( + self, request: BaseRequest, resp: StreamResponse, start_time: float + ) -> bool: + """Prepare the response and write_eof, then log access. + + This has to + be called within the context of any exception so the access logger + can get exception information. Returns True if the client disconnects + prematurely. + """ + if self._request_parser is not None: + self._request_parser.set_upgraded(False) + self._upgrade = False + if self._message_tail: + self._request_parser.feed_data(self._message_tail) + self._message_tail = b"" + try: + prepare_meth = resp.prepare + except AttributeError: + if resp is None: + raise RuntimeError("Missing return " "statement on request handler") + else: + raise RuntimeError( + "Web-handler should return " + "a response instance, " + "got {!r}".format(resp) + ) + try: + await prepare_meth(request) + await resp.write_eof() + except ConnectionError: + self.log_access(request, resp, start_time) + return True + else: + self.log_access(request, resp, start_time) + return False + + def handle_error( + self, + request: BaseRequest, + status: int = 500, + exc: Optional[BaseException] = None, + message: Optional[str] = None, + ) -> StreamResponse: + """Handle errors. + + Returns HTTP response with specific status code. Logs additional + information. It always closes current connection. + """ + self.log_exception("Error handling request", exc_info=exc) + + # some data already got sent, connection is broken + if request.writer.output_size > 0: + raise ConnectionError( + "Response is sent already, cannot send another response " + "with the error message" + ) + + ct = "text/plain" + if status == HTTPStatus.INTERNAL_SERVER_ERROR: + title = "{0.value} {0.phrase}".format(HTTPStatus.INTERNAL_SERVER_ERROR) + msg = HTTPStatus.INTERNAL_SERVER_ERROR.description + tb = None + if self.debug: + with suppress(Exception): + tb = traceback.format_exc() + + if "text/html" in request.headers.get("Accept", ""): + if tb: + tb = html_escape(tb) + msg = f"

Traceback:

\n
{tb}
" + message = ( + "" + "{title}" + "\n

{title}

" + "\n{msg}\n\n" + ).format(title=title, msg=msg) + ct = "text/html" + else: + if tb: + msg = tb + message = title + "\n\n" + msg + + resp = Response(status=status, text=message, content_type=ct) + resp.force_close() + + return resp + + def _make_error_handler( + self, err_info: _ErrInfo + ) -> Callable[[BaseRequest], Awaitable[StreamResponse]]: + async def handler(request: BaseRequest) -> StreamResponse: + return self.handle_error( + request, err_info.status, err_info.exc, err_info.message + ) + + return handler diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_request.py b/.venv/lib/python3.7/site-packages/aiohttp/web_request.py new file mode 100644 index 0000000..c02ebfc --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_request.py @@ -0,0 +1,882 @@ +import asyncio +import datetime +import io +import re +import socket +import string +import tempfile +import types +import warnings +from http.cookies import SimpleCookie +from types import MappingProxyType +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterator, + Mapping, + MutableMapping, + Optional, + Pattern, + Tuple, + Union, + cast, +) +from urllib.parse import parse_qsl + +import attr +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +from yarl import URL + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import ( + DEBUG, + ETAG_ANY, + LIST_QUOTED_ETAG_RE, + ChainMapProxy, + ETag, + HeadersMixin, + parse_http_date, + reify, + sentinel, +) +from .http_parser import RawRequestMessage +from .http_writer import HttpVersion +from .multipart import BodyPartReader, MultipartReader +from .streams import EmptyStreamReader, StreamReader +from .typedefs import ( + DEFAULT_JSON_DECODER, + Final, + JSONDecoder, + LooseHeaders, + RawHeaders, + StrOrURL, +) +from .web_exceptions import HTTPRequestEntityTooLarge +from .web_response import StreamResponse + +__all__ = ("BaseRequest", "FileField", "Request") + + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + from .web_protocol import RequestHandler + from .web_urldispatcher import UrlMappingMatchInfo + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class FileField: + name: str + filename: str + file: io.BufferedReader + content_type: str + headers: "CIMultiDictProxy[str]" + + +_TCHAR: Final[str] = string.digits + string.ascii_letters + r"!#$%&'*+.^_`|~-" +# '-' at the end to prevent interpretation as range in a char class + +_TOKEN: Final[str] = rf"[{_TCHAR}]+" + +_QDTEXT: Final[str] = r"[{}]".format( + r"".join(chr(c) for c in (0x09, 0x20, 0x21) + tuple(range(0x23, 0x7F))) +) +# qdtext includes 0x5C to escape 0x5D ('\]') +# qdtext excludes obs-text (because obsoleted, and encoding not specified) + +_QUOTED_PAIR: Final[str] = r"\\[\t !-~]" + +_QUOTED_STRING: Final[str] = r'"(?:{quoted_pair}|{qdtext})*"'.format( + qdtext=_QDTEXT, quoted_pair=_QUOTED_PAIR +) + +_FORWARDED_PAIR: Final[ + str +] = r"({token})=({token}|{quoted_string})(:\d{{1,4}})?".format( + token=_TOKEN, quoted_string=_QUOTED_STRING +) + +_QUOTED_PAIR_REPLACE_RE: Final[Pattern[str]] = re.compile(r"\\([\t !-~])") +# same pattern as _QUOTED_PAIR but contains a capture group + +_FORWARDED_PAIR_RE: Final[Pattern[str]] = re.compile(_FORWARDED_PAIR) + +############################################################ +# HTTP Request +############################################################ + + +class BaseRequest(MutableMapping[str, Any], HeadersMixin): + + POST_METHODS = { + hdrs.METH_PATCH, + hdrs.METH_POST, + hdrs.METH_PUT, + hdrs.METH_TRACE, + hdrs.METH_DELETE, + } + + ATTRS = HeadersMixin.ATTRS | frozenset( + [ + "_message", + "_protocol", + "_payload_writer", + "_payload", + "_headers", + "_method", + "_version", + "_rel_url", + "_post", + "_read_bytes", + "_state", + "_cache", + "_task", + "_client_max_size", + "_loop", + "_transport_sslcontext", + "_transport_peername", + ] + ) + + def __init__( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: "RequestHandler", + payload_writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + loop: asyncio.AbstractEventLoop, + *, + client_max_size: int = 1024**2, + state: Optional[Dict[str, Any]] = None, + scheme: Optional[str] = None, + host: Optional[str] = None, + remote: Optional[str] = None, + ) -> None: + if state is None: + state = {} + self._message = message + self._protocol = protocol + self._payload_writer = payload_writer + + self._payload = payload + self._headers = message.headers + self._method = message.method + self._version = message.version + self._cache: Dict[str, Any] = {} + url = message.url + if url.is_absolute(): + # absolute URL is given, + # override auto-calculating url, host, and scheme + # all other properties should be good + self._cache["url"] = url + self._cache["host"] = url.host + self._cache["scheme"] = url.scheme + self._rel_url = url.relative() + else: + self._rel_url = message.url + self._post: Optional[MultiDictProxy[Union[str, bytes, FileField]]] = None + self._read_bytes: Optional[bytes] = None + + self._state = state + self._task = task + self._client_max_size = client_max_size + self._loop = loop + + transport = self._protocol.transport + assert transport is not None + self._transport_sslcontext = transport.get_extra_info("sslcontext") + self._transport_peername = transport.get_extra_info("peername") + + if scheme is not None: + self._cache["scheme"] = scheme + if host is not None: + self._cache["host"] = host + if remote is not None: + self._cache["remote"] = remote + + def clone( + self, + *, + method: str = sentinel, + rel_url: StrOrURL = sentinel, + headers: LooseHeaders = sentinel, + scheme: str = sentinel, + host: str = sentinel, + remote: str = sentinel, + ) -> "BaseRequest": + """Clone itself with replacement some attributes. + + Creates and returns a new instance of Request object. If no parameters + are given, an exact copy is returned. If a parameter is not passed, it + will reuse the one from the current request object. + """ + if self._read_bytes: + raise RuntimeError("Cannot clone request " "after reading its content") + + dct: Dict[str, Any] = {} + if method is not sentinel: + dct["method"] = method + if rel_url is not sentinel: + new_url = URL(rel_url) + dct["url"] = new_url + dct["path"] = str(new_url) + if headers is not sentinel: + # a copy semantic + dct["headers"] = CIMultiDictProxy(CIMultiDict(headers)) + dct["raw_headers"] = tuple( + (k.encode("utf-8"), v.encode("utf-8")) for k, v in headers.items() + ) + + message = self._message._replace(**dct) + + kwargs = {} + if scheme is not sentinel: + kwargs["scheme"] = scheme + if host is not sentinel: + kwargs["host"] = host + if remote is not sentinel: + kwargs["remote"] = remote + + return self.__class__( + message, + self._payload, + self._protocol, + self._payload_writer, + self._task, + self._loop, + client_max_size=self._client_max_size, + state=self._state.copy(), + **kwargs, + ) + + @property + def task(self) -> "asyncio.Task[None]": + return self._task + + @property + def protocol(self) -> "RequestHandler": + return self._protocol + + @property + def transport(self) -> Optional[asyncio.Transport]: + if self._protocol is None: + return None + return self._protocol.transport + + @property + def writer(self) -> AbstractStreamWriter: + return self._payload_writer + + @reify + def message(self) -> RawRequestMessage: + warnings.warn("Request.message is deprecated", DeprecationWarning, stacklevel=3) + return self._message + + @reify + def rel_url(self) -> URL: + return self._rel_url + + @reify + def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn( + "request.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + # MutableMapping API + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def __setitem__(self, key: str, value: Any) -> None: + self._state[key] = value + + def __delitem__(self, key: str) -> None: + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + ######## + + @reify + def secure(self) -> bool: + """A bool indicating if the request is handled with SSL.""" + return self.scheme == "https" + + @reify + def forwarded(self) -> Tuple[Mapping[str, str], ...]: + """A tuple containing all parsed Forwarded header(s). + + Makes an effort to parse Forwarded headers as specified by RFC 7239: + + - It adds one (immutable) dictionary per Forwarded 'field-value', ie + per proxy. The element corresponds to the data in the Forwarded + field-value added by the first proxy encountered by the client. Each + subsequent item corresponds to those added by later proxies. + - It checks that every value has valid syntax in general as specified + in section 4: either a 'token' or a 'quoted-string'. + - It un-escapes found escape sequences. + - It does NOT validate 'by' and 'for' contents as specified in section + 6. + - It does NOT validate 'host' contents (Host ABNF). + - It does NOT validate 'proto' contents for valid URI scheme names. + + Returns a tuple containing one or more immutable dicts + """ + elems = [] + for field_value in self._message.headers.getall(hdrs.FORWARDED, ()): + length = len(field_value) + pos = 0 + need_separator = False + elem: Dict[str, str] = {} + elems.append(types.MappingProxyType(elem)) + while 0 <= pos < length: + match = _FORWARDED_PAIR_RE.match(field_value, pos) + if match is not None: # got a valid forwarded-pair + if need_separator: + # bad syntax here, skip to next comma + pos = field_value.find(",", pos) + else: + name, value, port = match.groups() + if value[0] == '"': + # quoted string: remove quotes and unescape + value = _QUOTED_PAIR_REPLACE_RE.sub(r"\1", value[1:-1]) + if port: + value += port + elem[name.lower()] = value + pos += len(match.group(0)) + need_separator = True + elif field_value[pos] == ",": # next forwarded-element + need_separator = False + elem = {} + elems.append(types.MappingProxyType(elem)) + pos += 1 + elif field_value[pos] == ";": # next forwarded-pair + need_separator = False + pos += 1 + elif field_value[pos] in " \t": + # Allow whitespace even between forwarded-pairs, though + # RFC 7239 doesn't. This simplifies code and is in line + # with Postel's law. + pos += 1 + else: + # bad syntax here, skip to next comma + pos = field_value.find(",", pos) + return tuple(elems) + + @reify + def scheme(self) -> str: + """A string representing the scheme of the request. + + Hostname is resolved in this order: + + - overridden value by .clone(scheme=new_scheme) call. + - type of connection to peer: HTTPS if socket is SSL, HTTP otherwise. + + 'http' or 'https'. + """ + if self._transport_sslcontext: + return "https" + else: + return "http" + + @reify + def method(self) -> str: + """Read only property for getting HTTP method. + + The value is upper-cased str like 'GET', 'POST', 'PUT' etc. + """ + return self._method + + @reify + def version(self) -> HttpVersion: + """Read only property for getting HTTP version of request. + + Returns aiohttp.protocol.HttpVersion instance. + """ + return self._version + + @reify + def host(self) -> str: + """Hostname of the request. + + Hostname is resolved in this order: + + - overridden value by .clone(host=new_host) call. + - HOST HTTP header + - socket.getfqdn() value + """ + host = self._message.headers.get(hdrs.HOST) + if host is not None: + return host + return socket.getfqdn() + + @reify + def remote(self) -> Optional[str]: + """Remote IP of client initiated HTTP request. + + The IP is resolved in this order: + + - overridden value by .clone(remote=new_remote) call. + - peername of opened socket + """ + if self._transport_peername is None: + return None + if isinstance(self._transport_peername, (list, tuple)): + return str(self._transport_peername[0]) + return str(self._transport_peername) + + @reify + def url(self) -> URL: + url = URL.build(scheme=self.scheme, host=self.host) + return url.join(self._rel_url) + + @reify + def path(self) -> str: + """The URL including *PATH INFO* without the host or scheme. + + E.g., ``/app/blog`` + """ + return self._rel_url.path + + @reify + def path_qs(self) -> str: + """The URL including PATH_INFO and the query string. + + E.g, /app/blog?id=10 + """ + return str(self._rel_url) + + @reify + def raw_path(self) -> str: + """The URL including raw *PATH INFO* without the host or scheme. + + Warning, the path is unquoted and may contains non valid URL characters + + E.g., ``/my%2Fpath%7Cwith%21some%25strange%24characters`` + """ + return self._message.path + + @reify + def query(self) -> "MultiDictProxy[str]": + """A multidict with all the variables in the query string.""" + return MultiDictProxy(self._rel_url.query) + + @reify + def query_string(self) -> str: + """The query string in the URL. + + E.g., id=10 + """ + return self._rel_url.query_string + + @reify + def headers(self) -> "CIMultiDictProxy[str]": + """A case-insensitive multidict proxy with all headers.""" + return self._headers + + @reify + def raw_headers(self) -> RawHeaders: + """A sequence of pairs for all headers.""" + return self._message.raw_headers + + @reify + def if_modified_since(self) -> Optional[datetime.datetime]: + """The value of If-Modified-Since HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return parse_http_date(self.headers.get(hdrs.IF_MODIFIED_SINCE)) + + @reify + def if_unmodified_since(self) -> Optional[datetime.datetime]: + """The value of If-Unmodified-Since HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return parse_http_date(self.headers.get(hdrs.IF_UNMODIFIED_SINCE)) + + @staticmethod + def _etag_values(etag_header: str) -> Iterator[ETag]: + """Extract `ETag` objects from raw header.""" + if etag_header == ETAG_ANY: + yield ETag( + is_weak=False, + value=ETAG_ANY, + ) + else: + for match in LIST_QUOTED_ETAG_RE.finditer(etag_header): + is_weak, value, garbage = match.group(2, 3, 4) + # Any symbol captured by 4th group means + # that the following sequence is invalid. + if garbage: + break + + yield ETag( + is_weak=bool(is_weak), + value=value, + ) + + @classmethod + def _if_match_or_none_impl( + cls, header_value: Optional[str] + ) -> Optional[Tuple[ETag, ...]]: + if not header_value: + return None + + return tuple(cls._etag_values(header_value)) + + @reify + def if_match(self) -> Optional[Tuple[ETag, ...]]: + """The value of If-Match HTTP header, or None. + + This header is represented as a `tuple` of `ETag` objects. + """ + return self._if_match_or_none_impl(self.headers.get(hdrs.IF_MATCH)) + + @reify + def if_none_match(self) -> Optional[Tuple[ETag, ...]]: + """The value of If-None-Match HTTP header, or None. + + This header is represented as a `tuple` of `ETag` objects. + """ + return self._if_match_or_none_impl(self.headers.get(hdrs.IF_NONE_MATCH)) + + @reify + def if_range(self) -> Optional[datetime.datetime]: + """The value of If-Range HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return parse_http_date(self.headers.get(hdrs.IF_RANGE)) + + @reify + def keep_alive(self) -> bool: + """Is keepalive enabled by client?""" + return not self._message.should_close + + @reify + def cookies(self) -> Mapping[str, str]: + """Return request cookies. + + A read-only dictionary-like object. + """ + raw = self.headers.get(hdrs.COOKIE, "") + parsed: SimpleCookie[str] = SimpleCookie(raw) + return MappingProxyType({key: val.value for key, val in parsed.items()}) + + @reify + def http_range(self) -> slice: + """The content of Range HTTP header. + + Return a slice instance. + + """ + rng = self._headers.get(hdrs.RANGE) + start, end = None, None + if rng is not None: + try: + pattern = r"^bytes=(\d*)-(\d*)$" + start, end = re.findall(pattern, rng)[0] + except IndexError: # pattern was not found in header + raise ValueError("range not in acceptable format") + + end = int(end) if end else None + start = int(start) if start else None + + if start is None and end is not None: + # end with no start is to return tail of content + start = -end + end = None + + if start is not None and end is not None: + # end is inclusive in range header, exclusive for slice + end += 1 + + if start >= end: + raise ValueError("start cannot be after end") + + if start is end is None: # No valid range supplied + raise ValueError("No start or end of range specified") + + return slice(start, end, 1) + + @reify + def content(self) -> StreamReader: + """Return raw payload stream.""" + return self._payload + + @property + def has_body(self) -> bool: + """Return True if request's HTTP BODY can be read, False otherwise.""" + warnings.warn( + "Deprecated, use .can_read_body #2005", DeprecationWarning, stacklevel=2 + ) + return not self._payload.at_eof() + + @property + def can_read_body(self) -> bool: + """Return True if request's HTTP BODY can be read, False otherwise.""" + return not self._payload.at_eof() + + @reify + def body_exists(self) -> bool: + """Return True if request has HTTP BODY, False otherwise.""" + return type(self._payload) is not EmptyStreamReader + + async def release(self) -> None: + """Release request. + + Eat unread part of HTTP BODY if present. + """ + while not self._payload.at_eof(): + await self._payload.readany() + + async def read(self) -> bytes: + """Read request body if present. + + Returns bytes object with full request content. + """ + if self._read_bytes is None: + body = bytearray() + while True: + chunk = await self._payload.readany() + body.extend(chunk) + if self._client_max_size: + body_size = len(body) + if body_size >= self._client_max_size: + raise HTTPRequestEntityTooLarge( + max_size=self._client_max_size, actual_size=body_size + ) + if not chunk: + break + self._read_bytes = bytes(body) + return self._read_bytes + + async def text(self) -> str: + """Return BODY as text using encoding from .charset.""" + bytes_body = await self.read() + encoding = self.charset or "utf-8" + return bytes_body.decode(encoding) + + async def json(self, *, loads: JSONDecoder = DEFAULT_JSON_DECODER) -> Any: + """Return BODY as JSON.""" + body = await self.text() + return loads(body) + + async def multipart(self) -> MultipartReader: + """Return async iterator to process BODY as multipart.""" + return MultipartReader(self._headers, self._payload) + + async def post(self) -> "MultiDictProxy[Union[str, bytes, FileField]]": + """Return POST parameters.""" + if self._post is not None: + return self._post + if self._method not in self.POST_METHODS: + self._post = MultiDictProxy(MultiDict()) + return self._post + + content_type = self.content_type + if content_type not in ( + "", + "application/x-www-form-urlencoded", + "multipart/form-data", + ): + self._post = MultiDictProxy(MultiDict()) + return self._post + + out: MultiDict[Union[str, bytes, FileField]] = MultiDict() + + if content_type == "multipart/form-data": + multipart = await self.multipart() + max_size = self._client_max_size + + field = await multipart.next() + while field is not None: + size = 0 + field_ct = field.headers.get(hdrs.CONTENT_TYPE) + + if isinstance(field, BodyPartReader): + assert field.name is not None + + # Note that according to RFC 7578, the Content-Type header + # is optional, even for files, so we can't assume it's + # present. + # https://tools.ietf.org/html/rfc7578#section-4.4 + if field.filename: + # store file in temp file + tmp = tempfile.TemporaryFile() + chunk = await field.read_chunk(size=2**16) + while chunk: + chunk = field.decode(chunk) + tmp.write(chunk) + size += len(chunk) + if 0 < max_size < size: + tmp.close() + raise HTTPRequestEntityTooLarge( + max_size=max_size, actual_size=size + ) + chunk = await field.read_chunk(size=2**16) + tmp.seek(0) + + if field_ct is None: + field_ct = "application/octet-stream" + + ff = FileField( + field.name, + field.filename, + cast(io.BufferedReader, tmp), + field_ct, + field.headers, + ) + out.add(field.name, ff) + else: + # deal with ordinary data + value = await field.read(decode=True) + if field_ct is None or field_ct.startswith("text/"): + charset = field.get_charset(default="utf-8") + out.add(field.name, value.decode(charset)) + else: + out.add(field.name, value) + size += len(value) + if 0 < max_size < size: + raise HTTPRequestEntityTooLarge( + max_size=max_size, actual_size=size + ) + else: + raise ValueError( + "To decode nested multipart you need " "to use custom reader", + ) + + field = await multipart.next() + else: + data = await self.read() + if data: + charset = self.charset or "utf-8" + out.extend( + parse_qsl( + data.rstrip().decode(charset), + keep_blank_values=True, + encoding=charset, + ) + ) + + self._post = MultiDictProxy(out) + return self._post + + def get_extra_info(self, name: str, default: Any = None) -> Any: + """Extra info from protocol transport""" + protocol = self._protocol + if protocol is None: + return default + + transport = protocol.transport + if transport is None: + return default + + return transport.get_extra_info(name, default) + + def __repr__(self) -> str: + ascii_encodable_path = self.path.encode("ascii", "backslashreplace").decode( + "ascii" + ) + return "<{} {} {} >".format( + self.__class__.__name__, self._method, ascii_encodable_path + ) + + def __eq__(self, other: object) -> bool: + return id(self) == id(other) + + def __bool__(self) -> bool: + return True + + async def _prepare_hook(self, response: StreamResponse) -> None: + return + + def _cancel(self, exc: BaseException) -> None: + self._payload.set_exception(exc) + + +class Request(BaseRequest): + + ATTRS = BaseRequest.ATTRS | frozenset(["_match_info"]) + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + # matchdict, route_name, handler + # or information about traversal lookup + + # initialized after route resolving + self._match_info: Optional[UrlMappingMatchInfo] = None + + if DEBUG: + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom {}.{} attribute " + "is discouraged".format(self.__class__.__name__, name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + def clone( + self, + *, + method: str = sentinel, + rel_url: StrOrURL = sentinel, + headers: LooseHeaders = sentinel, + scheme: str = sentinel, + host: str = sentinel, + remote: str = sentinel, + ) -> "Request": + ret = super().clone( + method=method, + rel_url=rel_url, + headers=headers, + scheme=scheme, + host=host, + remote=remote, + ) + new_ret = cast(Request, ret) + new_ret._match_info = self._match_info + return new_ret + + @reify + def match_info(self) -> "UrlMappingMatchInfo": + """Result of route resolving.""" + match_info = self._match_info + assert match_info is not None + return match_info + + @property + def app(self) -> "Application": + """Application instance.""" + match_info = self._match_info + assert match_info is not None + return match_info.current_app + + @property + def config_dict(self) -> ChainMapProxy: + match_info = self._match_info + assert match_info is not None + lst = match_info.apps + app = self.app + idx = lst.index(app) + sublist = list(reversed(lst[: idx + 1])) + return ChainMapProxy(sublist) + + async def _prepare_hook(self, response: StreamResponse) -> None: + match_info = self._match_info + if match_info is None: + return + for app in match_info._apps: + await app.on_response_prepare.send(self, response) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_response.py b/.venv/lib/python3.7/site-packages/aiohttp/web_response.py new file mode 100644 index 0000000..ce07f81 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_response.py @@ -0,0 +1,825 @@ +import asyncio +import collections.abc +import datetime +import enum +import json +import math +import time +import warnings +import zlib +from concurrent.futures import Executor +from http.cookies import Morsel, SimpleCookie +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterator, + Mapping, + MutableMapping, + Optional, + Tuple, + Union, + cast, +) + +from multidict import CIMultiDict, istr + +from . import hdrs, payload +from .abc import AbstractStreamWriter +from .helpers import ( + ETAG_ANY, + PY_38, + QUOTED_ETAG_RE, + ETag, + HeadersMixin, + parse_http_date, + rfc822_formatted_time, + sentinel, + validate_etag_value, +) +from .http import RESPONSES, SERVER_SOFTWARE, HttpVersion10, HttpVersion11 +from .payload import Payload +from .typedefs import JSONEncoder, LooseHeaders + +__all__ = ("ContentCoding", "StreamResponse", "Response", "json_response") + + +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest + + BaseClass = MutableMapping[str, Any] +else: + BaseClass = collections.abc.MutableMapping + + +if not PY_38: + # allow samesite to be used in python < 3.8 + # already permitted in python 3.8, see https://bugs.python.org/issue29613 + Morsel._reserved["samesite"] = "SameSite" # type: ignore[attr-defined] + + +class ContentCoding(enum.Enum): + # The content codings that we have support for. + # + # Additional registered codings are listed at: + # https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding + deflate = "deflate" + gzip = "gzip" + identity = "identity" + + +############################################################ +# HTTP Response classes +############################################################ + + +class StreamResponse(BaseClass, HeadersMixin): + + _length_check = True + + def __init__( + self, + *, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + ) -> None: + self._body = None + self._keep_alive: Optional[bool] = None + self._chunked = False + self._compression = False + self._compression_force: Optional[ContentCoding] = None + self._cookies: SimpleCookie[str] = SimpleCookie() + + self._req: Optional[BaseRequest] = None + self._payload_writer: Optional[AbstractStreamWriter] = None + self._eof_sent = False + self._body_length = 0 + self._state: Dict[str, Any] = {} + + if headers is not None: + self._headers: CIMultiDict[str] = CIMultiDict(headers) + else: + self._headers = CIMultiDict() + + self.set_status(status, reason) + + @property + def prepared(self) -> bool: + return self._payload_writer is not None + + @property + def task(self) -> "Optional[asyncio.Task[None]]": + if self._req: + return self._req.task + else: + return None + + @property + def status(self) -> int: + return self._status + + @property + def chunked(self) -> bool: + return self._chunked + + @property + def compression(self) -> bool: + return self._compression + + @property + def reason(self) -> str: + return self._reason + + def set_status( + self, + status: int, + reason: Optional[str] = None, + _RESPONSES: Mapping[int, Tuple[str, str]] = RESPONSES, + ) -> None: + assert not self.prepared, ( + "Cannot change the response status code after " "the headers have been sent" + ) + self._status = int(status) + if reason is None: + try: + reason = _RESPONSES[self._status][0] + except Exception: + reason = "" + self._reason = reason + + @property + def keep_alive(self) -> Optional[bool]: + return self._keep_alive + + def force_close(self) -> None: + self._keep_alive = False + + @property + def body_length(self) -> int: + return self._body_length + + @property + def output_length(self) -> int: + warnings.warn("output_length is deprecated", DeprecationWarning) + assert self._payload_writer + return self._payload_writer.buffer_size + + def enable_chunked_encoding(self, chunk_size: Optional[int] = None) -> None: + """Enables automatic chunked transfer encoding.""" + self._chunked = True + + if hdrs.CONTENT_LENGTH in self._headers: + raise RuntimeError( + "You can't enable chunked encoding when " "a content length is set" + ) + if chunk_size is not None: + warnings.warn("Chunk size is deprecated #1615", DeprecationWarning) + + def enable_compression( + self, force: Optional[Union[bool, ContentCoding]] = None + ) -> None: + """Enables response compression encoding.""" + # Backwards compatibility for when force was a bool <0.17. + if type(force) == bool: + force = ContentCoding.deflate if force else ContentCoding.identity + warnings.warn( + "Using boolean for force is deprecated #3318", DeprecationWarning + ) + elif force is not None: + assert isinstance(force, ContentCoding), ( + "force should one of " "None, bool or " "ContentEncoding" + ) + + self._compression = True + self._compression_force = force + + @property + def headers(self) -> "CIMultiDict[str]": + return self._headers + + @property + def cookies(self) -> "SimpleCookie[str]": + return self._cookies + + def set_cookie( + self, + name: str, + value: str, + *, + expires: Optional[str] = None, + domain: Optional[str] = None, + max_age: Optional[Union[int, str]] = None, + path: str = "/", + secure: Optional[bool] = None, + httponly: Optional[bool] = None, + version: Optional[str] = None, + samesite: Optional[str] = None, + ) -> None: + """Set or update response cookie. + + Sets new cookie or updates existent with new value. + Also updates only those params which are not None. + """ + old = self._cookies.get(name) + if old is not None and old.coded_value == "": + # deleted cookie + self._cookies.pop(name, None) + + self._cookies[name] = value + c = self._cookies[name] + + if expires is not None: + c["expires"] = expires + elif c.get("expires") == "Thu, 01 Jan 1970 00:00:00 GMT": + del c["expires"] + + if domain is not None: + c["domain"] = domain + + if max_age is not None: + c["max-age"] = str(max_age) + elif "max-age" in c: + del c["max-age"] + + c["path"] = path + + if secure is not None: + c["secure"] = secure + if httponly is not None: + c["httponly"] = httponly + if version is not None: + c["version"] = version + if samesite is not None: + c["samesite"] = samesite + + def del_cookie( + self, name: str, *, domain: Optional[str] = None, path: str = "/" + ) -> None: + """Delete cookie. + + Creates new empty expired cookie. + """ + # TODO: do we need domain/path here? + self._cookies.pop(name, None) + self.set_cookie( + name, + "", + max_age=0, + expires="Thu, 01 Jan 1970 00:00:00 GMT", + domain=domain, + path=path, + ) + + @property + def content_length(self) -> Optional[int]: + # Just a placeholder for adding setter + return super().content_length + + @content_length.setter + def content_length(self, value: Optional[int]) -> None: + if value is not None: + value = int(value) + if self._chunked: + raise RuntimeError( + "You can't set content length when " "chunked encoding is enable" + ) + self._headers[hdrs.CONTENT_LENGTH] = str(value) + else: + self._headers.pop(hdrs.CONTENT_LENGTH, None) + + @property + def content_type(self) -> str: + # Just a placeholder for adding setter + return super().content_type + + @content_type.setter + def content_type(self, value: str) -> None: + self.content_type # read header values if needed + self._content_type = str(value) + self._generate_content_type_header() + + @property + def charset(self) -> Optional[str]: + # Just a placeholder for adding setter + return super().charset + + @charset.setter + def charset(self, value: Optional[str]) -> None: + ctype = self.content_type # read header values if needed + if ctype == "application/octet-stream": + raise RuntimeError( + "Setting charset for application/octet-stream " + "doesn't make sense, setup content_type first" + ) + assert self._content_dict is not None + if value is None: + self._content_dict.pop("charset", None) + else: + self._content_dict["charset"] = str(value).lower() + self._generate_content_type_header() + + @property + def last_modified(self) -> Optional[datetime.datetime]: + """The value of Last-Modified HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return parse_http_date(self._headers.get(hdrs.LAST_MODIFIED)) + + @last_modified.setter + def last_modified( + self, value: Optional[Union[int, float, datetime.datetime, str]] + ) -> None: + if value is None: + self._headers.pop(hdrs.LAST_MODIFIED, None) + elif isinstance(value, (int, float)): + self._headers[hdrs.LAST_MODIFIED] = time.strftime( + "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(math.ceil(value)) + ) + elif isinstance(value, datetime.datetime): + self._headers[hdrs.LAST_MODIFIED] = time.strftime( + "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple() + ) + elif isinstance(value, str): + self._headers[hdrs.LAST_MODIFIED] = value + + @property + def etag(self) -> Optional[ETag]: + quoted_value = self._headers.get(hdrs.ETAG) + if not quoted_value: + return None + elif quoted_value == ETAG_ANY: + return ETag(value=ETAG_ANY) + match = QUOTED_ETAG_RE.fullmatch(quoted_value) + if not match: + return None + is_weak, value = match.group(1, 2) + return ETag( + is_weak=bool(is_weak), + value=value, + ) + + @etag.setter + def etag(self, value: Optional[Union[ETag, str]]) -> None: + if value is None: + self._headers.pop(hdrs.ETAG, None) + elif (isinstance(value, str) and value == ETAG_ANY) or ( + isinstance(value, ETag) and value.value == ETAG_ANY + ): + self._headers[hdrs.ETAG] = ETAG_ANY + elif isinstance(value, str): + validate_etag_value(value) + self._headers[hdrs.ETAG] = f'"{value}"' + elif isinstance(value, ETag) and isinstance(value.value, str): + validate_etag_value(value.value) + hdr_value = f'W/"{value.value}"' if value.is_weak else f'"{value.value}"' + self._headers[hdrs.ETAG] = hdr_value + else: + raise ValueError( + f"Unsupported etag type: {type(value)}. " + f"etag must be str, ETag or None" + ) + + def _generate_content_type_header( + self, CONTENT_TYPE: istr = hdrs.CONTENT_TYPE + ) -> None: + assert self._content_dict is not None + assert self._content_type is not None + params = "; ".join(f"{k}={v}" for k, v in self._content_dict.items()) + if params: + ctype = self._content_type + "; " + params + else: + ctype = self._content_type + self._headers[CONTENT_TYPE] = ctype + + async def _do_start_compression(self, coding: ContentCoding) -> None: + if coding != ContentCoding.identity: + assert self._payload_writer is not None + self._headers[hdrs.CONTENT_ENCODING] = coding.value + self._payload_writer.enable_compression(coding.value) + # Compressed payload may have different content length, + # remove the header + self._headers.popall(hdrs.CONTENT_LENGTH, None) + + async def _start_compression(self, request: "BaseRequest") -> None: + if self._compression_force: + await self._do_start_compression(self._compression_force) + else: + accept_encoding = request.headers.get(hdrs.ACCEPT_ENCODING, "").lower() + for coding in ContentCoding: + if coding.value in accept_encoding: + await self._do_start_compression(coding) + return + + async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: + if self._eof_sent: + return None + if self._payload_writer is not None: + return self._payload_writer + + return await self._start(request) + + async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: + self._req = request + writer = self._payload_writer = request._payload_writer + + await self._prepare_headers() + await request._prepare_hook(self) + await self._write_headers() + + return writer + + async def _prepare_headers(self) -> None: + request = self._req + assert request is not None + writer = self._payload_writer + assert writer is not None + keep_alive = self._keep_alive + if keep_alive is None: + keep_alive = request.keep_alive + self._keep_alive = keep_alive + + version = request.version + + headers = self._headers + for cookie in self._cookies.values(): + value = cookie.output(header="")[1:] + headers.add(hdrs.SET_COOKIE, value) + + if self._compression: + await self._start_compression(request) + + if self._chunked: + if version != HttpVersion11: + raise RuntimeError( + "Using chunked encoding is forbidden " + "for HTTP/{0.major}.{0.minor}".format(request.version) + ) + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] + elif self._length_check: + writer.length = self.content_length + if writer.length is None: + if version >= HttpVersion11 and self.status != 204: + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] + else: + keep_alive = False + # HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2 + # HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4 + elif version >= HttpVersion11 and self.status in (100, 101, 102, 103, 204): + del headers[hdrs.CONTENT_LENGTH] + + if self.status not in (204, 304): + headers.setdefault(hdrs.CONTENT_TYPE, "application/octet-stream") + headers.setdefault(hdrs.DATE, rfc822_formatted_time()) + headers.setdefault(hdrs.SERVER, SERVER_SOFTWARE) + + # connection header + if hdrs.CONNECTION not in headers: + if keep_alive: + if version == HttpVersion10: + headers[hdrs.CONNECTION] = "keep-alive" + else: + if version == HttpVersion11: + headers[hdrs.CONNECTION] = "close" + + async def _write_headers(self) -> None: + request = self._req + assert request is not None + writer = self._payload_writer + assert writer is not None + # status line + version = request.version + status_line = "HTTP/{}.{} {} {}".format( + version[0], version[1], self._status, self._reason + ) + await writer.write_headers(status_line, self._headers) + + async def write(self, data: bytes) -> None: + assert isinstance( + data, (bytes, bytearray, memoryview) + ), "data argument must be byte-ish (%r)" % type(data) + + if self._eof_sent: + raise RuntimeError("Cannot call write() after write_eof()") + if self._payload_writer is None: + raise RuntimeError("Cannot call write() before prepare()") + + await self._payload_writer.write(data) + + async def drain(self) -> None: + assert not self._eof_sent, "EOF has already been sent" + assert self._payload_writer is not None, "Response has not been started" + warnings.warn( + "drain method is deprecated, use await resp.write()", + DeprecationWarning, + stacklevel=2, + ) + await self._payload_writer.drain() + + async def write_eof(self, data: bytes = b"") -> None: + assert isinstance( + data, (bytes, bytearray, memoryview) + ), "data argument must be byte-ish (%r)" % type(data) + + if self._eof_sent: + return + + assert self._payload_writer is not None, "Response has not been started" + + await self._payload_writer.write_eof(data) + self._eof_sent = True + self._req = None + self._body_length = self._payload_writer.output_size + self._payload_writer = None + + def __repr__(self) -> str: + if self._eof_sent: + info = "eof" + elif self.prepared: + assert self._req is not None + info = f"{self._req.method} {self._req.path} " + else: + info = "not prepared" + return f"<{self.__class__.__name__} {self.reason} {info}>" + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def __setitem__(self, key: str, value: Any) -> None: + self._state[key] = value + + def __delitem__(self, key: str) -> None: + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + def __hash__(self) -> int: + return hash(id(self)) + + def __eq__(self, other: object) -> bool: + return self is other + + +class Response(StreamResponse): + def __init__( + self, + *, + body: Any = None, + status: int = 200, + reason: Optional[str] = None, + text: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + content_type: Optional[str] = None, + charset: Optional[str] = None, + zlib_executor_size: Optional[int] = None, + zlib_executor: Optional[Executor] = None, + ) -> None: + if body is not None and text is not None: + raise ValueError("body and text are not allowed together") + + if headers is None: + real_headers: CIMultiDict[str] = CIMultiDict() + elif not isinstance(headers, CIMultiDict): + real_headers = CIMultiDict(headers) + else: + real_headers = headers # = cast('CIMultiDict[str]', headers) + + if content_type is not None and "charset" in content_type: + raise ValueError("charset must not be in content_type " "argument") + + if text is not None: + if hdrs.CONTENT_TYPE in real_headers: + if content_type or charset: + raise ValueError( + "passing both Content-Type header and " + "content_type or charset params " + "is forbidden" + ) + else: + # fast path for filling headers + if not isinstance(text, str): + raise TypeError("text argument must be str (%r)" % type(text)) + if content_type is None: + content_type = "text/plain" + if charset is None: + charset = "utf-8" + real_headers[hdrs.CONTENT_TYPE] = content_type + "; charset=" + charset + body = text.encode(charset) + text = None + else: + if hdrs.CONTENT_TYPE in real_headers: + if content_type is not None or charset is not None: + raise ValueError( + "passing both Content-Type header and " + "content_type or charset params " + "is forbidden" + ) + else: + if content_type is not None: + if charset is not None: + content_type += "; charset=" + charset + real_headers[hdrs.CONTENT_TYPE] = content_type + + super().__init__(status=status, reason=reason, headers=real_headers) + + if text is not None: + self.text = text + else: + self.body = body + + self._compressed_body: Optional[bytes] = None + self._zlib_executor_size = zlib_executor_size + self._zlib_executor = zlib_executor + + @property + def body(self) -> Optional[Union[bytes, Payload]]: + return self._body + + @body.setter + def body( + self, + body: bytes, + CONTENT_TYPE: istr = hdrs.CONTENT_TYPE, + CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, + ) -> None: + if body is None: + self._body: Optional[bytes] = None + self._body_payload: bool = False + elif isinstance(body, (bytes, bytearray)): + self._body = body + self._body_payload = False + else: + try: + self._body = body = payload.PAYLOAD_REGISTRY.get(body) + except payload.LookupError: + raise ValueError("Unsupported body type %r" % type(body)) + + self._body_payload = True + + headers = self._headers + + # set content-length header if needed + if not self._chunked and CONTENT_LENGTH not in headers: + size = body.size + if size is not None: + headers[CONTENT_LENGTH] = str(size) + + # set content-type + if CONTENT_TYPE not in headers: + headers[CONTENT_TYPE] = body.content_type + + # copy payload headers + if body.headers: + for (key, value) in body.headers.items(): + if key not in headers: + headers[key] = value + + self._compressed_body = None + + @property + def text(self) -> Optional[str]: + if self._body is None: + return None + return self._body.decode(self.charset or "utf-8") + + @text.setter + def text(self, text: str) -> None: + assert text is None or isinstance( + text, str + ), "text argument must be str (%r)" % type(text) + + if self.content_type == "application/octet-stream": + self.content_type = "text/plain" + if self.charset is None: + self.charset = "utf-8" + + self._body = text.encode(self.charset) + self._body_payload = False + self._compressed_body = None + + @property + def content_length(self) -> Optional[int]: + if self._chunked: + return None + + if hdrs.CONTENT_LENGTH in self._headers: + return super().content_length + + if self._compressed_body is not None: + # Return length of the compressed body + return len(self._compressed_body) + elif self._body_payload: + # A payload without content length, or a compressed payload + return None + elif self._body is not None: + return len(self._body) + else: + return 0 + + @content_length.setter + def content_length(self, value: Optional[int]) -> None: + raise RuntimeError("Content length is set automatically") + + async def write_eof(self, data: bytes = b"") -> None: + if self._eof_sent: + return + if self._compressed_body is None: + body: Optional[Union[bytes, Payload]] = self._body + else: + body = self._compressed_body + assert not data, f"data arg is not supported, got {data!r}" + assert self._req is not None + assert self._payload_writer is not None + if body is not None: + if self._req._method == hdrs.METH_HEAD or self._status in [204, 304]: + await super().write_eof() + elif self._body_payload: + payload = cast(Payload, body) + await payload.write(self._payload_writer) + await super().write_eof() + else: + await super().write_eof(cast(bytes, body)) + else: + await super().write_eof() + + async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: + if not self._chunked and hdrs.CONTENT_LENGTH not in self._headers: + if not self._body_payload: + if self._body is not None: + self._headers[hdrs.CONTENT_LENGTH] = str(len(self._body)) + else: + self._headers[hdrs.CONTENT_LENGTH] = "0" + + return await super()._start(request) + + def _compress_body(self, zlib_mode: int) -> None: + assert zlib_mode > 0 + compressobj = zlib.compressobj(wbits=zlib_mode) + body_in = self._body + assert body_in is not None + self._compressed_body = compressobj.compress(body_in) + compressobj.flush() + + async def _do_start_compression(self, coding: ContentCoding) -> None: + if self._body_payload or self._chunked: + return await super()._do_start_compression(coding) + + if coding != ContentCoding.identity: + # Instead of using _payload_writer.enable_compression, + # compress the whole body + zlib_mode = ( + 16 + zlib.MAX_WBITS if coding == ContentCoding.gzip else zlib.MAX_WBITS + ) + body_in = self._body + assert body_in is not None + if ( + self._zlib_executor_size is not None + and len(body_in) > self._zlib_executor_size + ): + await asyncio.get_event_loop().run_in_executor( + self._zlib_executor, self._compress_body, zlib_mode + ) + else: + self._compress_body(zlib_mode) + + body_out = self._compressed_body + assert body_out is not None + + self._headers[hdrs.CONTENT_ENCODING] = coding.value + self._headers[hdrs.CONTENT_LENGTH] = str(len(body_out)) + + +def json_response( + data: Any = sentinel, + *, + text: Optional[str] = None, + body: Optional[bytes] = None, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + content_type: str = "application/json", + dumps: JSONEncoder = json.dumps, +) -> Response: + if data is not sentinel: + if text or body: + raise ValueError("only one of data, text, or body should be specified") + else: + text = dumps(data) + return Response( + text=text, + body=body, + status=status, + reason=reason, + headers=headers, + content_type=content_type, + ) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_routedef.py b/.venv/lib/python3.7/site-packages/aiohttp/web_routedef.py new file mode 100644 index 0000000..a1eb0a7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_routedef.py @@ -0,0 +1,216 @@ +import abc +import os # noqa +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Iterator, + List, + Optional, + Sequence, + Type, + Union, + overload, +) + +import attr + +from . import hdrs +from .abc import AbstractView +from .typedefs import Handler, PathLike + +if TYPE_CHECKING: # pragma: no cover + from .web_request import Request + from .web_response import StreamResponse + from .web_urldispatcher import AbstractRoute, UrlDispatcher +else: + Request = StreamResponse = UrlDispatcher = AbstractRoute = None + + +__all__ = ( + "AbstractRouteDef", + "RouteDef", + "StaticDef", + "RouteTableDef", + "head", + "options", + "get", + "post", + "patch", + "put", + "delete", + "route", + "view", + "static", +) + + +class AbstractRouteDef(abc.ABC): + @abc.abstractmethod + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + pass # pragma: no cover + + +_HandlerType = Union[Type[AbstractView], Handler] + + +@attr.s(auto_attribs=True, frozen=True, repr=False, slots=True) +class RouteDef(AbstractRouteDef): + method: str + path: str + handler: _HandlerType + kwargs: Dict[str, Any] + + def __repr__(self) -> str: + info = [] + for name, value in sorted(self.kwargs.items()): + info.append(f", {name}={value!r}") + return " {handler.__name__!r}" "{info}>".format( + method=self.method, path=self.path, handler=self.handler, info="".join(info) + ) + + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + if self.method in hdrs.METH_ALL: + reg = getattr(router, "add_" + self.method.lower()) + return [reg(self.path, self.handler, **self.kwargs)] + else: + return [ + router.add_route(self.method, self.path, self.handler, **self.kwargs) + ] + + +@attr.s(auto_attribs=True, frozen=True, repr=False, slots=True) +class StaticDef(AbstractRouteDef): + prefix: str + path: PathLike + kwargs: Dict[str, Any] + + def __repr__(self) -> str: + info = [] + for name, value in sorted(self.kwargs.items()): + info.append(f", {name}={value!r}") + return " {path}" "{info}>".format( + prefix=self.prefix, path=self.path, info="".join(info) + ) + + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + resource = router.add_static(self.prefix, self.path, **self.kwargs) + routes = resource.get_info().get("routes", {}) + return list(routes.values()) + + +def route(method: str, path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return RouteDef(method, path, handler, kwargs) + + +def head(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_HEAD, path, handler, **kwargs) + + +def options(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_OPTIONS, path, handler, **kwargs) + + +def get( + path: str, + handler: _HandlerType, + *, + name: Optional[str] = None, + allow_head: bool = True, + **kwargs: Any, +) -> RouteDef: + return route( + hdrs.METH_GET, path, handler, name=name, allow_head=allow_head, **kwargs + ) + + +def post(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_POST, path, handler, **kwargs) + + +def put(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_PUT, path, handler, **kwargs) + + +def patch(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_PATCH, path, handler, **kwargs) + + +def delete(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_DELETE, path, handler, **kwargs) + + +def view(path: str, handler: Type[AbstractView], **kwargs: Any) -> RouteDef: + return route(hdrs.METH_ANY, path, handler, **kwargs) + + +def static(prefix: str, path: PathLike, **kwargs: Any) -> StaticDef: + return StaticDef(prefix, path, kwargs) + + +_Deco = Callable[[_HandlerType], _HandlerType] + + +class RouteTableDef(Sequence[AbstractRouteDef]): + """Route definition table""" + + def __init__(self) -> None: + self._items: List[AbstractRouteDef] = [] + + def __repr__(self) -> str: + return f"" + + @overload + def __getitem__(self, index: int) -> AbstractRouteDef: + ... + + @overload + def __getitem__(self, index: slice) -> List[AbstractRouteDef]: + ... + + def __getitem__(self, index): # type: ignore[no-untyped-def] + return self._items[index] + + def __iter__(self) -> Iterator[AbstractRouteDef]: + return iter(self._items) + + def __len__(self) -> int: + return len(self._items) + + def __contains__(self, item: object) -> bool: + return item in self._items + + def route(self, method: str, path: str, **kwargs: Any) -> _Deco: + def inner(handler: _HandlerType) -> _HandlerType: + self._items.append(RouteDef(method, path, handler, kwargs)) + return handler + + return inner + + def head(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_HEAD, path, **kwargs) + + def get(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_GET, path, **kwargs) + + def post(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_POST, path, **kwargs) + + def put(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_PUT, path, **kwargs) + + def patch(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_PATCH, path, **kwargs) + + def delete(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_DELETE, path, **kwargs) + + def options(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_OPTIONS, path, **kwargs) + + def view(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_ANY, path, **kwargs) + + def static(self, prefix: str, path: PathLike, **kwargs: Any) -> None: + self._items.append(StaticDef(prefix, path, kwargs)) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_runner.py b/.venv/lib/python3.7/site-packages/aiohttp/web_runner.py new file mode 100644 index 0000000..9282bb9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_runner.py @@ -0,0 +1,381 @@ +import asyncio +import signal +import socket +from abc import ABC, abstractmethod +from typing import Any, List, Optional, Set + +from yarl import URL + +from .web_app import Application +from .web_server import Server + +try: + from ssl import SSLContext +except ImportError: + SSLContext = object # type: ignore[misc,assignment] + + +__all__ = ( + "BaseSite", + "TCPSite", + "UnixSite", + "NamedPipeSite", + "SockSite", + "BaseRunner", + "AppRunner", + "ServerRunner", + "GracefulExit", +) + + +class GracefulExit(SystemExit): + code = 1 + + +def _raise_graceful_exit() -> None: + raise GracefulExit() + + +class BaseSite(ABC): + __slots__ = ("_runner", "_shutdown_timeout", "_ssl_context", "_backlog", "_server") + + def __init__( + self, + runner: "BaseRunner", + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + if runner.server is None: + raise RuntimeError("Call runner.setup() before making a site") + self._runner = runner + self._shutdown_timeout = shutdown_timeout + self._ssl_context = ssl_context + self._backlog = backlog + self._server: Optional[asyncio.AbstractServer] = None + + @property + @abstractmethod + def name(self) -> str: + pass # pragma: no cover + + @abstractmethod + async def start(self) -> None: + self._runner._reg_site(self) + + async def stop(self) -> None: + self._runner._check_site(self) + if self._server is None: + self._runner._unreg_site(self) + return # not started yet + self._server.close() + # named pipes do not have wait_closed property + if hasattr(self._server, "wait_closed"): + await self._server.wait_closed() + await self._runner.shutdown() + assert self._runner.server + await self._runner.server.shutdown(self._shutdown_timeout) + self._runner._unreg_site(self) + + +class TCPSite(BaseSite): + __slots__ = ("_host", "_port", "_reuse_address", "_reuse_port") + + def __init__( + self, + runner: "BaseRunner", + host: Optional[str] = None, + port: Optional[int] = None, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._host = host + if port is None: + port = 8443 if self._ssl_context else 8080 + self._port = port + self._reuse_address = reuse_address + self._reuse_port = reuse_port + + @property + def name(self) -> str: + scheme = "https" if self._ssl_context else "http" + host = "0.0.0.0" if self._host is None else self._host + return str(URL.build(scheme=scheme, host=host, port=self._port)) + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_server( + server, + self._host, + self._port, + ssl=self._ssl_context, + backlog=self._backlog, + reuse_address=self._reuse_address, + reuse_port=self._reuse_port, + ) + + +class UnixSite(BaseSite): + __slots__ = ("_path",) + + def __init__( + self, + runner: "BaseRunner", + path: str, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._path = path + + @property + def name(self) -> str: + scheme = "https" if self._ssl_context else "http" + return f"{scheme}://unix:{self._path}:" + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_unix_server( + server, self._path, ssl=self._ssl_context, backlog=self._backlog + ) + + +class NamedPipeSite(BaseSite): + __slots__ = ("_path",) + + def __init__( + self, runner: "BaseRunner", path: str, *, shutdown_timeout: float = 60.0 + ) -> None: + loop = asyncio.get_event_loop() + if not isinstance( + loop, asyncio.ProactorEventLoop # type: ignore[attr-defined] + ): + raise RuntimeError( + "Named Pipes only available in proactor" "loop under windows" + ) + super().__init__(runner, shutdown_timeout=shutdown_timeout) + self._path = path + + @property + def name(self) -> str: + return self._path + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + _server = await loop.start_serving_pipe( # type: ignore[attr-defined] + server, self._path + ) + self._server = _server[0] + + +class SockSite(BaseSite): + __slots__ = ("_sock", "_name") + + def __init__( + self, + runner: "BaseRunner", + sock: socket.socket, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._sock = sock + scheme = "https" if self._ssl_context else "http" + if hasattr(socket, "AF_UNIX") and sock.family == socket.AF_UNIX: + name = f"{scheme}://unix:{sock.getsockname()}:" + else: + host, port = sock.getsockname()[:2] + name = str(URL.build(scheme=scheme, host=host, port=port)) + self._name = name + + @property + def name(self) -> str: + return self._name + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_server( + server, sock=self._sock, ssl=self._ssl_context, backlog=self._backlog + ) + + +class BaseRunner(ABC): + __slots__ = ("_handle_signals", "_kwargs", "_server", "_sites") + + def __init__(self, *, handle_signals: bool = False, **kwargs: Any) -> None: + self._handle_signals = handle_signals + self._kwargs = kwargs + self._server: Optional[Server] = None + self._sites: List[BaseSite] = [] + + @property + def server(self) -> Optional[Server]: + return self._server + + @property + def addresses(self) -> List[Any]: + ret: List[Any] = [] + for site in self._sites: + server = site._server + if server is not None: + sockets = server.sockets + if sockets is not None: + for sock in sockets: + ret.append(sock.getsockname()) + return ret + + @property + def sites(self) -> Set[BaseSite]: + return set(self._sites) + + async def setup(self) -> None: + loop = asyncio.get_event_loop() + + if self._handle_signals: + try: + loop.add_signal_handler(signal.SIGINT, _raise_graceful_exit) + loop.add_signal_handler(signal.SIGTERM, _raise_graceful_exit) + except NotImplementedError: # pragma: no cover + # add_signal_handler is not implemented on Windows + pass + + self._server = await self._make_server() + + @abstractmethod + async def shutdown(self) -> None: + pass # pragma: no cover + + async def cleanup(self) -> None: + loop = asyncio.get_event_loop() + + # The loop over sites is intentional, an exception on gather() + # leaves self._sites in unpredictable state. + # The loop guaranties that a site is either deleted on success or + # still present on failure + for site in list(self._sites): + await site.stop() + await self._cleanup_server() + self._server = None + if self._handle_signals: + try: + loop.remove_signal_handler(signal.SIGINT) + loop.remove_signal_handler(signal.SIGTERM) + except NotImplementedError: # pragma: no cover + # remove_signal_handler is not implemented on Windows + pass + + @abstractmethod + async def _make_server(self) -> Server: + pass # pragma: no cover + + @abstractmethod + async def _cleanup_server(self) -> None: + pass # pragma: no cover + + def _reg_site(self, site: BaseSite) -> None: + if site in self._sites: + raise RuntimeError(f"Site {site} is already registered in runner {self}") + self._sites.append(site) + + def _check_site(self, site: BaseSite) -> None: + if site not in self._sites: + raise RuntimeError(f"Site {site} is not registered in runner {self}") + + def _unreg_site(self, site: BaseSite) -> None: + if site not in self._sites: + raise RuntimeError(f"Site {site} is not registered in runner {self}") + self._sites.remove(site) + + +class ServerRunner(BaseRunner): + """Low-level web server runner""" + + __slots__ = ("_web_server",) + + def __init__( + self, web_server: Server, *, handle_signals: bool = False, **kwargs: Any + ) -> None: + super().__init__(handle_signals=handle_signals, **kwargs) + self._web_server = web_server + + async def shutdown(self) -> None: + pass + + async def _make_server(self) -> Server: + return self._web_server + + async def _cleanup_server(self) -> None: + pass + + +class AppRunner(BaseRunner): + """Web Application runner""" + + __slots__ = ("_app",) + + def __init__( + self, app: Application, *, handle_signals: bool = False, **kwargs: Any + ) -> None: + super().__init__(handle_signals=handle_signals, **kwargs) + if not isinstance(app, Application): + raise TypeError( + "The first argument should be web.Application " + "instance, got {!r}".format(app) + ) + self._app = app + + @property + def app(self) -> Application: + return self._app + + async def shutdown(self) -> None: + await self._app.shutdown() + + async def _make_server(self) -> Server: + loop = asyncio.get_event_loop() + self._app._set_loop(loop) + self._app.on_startup.freeze() + await self._app.startup() + self._app.freeze() + + return self._app._make_handler(loop=loop, **self._kwargs) + + async def _cleanup_server(self) -> None: + await self._app.cleanup() diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_server.py b/.venv/lib/python3.7/site-packages/aiohttp/web_server.py new file mode 100644 index 0000000..fa46e90 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_server.py @@ -0,0 +1,62 @@ +"""Low level HTTP server.""" +import asyncio +from typing import Any, Awaitable, Callable, Dict, List, Optional # noqa + +from .abc import AbstractStreamWriter +from .helpers import get_running_loop +from .http_parser import RawRequestMessage +from .streams import StreamReader +from .web_protocol import RequestHandler, _RequestFactory, _RequestHandler +from .web_request import BaseRequest + +__all__ = ("Server",) + + +class Server: + def __init__( + self, + handler: _RequestHandler, + *, + request_factory: Optional[_RequestFactory] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + **kwargs: Any + ) -> None: + self._loop = get_running_loop(loop) + self._connections: Dict[RequestHandler, asyncio.Transport] = {} + self._kwargs = kwargs + self.requests_count = 0 + self.request_handler = handler + self.request_factory = request_factory or self._make_request + + @property + def connections(self) -> List[RequestHandler]: + return list(self._connections.keys()) + + def connection_made( + self, handler: RequestHandler, transport: asyncio.Transport + ) -> None: + self._connections[handler] = transport + + def connection_lost( + self, handler: RequestHandler, exc: Optional[BaseException] = None + ) -> None: + if handler in self._connections: + del self._connections[handler] + + def _make_request( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + ) -> BaseRequest: + return BaseRequest(message, payload, protocol, writer, task, self._loop) + + async def shutdown(self, timeout: Optional[float] = None) -> None: + coros = [conn.shutdown(timeout) for conn in self._connections] + await asyncio.gather(*coros) + self._connections.clear() + + def __call__(self) -> RequestHandler: + return RequestHandler(self, loop=self._loop, **self._kwargs) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py b/.venv/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py new file mode 100644 index 0000000..5942e35 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py @@ -0,0 +1,1220 @@ +import abc +import asyncio +import base64 +import hashlib +import inspect +import keyword +import os +import re +import warnings +from contextlib import contextmanager +from functools import wraps +from pathlib import Path +from types import MappingProxyType +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Container, + Dict, + Generator, + Iterable, + Iterator, + List, + Mapping, + Optional, + Pattern, + Set, + Sized, + Tuple, + Type, + Union, + cast, +) + +from yarl import URL, __version__ as yarl_version # type: ignore[attr-defined] + +from . import hdrs +from .abc import AbstractMatchInfo, AbstractRouter, AbstractView +from .helpers import DEBUG +from .http import HttpVersion11 +from .typedefs import Final, Handler, PathLike, TypedDict +from .web_exceptions import ( + HTTPException, + HTTPExpectationFailed, + HTTPForbidden, + HTTPMethodNotAllowed, + HTTPNotFound, +) +from .web_fileresponse import FileResponse +from .web_request import Request +from .web_response import Response, StreamResponse +from .web_routedef import AbstractRouteDef + +__all__ = ( + "UrlDispatcher", + "UrlMappingMatchInfo", + "AbstractResource", + "Resource", + "PlainResource", + "DynamicResource", + "AbstractRoute", + "ResourceRoute", + "StaticResource", + "View", +) + + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + + BaseDict = Dict[str, str] +else: + BaseDict = dict + +YARL_VERSION: Final[Tuple[int, ...]] = tuple(map(int, yarl_version.split(".")[:2])) + +HTTP_METHOD_RE: Final[Pattern[str]] = re.compile( + r"^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`\|~]+$" +) +ROUTE_RE: Final[Pattern[str]] = re.compile( + r"(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})" +) +PATH_SEP: Final[str] = re.escape("/") + + +_ExpectHandler = Callable[[Request], Awaitable[None]] +_Resolve = Tuple[Optional["UrlMappingMatchInfo"], Set[str]] + + +class _InfoDict(TypedDict, total=False): + path: str + + formatter: str + pattern: Pattern[str] + + directory: Path + prefix: str + routes: Mapping[str, "AbstractRoute"] + + app: "Application" + + domain: str + + rule: "AbstractRuleMatching" + + http_exception: HTTPException + + +class AbstractResource(Sized, Iterable["AbstractRoute"]): + def __init__(self, *, name: Optional[str] = None) -> None: + self._name = name + + @property + def name(self) -> Optional[str]: + return self._name + + @property + @abc.abstractmethod + def canonical(self) -> str: + """Exposes the resource's canonical path. + + For example '/foo/bar/{name}' + + """ + + @abc.abstractmethod # pragma: no branch + def url_for(self, **kwargs: str) -> URL: + """Construct url for resource with additional params.""" + + @abc.abstractmethod # pragma: no branch + async def resolve(self, request: Request) -> _Resolve: + """Resolve resource. + + Return (UrlMappingMatchInfo, allowed_methods) pair. + """ + + @abc.abstractmethod + def add_prefix(self, prefix: str) -> None: + """Add a prefix to processed URLs. + + Required for subapplications support. + """ + + @abc.abstractmethod + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + def freeze(self) -> None: + pass + + @abc.abstractmethod + def raw_match(self, path: str) -> bool: + """Perform a raw match against path""" + + +class AbstractRoute(abc.ABC): + def __init__( + self, + method: str, + handler: Union[Handler, Type[AbstractView]], + *, + expect_handler: Optional[_ExpectHandler] = None, + resource: Optional[AbstractResource] = None, + ) -> None: + + if expect_handler is None: + expect_handler = _default_expect_handler + + assert asyncio.iscoroutinefunction( + expect_handler + ), f"Coroutine is expected, got {expect_handler!r}" + + method = method.upper() + if not HTTP_METHOD_RE.match(method): + raise ValueError(f"{method} is not allowed HTTP method") + + assert callable(handler), handler + if asyncio.iscoroutinefunction(handler): + pass + elif inspect.isgeneratorfunction(handler): + warnings.warn( + "Bare generators are deprecated, " "use @coroutine wrapper", + DeprecationWarning, + ) + elif isinstance(handler, type) and issubclass(handler, AbstractView): + pass + else: + warnings.warn( + "Bare functions are deprecated, " "use async ones", DeprecationWarning + ) + + @wraps(handler) + async def handler_wrapper(request: Request) -> StreamResponse: + result = old_handler(request) + if asyncio.iscoroutine(result): + return await result + return result # type: ignore[return-value] + + old_handler = handler + handler = handler_wrapper + + self._method = method + self._handler = handler + self._expect_handler = expect_handler + self._resource = resource + + @property + def method(self) -> str: + return self._method + + @property + def handler(self) -> Handler: + return self._handler + + @property + @abc.abstractmethod + def name(self) -> Optional[str]: + """Optional route's name, always equals to resource's name.""" + + @property + def resource(self) -> Optional[AbstractResource]: + return self._resource + + @abc.abstractmethod + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + @abc.abstractmethod # pragma: no branch + def url_for(self, *args: str, **kwargs: str) -> URL: + """Construct url for route with additional params.""" + + async def handle_expect_header(self, request: Request) -> None: + await self._expect_handler(request) + + +class UrlMappingMatchInfo(BaseDict, AbstractMatchInfo): + def __init__(self, match_dict: Dict[str, str], route: AbstractRoute): + super().__init__(match_dict) + self._route = route + self._apps: List[Application] = [] + self._current_app: Optional[Application] = None + self._frozen = False + + @property + def handler(self) -> Handler: + return self._route.handler + + @property + def route(self) -> AbstractRoute: + return self._route + + @property + def expect_handler(self) -> _ExpectHandler: + return self._route.handle_expect_header + + @property + def http_exception(self) -> Optional[HTTPException]: + return None + + def get_info(self) -> _InfoDict: # type: ignore[override] + return self._route.get_info() + + @property + def apps(self) -> Tuple["Application", ...]: + return tuple(self._apps) + + def add_app(self, app: "Application") -> None: + if self._frozen: + raise RuntimeError("Cannot change apps stack after .freeze() call") + if self._current_app is None: + self._current_app = app + self._apps.insert(0, app) + + @property + def current_app(self) -> "Application": + app = self._current_app + assert app is not None + return app + + @contextmanager + def set_current_app(self, app: "Application") -> Generator[None, None, None]: + if DEBUG: # pragma: no cover + if app not in self._apps: + raise RuntimeError( + "Expected one of the following apps {!r}, got {!r}".format( + self._apps, app + ) + ) + prev = self._current_app + self._current_app = app + try: + yield + finally: + self._current_app = prev + + def freeze(self) -> None: + self._frozen = True + + def __repr__(self) -> str: + return f"" + + +class MatchInfoError(UrlMappingMatchInfo): + def __init__(self, http_exception: HTTPException) -> None: + self._exception = http_exception + super().__init__({}, SystemRoute(self._exception)) + + @property + def http_exception(self) -> HTTPException: + return self._exception + + def __repr__(self) -> str: + return "".format( + self._exception.status, self._exception.reason + ) + + +async def _default_expect_handler(request: Request) -> None: + """Default handler for Expect header. + + Just send "100 Continue" to client. + raise HTTPExpectationFailed if value of header is not "100-continue" + """ + expect = request.headers.get(hdrs.EXPECT, "") + if request.version == HttpVersion11: + if expect.lower() == "100-continue": + await request.writer.write(b"HTTP/1.1 100 Continue\r\n\r\n") + else: + raise HTTPExpectationFailed(text="Unknown Expect: %s" % expect) + + +class Resource(AbstractResource): + def __init__(self, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + self._routes: List[ResourceRoute] = [] + + def add_route( + self, + method: str, + handler: Union[Type[AbstractView], Handler], + *, + expect_handler: Optional[_ExpectHandler] = None, + ) -> "ResourceRoute": + + for route_obj in self._routes: + if route_obj.method == method or route_obj.method == hdrs.METH_ANY: + raise RuntimeError( + "Added route will never be executed, " + "method {route.method} is already " + "registered".format(route=route_obj) + ) + + route_obj = ResourceRoute(method, handler, self, expect_handler=expect_handler) + self.register_route(route_obj) + return route_obj + + def register_route(self, route: "ResourceRoute") -> None: + assert isinstance( + route, ResourceRoute + ), f"Instance of Route class is required, got {route!r}" + self._routes.append(route) + + async def resolve(self, request: Request) -> _Resolve: + allowed_methods: Set[str] = set() + + match_dict = self._match(request.rel_url.raw_path) + if match_dict is None: + return None, allowed_methods + + for route_obj in self._routes: + route_method = route_obj.method + allowed_methods.add(route_method) + + if route_method == request.method or route_method == hdrs.METH_ANY: + return (UrlMappingMatchInfo(match_dict, route_obj), allowed_methods) + else: + return None, allowed_methods + + @abc.abstractmethod + def _match(self, path: str) -> Optional[Dict[str, str]]: + pass # pragma: no cover + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._routes) + + # TODO: implement all abstract methods + + +class PlainResource(Resource): + def __init__(self, path: str, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + assert not path or path.startswith("/") + self._path = path + + @property + def canonical(self) -> str: + return self._path + + def freeze(self) -> None: + if not self._path: + self._path = "/" + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._path = prefix + self._path + + def _match(self, path: str) -> Optional[Dict[str, str]]: + # string comparison is about 10 times faster than regexp matching + if self._path == path: + return {} + else: + return None + + def raw_match(self, path: str) -> bool: + return self._path == path + + def get_info(self) -> _InfoDict: + return {"path": self._path} + + def url_for(self) -> URL: # type: ignore[override] + return URL.build(path=self._path, encoded=True) + + def __repr__(self) -> str: + name = "'" + self.name + "' " if self.name is not None else "" + return f"" + + +class DynamicResource(Resource): + + DYN = re.compile(r"\{(?P[_a-zA-Z][_a-zA-Z0-9]*)\}") + DYN_WITH_RE = re.compile(r"\{(?P[_a-zA-Z][_a-zA-Z0-9]*):(?P.+)\}") + GOOD = r"[^{}/]+" + + def __init__(self, path: str, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + pattern = "" + formatter = "" + for part in ROUTE_RE.split(path): + match = self.DYN.fullmatch(part) + if match: + pattern += "(?P<{}>{})".format(match.group("var"), self.GOOD) + formatter += "{" + match.group("var") + "}" + continue + + match = self.DYN_WITH_RE.fullmatch(part) + if match: + pattern += "(?P<{var}>{re})".format(**match.groupdict()) + formatter += "{" + match.group("var") + "}" + continue + + if "{" in part or "}" in part: + raise ValueError(f"Invalid path '{path}'['{part}']") + + part = _requote_path(part) + formatter += part + pattern += re.escape(part) + + try: + compiled = re.compile(pattern) + except re.error as exc: + raise ValueError(f"Bad pattern '{pattern}': {exc}") from None + assert compiled.pattern.startswith(PATH_SEP) + assert formatter.startswith("/") + self._pattern = compiled + self._formatter = formatter + + @property + def canonical(self) -> str: + return self._formatter + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._pattern = re.compile(re.escape(prefix) + self._pattern.pattern) + self._formatter = prefix + self._formatter + + def _match(self, path: str) -> Optional[Dict[str, str]]: + match = self._pattern.fullmatch(path) + if match is None: + return None + else: + return { + key: _unquote_path(value) for key, value in match.groupdict().items() + } + + def raw_match(self, path: str) -> bool: + return self._formatter == path + + def get_info(self) -> _InfoDict: + return {"formatter": self._formatter, "pattern": self._pattern} + + def url_for(self, **parts: str) -> URL: + url = self._formatter.format_map({k: _quote_path(v) for k, v in parts.items()}) + return URL.build(path=url, encoded=True) + + def __repr__(self) -> str: + name = "'" + self.name + "' " if self.name is not None else "" + return "".format( + name=name, formatter=self._formatter + ) + + +class PrefixResource(AbstractResource): + def __init__(self, prefix: str, *, name: Optional[str] = None) -> None: + assert not prefix or prefix.startswith("/"), prefix + assert prefix in ("", "/") or not prefix.endswith("/"), prefix + super().__init__(name=name) + self._prefix = _requote_path(prefix) + self._prefix2 = self._prefix + "/" + + @property + def canonical(self) -> str: + return self._prefix + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._prefix = prefix + self._prefix + self._prefix2 = self._prefix + "/" + + def raw_match(self, prefix: str) -> bool: + return False + + # TODO: impl missing abstract methods + + +class StaticResource(PrefixResource): + VERSION_KEY = "v" + + def __init__( + self, + prefix: str, + directory: PathLike, + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + chunk_size: int = 256 * 1024, + show_index: bool = False, + follow_symlinks: bool = False, + append_version: bool = False, + ) -> None: + super().__init__(prefix, name=name) + try: + directory = Path(directory) + if str(directory).startswith("~"): + directory = Path(os.path.expanduser(str(directory))) + directory = directory.resolve() + if not directory.is_dir(): + raise ValueError("Not a directory") + except (FileNotFoundError, ValueError) as error: + raise ValueError(f"No directory exists at '{directory}'") from error + self._directory = directory + self._show_index = show_index + self._chunk_size = chunk_size + self._follow_symlinks = follow_symlinks + self._expect_handler = expect_handler + self._append_version = append_version + + self._routes = { + "GET": ResourceRoute( + "GET", self._handle, self, expect_handler=expect_handler + ), + "HEAD": ResourceRoute( + "HEAD", self._handle, self, expect_handler=expect_handler + ), + } + + def url_for( # type: ignore[override] + self, + *, + filename: Union[str, Path], + append_version: Optional[bool] = None, + ) -> URL: + if append_version is None: + append_version = self._append_version + if isinstance(filename, Path): + filename = str(filename) + filename = filename.lstrip("/") + + url = URL.build(path=self._prefix, encoded=True) + # filename is not encoded + if YARL_VERSION < (1, 6): + url = url / filename.replace("%", "%25") + else: + url = url / filename + + if append_version: + try: + filepath = self._directory.joinpath(filename).resolve() + if not self._follow_symlinks: + filepath.relative_to(self._directory) + except (ValueError, FileNotFoundError): + # ValueError for case when path point to symlink + # with follow_symlinks is False + return url # relatively safe + if filepath.is_file(): + # TODO cache file content + # with file watcher for cache invalidation + with filepath.open("rb") as f: + file_bytes = f.read() + h = self._get_file_hash(file_bytes) + url = url.with_query({self.VERSION_KEY: h}) + return url + return url + + @staticmethod + def _get_file_hash(byte_array: bytes) -> str: + m = hashlib.sha256() # todo sha256 can be configurable param + m.update(byte_array) + b64 = base64.urlsafe_b64encode(m.digest()) + return b64.decode("ascii") + + def get_info(self) -> _InfoDict: + return { + "directory": self._directory, + "prefix": self._prefix, + "routes": self._routes, + } + + def set_options_route(self, handler: Handler) -> None: + if "OPTIONS" in self._routes: + raise RuntimeError("OPTIONS route was set already") + self._routes["OPTIONS"] = ResourceRoute( + "OPTIONS", handler, self, expect_handler=self._expect_handler + ) + + async def resolve(self, request: Request) -> _Resolve: + path = request.rel_url.raw_path + method = request.method + allowed_methods = set(self._routes) + if not path.startswith(self._prefix2) and path != self._prefix: + return None, set() + + if method not in allowed_methods: + return None, allowed_methods + + match_dict = {"filename": _unquote_path(path[len(self._prefix) + 1 :])} + return (UrlMappingMatchInfo(match_dict, self._routes[method]), allowed_methods) + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._routes.values()) + + async def _handle(self, request: Request) -> StreamResponse: + rel_url = request.match_info["filename"] + try: + filename = Path(rel_url) + if filename.anchor: + # rel_url is an absolute name like + # /static/\\machine_name\c$ or /static/D:\path + # where the static dir is totally different + raise HTTPForbidden() + filepath = self._directory.joinpath(filename).resolve() + if not self._follow_symlinks: + filepath.relative_to(self._directory) + except (ValueError, FileNotFoundError) as error: + # relatively safe + raise HTTPNotFound() from error + except HTTPForbidden: + raise + except Exception as error: + # perm error or other kind! + request.app.logger.exception(error) + raise HTTPNotFound() from error + + # on opening a dir, load its contents if allowed + if filepath.is_dir(): + if self._show_index: + try: + return Response( + text=self._directory_as_html(filepath), content_type="text/html" + ) + except PermissionError: + raise HTTPForbidden() + else: + raise HTTPForbidden() + elif filepath.is_file(): + return FileResponse(filepath, chunk_size=self._chunk_size) + else: + raise HTTPNotFound + + def _directory_as_html(self, filepath: Path) -> str: + # returns directory's index as html + + # sanity check + assert filepath.is_dir() + + relative_path_to_dir = filepath.relative_to(self._directory).as_posix() + index_of = f"Index of /{relative_path_to_dir}" + h1 = f"

{index_of}

" + + index_list = [] + dir_index = filepath.iterdir() + for _file in sorted(dir_index): + # show file url as relative to static path + rel_path = _file.relative_to(self._directory).as_posix() + file_url = self._prefix + "/" + rel_path + + # if file is a directory, add '/' to the end of the name + if _file.is_dir(): + file_name = f"{_file.name}/" + else: + file_name = _file.name + + index_list.append( + '
'.format( + url=file_url, name=file_name + ) + ) + ul = "
    \n{}\n
".format("\n".join(index_list)) + body = f"\n{h1}\n{ul}\n" + + head_str = f"\n{index_of}\n" + html = f"\n{head_str}\n{body}\n" + + return html + + def __repr__(self) -> str: + name = "'" + self.name + "'" if self.name is not None else "" + return " {directory!r}>".format( + name=name, path=self._prefix, directory=self._directory + ) + + +class PrefixedSubAppResource(PrefixResource): + def __init__(self, prefix: str, app: "Application") -> None: + super().__init__(prefix) + self._app = app + for resource in app.router.resources(): + resource.add_prefix(prefix) + + def add_prefix(self, prefix: str) -> None: + super().add_prefix(prefix) + for resource in self._app.router.resources(): + resource.add_prefix(prefix) + + def url_for(self, *args: str, **kwargs: str) -> URL: + raise RuntimeError(".url_for() is not supported " "by sub-application root") + + def get_info(self) -> _InfoDict: + return {"app": self._app, "prefix": self._prefix} + + async def resolve(self, request: Request) -> _Resolve: + if ( + not request.url.raw_path.startswith(self._prefix2) + and request.url.raw_path != self._prefix + ): + return None, set() + match_info = await self._app.router.resolve(request) + match_info.add_app(self._app) + if isinstance(match_info.http_exception, HTTPMethodNotAllowed): + methods = match_info.http_exception.allowed_methods + else: + methods = set() + return match_info, methods + + def __len__(self) -> int: + return len(self._app.router.routes()) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._app.router.routes()) + + def __repr__(self) -> str: + return " {app!r}>".format( + prefix=self._prefix, app=self._app + ) + + +class AbstractRuleMatching(abc.ABC): + @abc.abstractmethod # pragma: no branch + async def match(self, request: Request) -> bool: + """Return bool if the request satisfies the criteria""" + + @abc.abstractmethod # pragma: no branch + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + @property + @abc.abstractmethod # pragma: no branch + def canonical(self) -> str: + """Return a str""" + + +class Domain(AbstractRuleMatching): + re_part = re.compile(r"(?!-)[a-z\d-]{1,63}(? None: + super().__init__() + self._domain = self.validation(domain) + + @property + def canonical(self) -> str: + return self._domain + + def validation(self, domain: str) -> str: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + domain = domain.rstrip(".").lower() + if not domain: + raise ValueError("Domain cannot be empty") + elif "://" in domain: + raise ValueError("Scheme not supported") + url = URL("http://" + domain) + assert url.raw_host is not None + if not all(self.re_part.fullmatch(x) for x in url.raw_host.split(".")): + raise ValueError("Domain not valid") + if url.port == 80: + return url.raw_host + return f"{url.raw_host}:{url.port}" + + async def match(self, request: Request) -> bool: + host = request.headers.get(hdrs.HOST) + if not host: + return False + return self.match_domain(host) + + def match_domain(self, host: str) -> bool: + return host.lower() == self._domain + + def get_info(self) -> _InfoDict: + return {"domain": self._domain} + + +class MaskDomain(Domain): + re_part = re.compile(r"(?!-)[a-z\d\*-]{1,63}(? None: + super().__init__(domain) + mask = self._domain.replace(".", r"\.").replace("*", ".*") + self._mask = re.compile(mask) + + @property + def canonical(self) -> str: + return self._mask.pattern + + def match_domain(self, host: str) -> bool: + return self._mask.fullmatch(host) is not None + + +class MatchedSubAppResource(PrefixedSubAppResource): + def __init__(self, rule: AbstractRuleMatching, app: "Application") -> None: + AbstractResource.__init__(self) + self._prefix = "" + self._app = app + self._rule = rule + + @property + def canonical(self) -> str: + return self._rule.canonical + + def get_info(self) -> _InfoDict: + return {"app": self._app, "rule": self._rule} + + async def resolve(self, request: Request) -> _Resolve: + if not await self._rule.match(request): + return None, set() + match_info = await self._app.router.resolve(request) + match_info.add_app(self._app) + if isinstance(match_info.http_exception, HTTPMethodNotAllowed): + methods = match_info.http_exception.allowed_methods + else: + methods = set() + return match_info, methods + + def __repr__(self) -> str: + return " {app!r}>" "".format(app=self._app) + + +class ResourceRoute(AbstractRoute): + """A route with resource""" + + def __init__( + self, + method: str, + handler: Union[Handler, Type[AbstractView]], + resource: AbstractResource, + *, + expect_handler: Optional[_ExpectHandler] = None, + ) -> None: + super().__init__( + method, handler, expect_handler=expect_handler, resource=resource + ) + + def __repr__(self) -> str: + return " {handler!r}".format( + method=self.method, resource=self._resource, handler=self.handler + ) + + @property + def name(self) -> Optional[str]: + if self._resource is None: + return None + return self._resource.name + + def url_for(self, *args: str, **kwargs: str) -> URL: + """Construct url for route with additional params.""" + assert self._resource is not None + return self._resource.url_for(*args, **kwargs) + + def get_info(self) -> _InfoDict: + assert self._resource is not None + return self._resource.get_info() + + +class SystemRoute(AbstractRoute): + def __init__(self, http_exception: HTTPException) -> None: + super().__init__(hdrs.METH_ANY, self._handle) + self._http_exception = http_exception + + def url_for(self, *args: str, **kwargs: str) -> URL: + raise RuntimeError(".url_for() is not allowed for SystemRoute") + + @property + def name(self) -> Optional[str]: + return None + + def get_info(self) -> _InfoDict: + return {"http_exception": self._http_exception} + + async def _handle(self, request: Request) -> StreamResponse: + raise self._http_exception + + @property + def status(self) -> int: + return self._http_exception.status + + @property + def reason(self) -> str: + return self._http_exception.reason + + def __repr__(self) -> str: + return "".format(self=self) + + +class View(AbstractView): + async def _iter(self) -> StreamResponse: + if self.request.method not in hdrs.METH_ALL: + self._raise_allowed_methods() + method: Callable[[], Awaitable[StreamResponse]] = getattr( + self, self.request.method.lower(), None + ) + if method is None: + self._raise_allowed_methods() + resp = await method() + return resp + + def __await__(self) -> Generator[Any, None, StreamResponse]: + return self._iter().__await__() + + def _raise_allowed_methods(self) -> None: + allowed_methods = {m for m in hdrs.METH_ALL if hasattr(self, m.lower())} + raise HTTPMethodNotAllowed(self.request.method, allowed_methods) + + +class ResourcesView(Sized, Iterable[AbstractResource], Container[AbstractResource]): + def __init__(self, resources: List[AbstractResource]) -> None: + self._resources = resources + + def __len__(self) -> int: + return len(self._resources) + + def __iter__(self) -> Iterator[AbstractResource]: + yield from self._resources + + def __contains__(self, resource: object) -> bool: + return resource in self._resources + + +class RoutesView(Sized, Iterable[AbstractRoute], Container[AbstractRoute]): + def __init__(self, resources: List[AbstractResource]): + self._routes: List[AbstractRoute] = [] + for resource in resources: + for route in resource: + self._routes.append(route) + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + yield from self._routes + + def __contains__(self, route: object) -> bool: + return route in self._routes + + +class UrlDispatcher(AbstractRouter, Mapping[str, AbstractResource]): + + NAME_SPLIT_RE = re.compile(r"[.:-]") + + def __init__(self) -> None: + super().__init__() + self._resources: List[AbstractResource] = [] + self._named_resources: Dict[str, AbstractResource] = {} + + async def resolve(self, request: Request) -> UrlMappingMatchInfo: + method = request.method + allowed_methods: Set[str] = set() + + for resource in self._resources: + match_dict, allowed = await resource.resolve(request) + if match_dict is not None: + return match_dict + else: + allowed_methods |= allowed + + if allowed_methods: + return MatchInfoError(HTTPMethodNotAllowed(method, allowed_methods)) + else: + return MatchInfoError(HTTPNotFound()) + + def __iter__(self) -> Iterator[str]: + return iter(self._named_resources) + + def __len__(self) -> int: + return len(self._named_resources) + + def __contains__(self, resource: object) -> bool: + return resource in self._named_resources + + def __getitem__(self, name: str) -> AbstractResource: + return self._named_resources[name] + + def resources(self) -> ResourcesView: + return ResourcesView(self._resources) + + def routes(self) -> RoutesView: + return RoutesView(self._resources) + + def named_resources(self) -> Mapping[str, AbstractResource]: + return MappingProxyType(self._named_resources) + + def register_resource(self, resource: AbstractResource) -> None: + assert isinstance( + resource, AbstractResource + ), f"Instance of AbstractResource class is required, got {resource!r}" + if self.frozen: + raise RuntimeError("Cannot register a resource into frozen router.") + + name = resource.name + + if name is not None: + parts = self.NAME_SPLIT_RE.split(name) + for part in parts: + if keyword.iskeyword(part): + raise ValueError( + f"Incorrect route name {name!r}, " + "python keywords cannot be used " + "for route name" + ) + if not part.isidentifier(): + raise ValueError( + "Incorrect route name {!r}, " + "the name should be a sequence of " + "python identifiers separated " + "by dash, dot or column".format(name) + ) + if name in self._named_resources: + raise ValueError( + "Duplicate {!r}, " + "already handled by {!r}".format(name, self._named_resources[name]) + ) + self._named_resources[name] = resource + self._resources.append(resource) + + def add_resource(self, path: str, *, name: Optional[str] = None) -> Resource: + if path and not path.startswith("/"): + raise ValueError("path should be started with / or be empty") + # Reuse last added resource if path and name are the same + if self._resources: + resource = self._resources[-1] + if resource.name == name and resource.raw_match(path): + return cast(Resource, resource) + if not ("{" in path or "}" in path or ROUTE_RE.search(path)): + resource = PlainResource(_requote_path(path), name=name) + self.register_resource(resource) + return resource + resource = DynamicResource(path, name=name) + self.register_resource(resource) + return resource + + def add_route( + self, + method: str, + path: str, + handler: Union[Handler, Type[AbstractView]], + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + ) -> AbstractRoute: + resource = self.add_resource(path, name=name) + return resource.add_route(method, handler, expect_handler=expect_handler) + + def add_static( + self, + prefix: str, + path: PathLike, + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + chunk_size: int = 256 * 1024, + show_index: bool = False, + follow_symlinks: bool = False, + append_version: bool = False, + ) -> AbstractResource: + """Add static files view. + + prefix - url prefix + path - folder with files + + """ + assert prefix.startswith("/") + if prefix.endswith("/"): + prefix = prefix[:-1] + resource = StaticResource( + prefix, + path, + name=name, + expect_handler=expect_handler, + chunk_size=chunk_size, + show_index=show_index, + follow_symlinks=follow_symlinks, + append_version=append_version, + ) + self.register_resource(resource) + return resource + + def add_head(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method HEAD.""" + return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs) + + def add_options(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method OPTIONS.""" + return self.add_route(hdrs.METH_OPTIONS, path, handler, **kwargs) + + def add_get( + self, + path: str, + handler: Handler, + *, + name: Optional[str] = None, + allow_head: bool = True, + **kwargs: Any, + ) -> AbstractRoute: + """Shortcut for add_route with method GET. + + If allow_head is true, another + route is added allowing head requests to the same endpoint. + """ + resource = self.add_resource(path, name=name) + if allow_head: + resource.add_route(hdrs.METH_HEAD, handler, **kwargs) + return resource.add_route(hdrs.METH_GET, handler, **kwargs) + + def add_post(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method POST.""" + return self.add_route(hdrs.METH_POST, path, handler, **kwargs) + + def add_put(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method PUT.""" + return self.add_route(hdrs.METH_PUT, path, handler, **kwargs) + + def add_patch(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method PATCH.""" + return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs) + + def add_delete(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method DELETE.""" + return self.add_route(hdrs.METH_DELETE, path, handler, **kwargs) + + def add_view( + self, path: str, handler: Type[AbstractView], **kwargs: Any + ) -> AbstractRoute: + """Shortcut for add_route with ANY methods for a class-based view.""" + return self.add_route(hdrs.METH_ANY, path, handler, **kwargs) + + def freeze(self) -> None: + super().freeze() + for resource in self._resources: + resource.freeze() + + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]: + """Append routes to route table. + + Parameter should be a sequence of RouteDef objects. + + Returns a list of registered AbstractRoute instances. + """ + registered_routes = [] + for route_def in routes: + registered_routes.extend(route_def.register(self)) + return registered_routes + + +def _quote_path(value: str) -> str: + if YARL_VERSION < (1, 6): + value = value.replace("%", "%25") + return URL.build(path=value, encoded=False).raw_path + + +def _unquote_path(value: str) -> str: + return URL.build(path=value, encoded=True).path + + +def _requote_path(value: str) -> str: + # Quote non-ascii characters and other characters which must be quoted, + # but preserve existing %-sequences. + result = _quote_path(value) + if "%" in value: + result = result.replace("%25", "%") + return result diff --git a/.venv/lib/python3.7/site-packages/aiohttp/web_ws.py b/.venv/lib/python3.7/site-packages/aiohttp/web_ws.py new file mode 100644 index 0000000..0d32a21 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/web_ws.py @@ -0,0 +1,487 @@ +import asyncio +import base64 +import binascii +import hashlib +import json +from typing import Any, Iterable, Optional, Tuple, cast + +import async_timeout +import attr +from multidict import CIMultiDict + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import call_later, set_result +from .http import ( + WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE, + WS_KEY, + WebSocketError, + WebSocketReader, + WebSocketWriter, + WSCloseCode, + WSMessage, + WSMsgType as WSMsgType, + ws_ext_gen, + ws_ext_parse, +) +from .log import ws_logger +from .streams import EofStream, FlowControlDataQueue +from .typedefs import Final, JSONDecoder, JSONEncoder +from .web_exceptions import HTTPBadRequest, HTTPException +from .web_request import BaseRequest +from .web_response import StreamResponse + +__all__ = ( + "WebSocketResponse", + "WebSocketReady", + "WSMsgType", +) + +THRESHOLD_CONNLOST_ACCESS: Final[int] = 5 + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class WebSocketReady: + ok: bool + protocol: Optional[str] + + def __bool__(self) -> bool: + return self.ok + + +class WebSocketResponse(StreamResponse): + + _length_check = False + + def __init__( + self, + *, + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + protocols: Iterable[str] = (), + compress: bool = True, + max_msg_size: int = 4 * 1024 * 1024, + ) -> None: + super().__init__(status=101) + self._protocols = protocols + self._ws_protocol: Optional[str] = None + self._writer: Optional[WebSocketWriter] = None + self._reader: Optional[FlowControlDataQueue[WSMessage]] = None + self._closed = False + self._closing = False + self._conn_lost = 0 + self._close_code: Optional[int] = None + self._loop: Optional[asyncio.AbstractEventLoop] = None + self._waiting: Optional[asyncio.Future[bool]] = None + self._exception: Optional[BaseException] = None + self._timeout = timeout + self._receive_timeout = receive_timeout + self._autoclose = autoclose + self._autoping = autoping + self._heartbeat = heartbeat + self._heartbeat_cb: Optional[asyncio.TimerHandle] = None + if heartbeat is not None: + self._pong_heartbeat = heartbeat / 2.0 + self._pong_response_cb: Optional[asyncio.TimerHandle] = None + self._compress = compress + self._max_msg_size = max_msg_size + + def _cancel_heartbeat(self) -> None: + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = None + + if self._heartbeat_cb is not None: + self._heartbeat_cb.cancel() + self._heartbeat_cb = None + + def _reset_heartbeat(self) -> None: + self._cancel_heartbeat() + + if self._heartbeat is not None: + assert self._loop is not None + self._heartbeat_cb = call_later( + self._send_heartbeat, self._heartbeat, self._loop + ) + + def _send_heartbeat(self) -> None: + if self._heartbeat is not None and not self._closed: + assert self._loop is not None + # fire-and-forget a task is not perfect but maybe ok for + # sending ping. Otherwise we need a long-living heartbeat + # task in the class. + self._loop.create_task(self._writer.ping()) # type: ignore[union-attr] + + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = call_later( + self._pong_not_received, self._pong_heartbeat, self._loop + ) + + def _pong_not_received(self) -> None: + if self._req is not None and self._req.transport is not None: + self._closed = True + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = asyncio.TimeoutError() + self._req.transport.close() + + async def prepare(self, request: BaseRequest) -> AbstractStreamWriter: + # make pre-check to don't hide it by do_handshake() exceptions + if self._payload_writer is not None: + return self._payload_writer + + protocol, writer = self._pre_start(request) + payload_writer = await super().prepare(request) + assert payload_writer is not None + self._post_start(request, protocol, writer) + await payload_writer.drain() + return payload_writer + + def _handshake( + self, request: BaseRequest + ) -> Tuple["CIMultiDict[str]", str, bool, bool]: + headers = request.headers + if "websocket" != headers.get(hdrs.UPGRADE, "").lower().strip(): + raise HTTPBadRequest( + text=( + "No WebSocket UPGRADE hdr: {}\n Can " + '"Upgrade" only to "WebSocket".' + ).format(headers.get(hdrs.UPGRADE)) + ) + + if "upgrade" not in headers.get(hdrs.CONNECTION, "").lower(): + raise HTTPBadRequest( + text="No CONNECTION upgrade hdr: {}".format( + headers.get(hdrs.CONNECTION) + ) + ) + + # find common sub-protocol between client and server + protocol = None + if hdrs.SEC_WEBSOCKET_PROTOCOL in headers: + req_protocols = [ + str(proto.strip()) + for proto in headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",") + ] + + for proto in req_protocols: + if proto in self._protocols: + protocol = proto + break + else: + # No overlap found: Return no protocol as per spec + ws_logger.warning( + "Client protocols %r don’t overlap server-known ones %r", + req_protocols, + self._protocols, + ) + + # check supported version + version = headers.get(hdrs.SEC_WEBSOCKET_VERSION, "") + if version not in ("13", "8", "7"): + raise HTTPBadRequest(text=f"Unsupported version: {version}") + + # check client handshake for validity + key = headers.get(hdrs.SEC_WEBSOCKET_KEY) + try: + if not key or len(base64.b64decode(key)) != 16: + raise HTTPBadRequest(text=f"Handshake error: {key!r}") + except binascii.Error: + raise HTTPBadRequest(text=f"Handshake error: {key!r}") from None + + accept_val = base64.b64encode( + hashlib.sha1(key.encode() + WS_KEY).digest() + ).decode() + response_headers = CIMultiDict( + { + hdrs.UPGRADE: "websocket", + hdrs.CONNECTION: "upgrade", + hdrs.SEC_WEBSOCKET_ACCEPT: accept_val, + } + ) + + notakeover = False + compress = 0 + if self._compress: + extensions = headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS) + # Server side always get return with no exception. + # If something happened, just drop compress extension + compress, notakeover = ws_ext_parse(extensions, isserver=True) + if compress: + enabledext = ws_ext_gen( + compress=compress, isserver=True, server_notakeover=notakeover + ) + response_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = enabledext + + if protocol: + response_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = protocol + return ( + response_headers, + protocol, + compress, + notakeover, + ) # type: ignore[return-value] + + def _pre_start(self, request: BaseRequest) -> Tuple[str, WebSocketWriter]: + self._loop = request._loop + + headers, protocol, compress, notakeover = self._handshake(request) + + self.set_status(101) + self.headers.update(headers) + self.force_close() + self._compress = compress + transport = request._protocol.transport + assert transport is not None + writer = WebSocketWriter( + request._protocol, transport, compress=compress, notakeover=notakeover + ) + + return protocol, writer + + def _post_start( + self, request: BaseRequest, protocol: str, writer: WebSocketWriter + ) -> None: + self._ws_protocol = protocol + self._writer = writer + + self._reset_heartbeat() + + loop = self._loop + assert loop is not None + self._reader = FlowControlDataQueue(request._protocol, 2**16, loop=loop) + request.protocol.set_parser( + WebSocketReader(self._reader, self._max_msg_size, compress=self._compress) + ) + # disable HTTP keepalive for WebSocket + request.protocol.keep_alive(False) + + def can_prepare(self, request: BaseRequest) -> WebSocketReady: + if self._writer is not None: + raise RuntimeError("Already started") + try: + _, protocol, _, _ = self._handshake(request) + except HTTPException: + return WebSocketReady(False, None) + else: + return WebSocketReady(True, protocol) + + @property + def closed(self) -> bool: + return self._closed + + @property + def close_code(self) -> Optional[int]: + return self._close_code + + @property + def ws_protocol(self) -> Optional[str]: + return self._ws_protocol + + @property + def compress(self) -> bool: + return self._compress + + def exception(self) -> Optional[BaseException]: + return self._exception + + async def ping(self, message: bytes = b"") -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + await self._writer.ping(message) + + async def pong(self, message: bytes = b"") -> None: + # unsolicited pong + if self._writer is None: + raise RuntimeError("Call .prepare() first") + await self._writer.pong(message) + + async def send_str(self, data: str, compress: Optional[bool] = None) -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + if not isinstance(data, str): + raise TypeError("data argument must be str (%r)" % type(data)) + await self._writer.send(data, binary=False, compress=compress) + + async def send_bytes(self, data: bytes, compress: Optional[bool] = None) -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data argument must be byte-ish (%r)" % type(data)) + await self._writer.send(data, binary=True, compress=compress) + + async def send_json( + self, + data: Any, + compress: Optional[bool] = None, + *, + dumps: JSONEncoder = json.dumps, + ) -> None: + await self.send_str(dumps(data), compress=compress) + + async def write_eof(self) -> None: # type: ignore[override] + if self._eof_sent: + return + if self._payload_writer is None: + raise RuntimeError("Response has not been started") + + await self.close() + self._eof_sent = True + + async def close(self, *, code: int = WSCloseCode.OK, message: bytes = b"") -> bool: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + + self._cancel_heartbeat() + reader = self._reader + assert reader is not None + + # we need to break `receive()` cycle first, + # `close()` may be called from different task + if self._waiting is not None and not self._closed: + reader.feed_data(WS_CLOSING_MESSAGE, 0) + await self._waiting + + if not self._closed: + self._closed = True + try: + await self._writer.close(code, message) + writer = self._payload_writer + assert writer is not None + await writer.drain() + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + raise + except Exception as exc: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = exc + return True + + if self._closing: + return True + + reader = self._reader + assert reader is not None + try: + async with async_timeout.timeout(self._timeout): + msg = await reader.read() + except asyncio.CancelledError: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + raise + except Exception as exc: + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = exc + return True + + if msg.type == WSMsgType.CLOSE: + self._close_code = msg.data + return True + + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + self._exception = asyncio.TimeoutError() + return True + else: + return False + + async def receive(self, timeout: Optional[float] = None) -> WSMessage: + if self._reader is None: + raise RuntimeError("Call .prepare() first") + + loop = self._loop + assert loop is not None + while True: + if self._waiting is not None: + raise RuntimeError("Concurrent call to receive() is not allowed") + + if self._closed: + self._conn_lost += 1 + if self._conn_lost >= THRESHOLD_CONNLOST_ACCESS: + raise RuntimeError("WebSocket connection is closed.") + return WS_CLOSED_MESSAGE + elif self._closing: + return WS_CLOSING_MESSAGE + + try: + self._waiting = loop.create_future() + try: + async with async_timeout.timeout(timeout or self._receive_timeout): + msg = await self._reader.read() + self._reset_heartbeat() + finally: + waiter = self._waiting + set_result(waiter, True) + self._waiting = None + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + raise + except EofStream: + self._close_code = WSCloseCode.OK + await self.close() + return WSMessage(WSMsgType.CLOSED, None, None) + except WebSocketError as exc: + self._close_code = exc.code + await self.close(code=exc.code) + return WSMessage(WSMsgType.ERROR, exc, None) + except Exception as exc: + self._exception = exc + self._closing = True + self._close_code = WSCloseCode.ABNORMAL_CLOSURE + await self.close() + return WSMessage(WSMsgType.ERROR, exc, None) + + if msg.type == WSMsgType.CLOSE: + self._closing = True + self._close_code = msg.data + if not self._closed and self._autoclose: + await self.close() + elif msg.type == WSMsgType.CLOSING: + self._closing = True + elif msg.type == WSMsgType.PING and self._autoping: + await self.pong(msg.data) + continue + elif msg.type == WSMsgType.PONG and self._autoping: + continue + + return msg + + async def receive_str(self, *, timeout: Optional[float] = None) -> str: + msg = await self.receive(timeout) + if msg.type != WSMsgType.TEXT: + raise TypeError( + "Received message {}:{!r} is not WSMsgType.TEXT".format( + msg.type, msg.data + ) + ) + return cast(str, msg.data) + + async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: + msg = await self.receive(timeout) + if msg.type != WSMsgType.BINARY: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") + return cast(bytes, msg.data) + + async def receive_json( + self, *, loads: JSONDecoder = json.loads, timeout: Optional[float] = None + ) -> Any: + data = await self.receive_str(timeout=timeout) + return loads(data) + + async def write(self, data: bytes) -> None: + raise RuntimeError("Cannot call .write() for websocket") + + def __aiter__(self) -> "WebSocketResponse": + return self + + async def __anext__(self) -> WSMessage: + msg = await self.receive() + if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): + raise StopAsyncIteration + return msg + + def _cancel(self, exc: BaseException) -> None: + if self._reader is not None: + self._reader.set_exception(exc) diff --git a/.venv/lib/python3.7/site-packages/aiohttp/worker.py b/.venv/lib/python3.7/site-packages/aiohttp/worker.py new file mode 100644 index 0000000..ab6007a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiohttp/worker.py @@ -0,0 +1,269 @@ +"""Async gunicorn worker for aiohttp.web""" + +import asyncio +import os +import re +import signal +import sys +from types import FrameType +from typing import Any, Awaitable, Callable, Optional, Union # noqa + +from gunicorn.config import AccessLogFormat as GunicornAccessLogFormat +from gunicorn.workers import base + +from aiohttp import web + +from .helpers import set_result +from .web_app import Application +from .web_log import AccessLogger + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] + + +__all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker", "GunicornTokioWebWorker") + + +class GunicornWebWorker(base.Worker): # type: ignore[misc,no-any-unimported] + + DEFAULT_AIOHTTP_LOG_FORMAT = AccessLogger.LOG_FORMAT + DEFAULT_GUNICORN_LOG_FORMAT = GunicornAccessLogFormat.default + + def __init__(self, *args: Any, **kw: Any) -> None: # pragma: no cover + super().__init__(*args, **kw) + + self._task: Optional[asyncio.Task[None]] = None + self.exit_code = 0 + self._notify_waiter: Optional[asyncio.Future[bool]] = None + + def init_process(self) -> None: + # create new event_loop after fork + asyncio.get_event_loop().close() + + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + + super().init_process() + + def run(self) -> None: + self._task = self.loop.create_task(self._run()) + + try: # ignore all finalization problems + self.loop.run_until_complete(self._task) + except Exception: + self.log.exception("Exception in gunicorn worker") + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + self.loop.close() + + sys.exit(self.exit_code) + + async def _run(self) -> None: + runner = None + if isinstance(self.wsgi, Application): + app = self.wsgi + elif asyncio.iscoroutinefunction(self.wsgi): + wsgi = await self.wsgi() + if isinstance(wsgi, web.AppRunner): + runner = wsgi + app = runner.app + else: + app = wsgi + else: + raise RuntimeError( + "wsgi app should be either Application or " + "async function returning Application, got {}".format(self.wsgi) + ) + + if runner is None: + access_log = self.log.access_log if self.cfg.accesslog else None + runner = web.AppRunner( + app, + logger=self.log, + keepalive_timeout=self.cfg.keepalive, + access_log=access_log, + access_log_format=self._get_valid_log_format( + self.cfg.access_log_format + ), + ) + await runner.setup() + + ctx = self._create_ssl_context(self.cfg) if self.cfg.is_ssl else None + + runner = runner + assert runner is not None + server = runner.server + assert server is not None + for sock in self.sockets: + site = web.SockSite( + runner, + sock, + ssl_context=ctx, + shutdown_timeout=self.cfg.graceful_timeout / 100 * 95, + ) + await site.start() + + # If our parent changed then we shut down. + pid = os.getpid() + try: + while self.alive: # type: ignore[has-type] + self.notify() + + cnt = server.requests_count + if self.max_requests and cnt > self.max_requests: + self.alive = False + self.log.info("Max requests, shutting down: %s", self) + + elif pid == os.getpid() and self.ppid != os.getppid(): + self.alive = False + self.log.info("Parent changed, shutting down: %s", self) + else: + await self._wait_next_notify() + except BaseException: + pass + + await runner.cleanup() + + def _wait_next_notify(self) -> "asyncio.Future[bool]": + self._notify_waiter_done() + + loop = self.loop + assert loop is not None + self._notify_waiter = waiter = loop.create_future() + self.loop.call_later(1.0, self._notify_waiter_done, waiter) + + return waiter + + def _notify_waiter_done( + self, waiter: Optional["asyncio.Future[bool]"] = None + ) -> None: + if waiter is None: + waiter = self._notify_waiter + if waiter is not None: + set_result(waiter, True) + + if waiter is self._notify_waiter: + self._notify_waiter = None + + def init_signals(self) -> None: + # Set up signals through the event loop API. + + self.loop.add_signal_handler( + signal.SIGQUIT, self.handle_quit, signal.SIGQUIT, None + ) + + self.loop.add_signal_handler( + signal.SIGTERM, self.handle_exit, signal.SIGTERM, None + ) + + self.loop.add_signal_handler( + signal.SIGINT, self.handle_quit, signal.SIGINT, None + ) + + self.loop.add_signal_handler( + signal.SIGWINCH, self.handle_winch, signal.SIGWINCH, None + ) + + self.loop.add_signal_handler( + signal.SIGUSR1, self.handle_usr1, signal.SIGUSR1, None + ) + + self.loop.add_signal_handler( + signal.SIGABRT, self.handle_abort, signal.SIGABRT, None + ) + + # Don't let SIGTERM and SIGUSR1 disturb active requests + # by interrupting system calls + signal.siginterrupt(signal.SIGTERM, False) + signal.siginterrupt(signal.SIGUSR1, False) + # Reset signals so Gunicorn doesn't swallow subprocess return codes + # See: https://github.com/aio-libs/aiohttp/issues/6130 + if sys.version_info < (3, 8): + # Starting from Python 3.8, + # the default child watcher is ThreadedChildWatcher. + # The watcher doesn't depend on SIGCHLD signal, + # there is no need to reset it. + signal.signal(signal.SIGCHLD, signal.SIG_DFL) + + def handle_quit(self, sig: int, frame: FrameType) -> None: + self.alive = False + + # worker_int callback + self.cfg.worker_int(self) + + # wakeup closing process + self._notify_waiter_done() + + def handle_abort(self, sig: int, frame: FrameType) -> None: + self.alive = False + self.exit_code = 1 + self.cfg.worker_abort(self) + sys.exit(1) + + @staticmethod + def _create_ssl_context(cfg: Any) -> "SSLContext": + """Creates SSLContext instance for usage in asyncio.create_server. + + See ssl.SSLSocket.__init__ for more details. + """ + if ssl is None: # pragma: no cover + raise RuntimeError("SSL is not supported.") + + ctx = ssl.SSLContext(cfg.ssl_version) + ctx.load_cert_chain(cfg.certfile, cfg.keyfile) + ctx.verify_mode = cfg.cert_reqs + if cfg.ca_certs: + ctx.load_verify_locations(cfg.ca_certs) + if cfg.ciphers: + ctx.set_ciphers(cfg.ciphers) + return ctx + + def _get_valid_log_format(self, source_format: str) -> str: + if source_format == self.DEFAULT_GUNICORN_LOG_FORMAT: + return self.DEFAULT_AIOHTTP_LOG_FORMAT + elif re.search(r"%\([^\)]+\)", source_format): + raise ValueError( + "Gunicorn's style options in form of `%(name)s` are not " + "supported for the log formatting. Please use aiohttp's " + "format specification to configure access log formatting: " + "http://docs.aiohttp.org/en/stable/logging.html" + "#format-specification" + ) + else: + return source_format + + +class GunicornUVLoopWebWorker(GunicornWebWorker): + def init_process(self) -> None: + import uvloop + + # Close any existing event loop before setting a + # new policy. + asyncio.get_event_loop().close() + + # Setup uvloop policy, so that every + # asyncio.get_event_loop() will create an instance + # of uvloop event loop. + asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) + + super().init_process() + + +class GunicornTokioWebWorker(GunicornWebWorker): + def init_process(self) -> None: # pragma: no cover + import tokio + + # Close any existing event loop before setting a + # new policy. + asyncio.get_event_loop().close() + + # Setup tokio policy, so that every + # asyncio.get_event_loop() will create an instance + # of tokio event loop. + asyncio.set_event_loop_policy(tokio.EventLoopPolicy()) + + super().init_process() diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/LICENSE b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/LICENSE new file mode 100644 index 0000000..7082a2d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2019 Nikolay Kim and Andrew Svetlov + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/METADATA b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/METADATA new file mode 100644 index 0000000..fc96452 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/METADATA @@ -0,0 +1,128 @@ +Metadata-Version: 2.1 +Name: aiosignal +Version: 1.3.1 +Summary: aiosignal: a list of registered asynchronous callbacks +Home-page: https://github.com/aio-libs/aiosignal +Maintainer: aiohttp team +Maintainer-email: team@aiohttp.org +License: Apache 2.0 +Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby +Project-URL: CI: GitHub Actions, https://github.com/aio-libs/aiosignal/actions +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiosignal +Project-URL: Docs: RTD, https://docs.aiosignal.org +Project-URL: GitHub: issues, https://github.com/aio-libs/aiosignal/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/aiosignal +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Framework :: AsyncIO +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: frozenlist (>=1.1.0) + +========= +aiosignal +========= + +.. image:: https://github.com/aio-libs/aiosignal/workflows/CI/badge.svg + :target: https://github.com/aio-libs/aiosignal/actions?query=workflow%3ACI + :alt: GitHub status for master branch + +.. image:: https://codecov.io/gh/aio-libs/aiosignal/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/aiosignal + :alt: codecov.io status for master branch + +.. image:: https://badge.fury.io/py/aiosignal.svg + :target: https://pypi.org/project/aiosignal + :alt: Latest PyPI package version + +.. image:: https://readthedocs.org/projects/aiosignal/badge/?version=latest + :target: https://aiosignal.readthedocs.io/ + :alt: Latest Read The Docs + +.. image:: https://img.shields.io/discourse/topics?server=https%3A%2F%2Faio-libs.discourse.group%2F + :target: https://aio-libs.discourse.group/ + :alt: Discourse group for io-libs + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :target: https://gitter.im/aio-libs/Lobby + :alt: Chat on Gitter + +Introduction +============ + +A project to manage callbacks in `asyncio` projects. + +``Signal`` is a list of registered asynchronous callbacks. + +The signal's life-cycle has two stages: after creation its content +could be filled by using standard list operations: ``sig.append()`` +etc. + +After you call ``sig.freeze()`` the signal is *frozen*: adding, removing +and dropping callbacks is forbidden. + +The only available operation is calling the previously registered +callbacks by using ``await sig.send(data)``. + +For concrete usage examples see the `Signals + +section of the `Web Server Advanced +` chapter of the `aiohttp +documentation`_. + + +Installation +------------ + +:: + + $ pip install aiosignal + +The library requires Python 3.6 or newer. + + +Documentation +============= + +https://aiosignal.readthedocs.io/ + +Communication channels +====================== + +*gitter chat* https://gitter.im/aio-libs/Lobby + +Requirements +============ + +- Python >= 3.6 +- frozenlist >= 1.0.0 + +License +======= + +``aiosignal`` is offered under the Apache 2 license. + +Source code +=========== + +The project is hosted on GitHub_ + +Please file an issue in the `bug tracker +`_ if you have found a bug +or have some suggestions to improve the library. + +.. _GitHub: https://github.com/aio-libs/aiosignal +.. _aiohttp documentation: https://docs.aiohttp.org/ diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/RECORD b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/RECORD new file mode 100644 index 0000000..fd244a9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/RECORD @@ -0,0 +1,10 @@ +aiosignal-1.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +aiosignal-1.3.1.dist-info/LICENSE,sha256=b9UkPpLdf5jsacesN3co50kFcJ_1J6W_mNbQJjwE9bY,11332 +aiosignal-1.3.1.dist-info/METADATA,sha256=c0HRnlYzfXKztZPTFDlPfygizTherhG5WdwXlvco0Ug,4008 +aiosignal-1.3.1.dist-info/RECORD,, +aiosignal-1.3.1.dist-info/WHEEL,sha256=ZL1lC_LiPDNRgDnOl2taCMc83aPEUZgHHv2h-LDgdiM,92 +aiosignal-1.3.1.dist-info/top_level.txt,sha256=z45aNOKGDdrI1roqZY3BGXQ22kJFPHBmVdwtLYLtXC0,10 +aiosignal/__init__.py,sha256=zQNfFYRSd84bswvpFv8ZWjEr5DeYwV3LXbMSyo2222s,867 +aiosignal/__init__.pyi,sha256=xeCddYSS8fZAkz8S4HuKSR2IDe3N7RW_LKcXDPPA1Xk,311 +aiosignal/__pycache__/__init__.cpython-37.pyc,, +aiosignal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/WHEEL new file mode 100644 index 0000000..5e1f087 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/top_level.txt new file mode 100644 index 0000000..ac6df3a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal-1.3.1.dist-info/top_level.txt @@ -0,0 +1 @@ +aiosignal diff --git a/.venv/lib/python3.7/site-packages/aiosignal/__init__.py b/.venv/lib/python3.7/site-packages/aiosignal/__init__.py new file mode 100644 index 0000000..3d288e6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal/__init__.py @@ -0,0 +1,36 @@ +from frozenlist import FrozenList + +__version__ = "1.3.1" + +__all__ = ("Signal",) + + +class Signal(FrozenList): + """Coroutine-based signal implementation. + + To connect a callback to a signal, use any list method. + + Signals are fired using the send() coroutine, which takes named + arguments. + """ + + __slots__ = ("_owner",) + + def __init__(self, owner): + super().__init__() + self._owner = owner + + def __repr__(self): + return "".format( + self._owner, self.frozen, list(self) + ) + + async def send(self, *args, **kwargs): + """ + Sends data to all registered receivers. + """ + if not self.frozen: + raise RuntimeError("Cannot send non-frozen signal.") + + for receiver in self: + await receiver(*args, **kwargs) # type: ignore diff --git a/.venv/lib/python3.7/site-packages/aiosignal/__init__.pyi b/.venv/lib/python3.7/site-packages/aiosignal/__init__.pyi new file mode 100644 index 0000000..d4e3416 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/aiosignal/__init__.pyi @@ -0,0 +1,12 @@ +from typing import Any, Generic, TypeVar + +from frozenlist import FrozenList + +__all__ = ("Signal",) + +_T = TypeVar("_T") + +class Signal(FrozenList[_T], Generic[_T]): + def __init__(self, owner: Any) -> None: ... + def __repr__(self) -> str: ... + async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/.venv/lib/python3.7/site-packages/aiosignal/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiosignal/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..485995b90998ca485f26db1b05d859566841b24d GIT binary patch literal 1282 zcmZ8g&u<(x6t-tPyOT{q4@C4*RfbbXN;VB`50y$)5!!-;av(@ZBO%KjdpFa}*jw96 z=yr2}MCz^Q9@``T1OEd@q`7k9U*N=hp4}2*$-m~kdGGt)`~2nh_K3iE`^%rxDkbDE zysQUcgJV(*{|0YT&~Eg^*@ZUW z);=tnNzt+Vq`8@=~TdabyR$#~t)8r^CWWT>qfk47BE_m)@I7+nP} zc_o|XnXFEEuyE^t+vRhwxil|%0~C0x!--X^pL-UbOQ-pyc93fBYcu8HM02l=x>Z2% z6_#Coc2ZX-Jjhe+xsk0_5rA~lIfC-zc*WufduFt&lD-}UcbrJh@4yns1$jr`6H1nJ zNkpOukf%pQ+GTz|)2_>fs7)P&aM-*e>6q8eq|0Jl$gm+q)kyD!_>KH?e?PRd{aHQR ztBns(fxYJQJAQiapx&3Y?Tc{bv<^LtVJ{xPD$G=z@m;#yyl@!G4RXn}z{x*x*y zpTMH%JF+Ctfxz=5q)T!^-={z$Ia+-7pbx?$+%I08@A661P&~f+)SW*pST~qh*UAtX z!X-L%40}{iH-rQZCEYKZaKfTEJ##`_huaD+Ns&0bG&rONS9k+^LD)opz@H=%CzW9O_ZSft)DP?hfn zr)RjA`8xjpO9HYm>IU-5VIgcl^8}i>xoRR>iw!Is%2kMNBt&b~yutI95HIGkSy_fc zC|kj2kd|+30BJ>axN8vCp+>sxmFOznG+_PE9cb4EI$@LI14b+!&H0ceEZJgt7QY`A vSvl&ffNgg8Cb~@_uyF98AvvG`{X%ejD*t7;DuM?+frqF^kAmES6fFH0_rpXX literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiosignal/py.typed b/.venv/lib/python3.7/site-packages/aiosignal/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/LICENSE b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/LICENSE new file mode 100644 index 0000000..033c86b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/LICENSE @@ -0,0 +1,13 @@ +Copyright 2016-2020 aio-libs collaboration. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/METADATA b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/METADATA new file mode 100644 index 0000000..d8dd6d1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/METADATA @@ -0,0 +1,131 @@ +Metadata-Version: 2.1 +Name: async-timeout +Version: 4.0.3 +Summary: Timeout context manager for asyncio programs +Home-page: https://github.com/aio-libs/async-timeout +Author: Andrew Svetlov +Author-email: andrew.svetlov@gmail.com +License: Apache 2 +Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby +Project-URL: CI: GitHub Actions, https://github.com/aio-libs/async-timeout/actions +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/async-timeout +Project-URL: GitHub: issues, https://github.com/aio-libs/async-timeout/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/async-timeout +Classifier: Development Status :: 5 - Production/Stable +Classifier: Topic :: Software Development :: Libraries +Classifier: Framework :: AsyncIO +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: typing-extensions >=3.6.5 ; python_version < "3.8" + +async-timeout +============= +.. image:: https://travis-ci.com/aio-libs/async-timeout.svg?branch=master + :target: https://travis-ci.com/aio-libs/async-timeout +.. image:: https://codecov.io/gh/aio-libs/async-timeout/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/async-timeout +.. image:: https://img.shields.io/pypi/v/async-timeout.svg + :target: https://pypi.python.org/pypi/async-timeout +.. image:: https://badges.gitter.im/Join%20Chat.svg + :target: https://gitter.im/aio-libs/Lobby + :alt: Chat on Gitter + +asyncio-compatible timeout context manager. + + +Usage example +------------- + + +The context manager is useful in cases when you want to apply timeout +logic around block of code or in cases when ``asyncio.wait_for()`` is +not suitable. Also it's much faster than ``asyncio.wait_for()`` +because ``timeout`` doesn't create a new task. + +The ``timeout(delay, *, loop=None)`` call returns a context manager +that cancels a block on *timeout* expiring:: + + from async_timeout import timeout + async with timeout(1.5): + await inner() + +1. If ``inner()`` is executed faster than in ``1.5`` seconds nothing + happens. +2. Otherwise ``inner()`` is cancelled internally by sending + ``asyncio.CancelledError`` into but ``asyncio.TimeoutError`` is + raised outside of context manager scope. + +*timeout* parameter could be ``None`` for skipping timeout functionality. + + +Alternatively, ``timeout_at(when)`` can be used for scheduling +at the absolute time:: + + loop = asyncio.get_event_loop() + now = loop.time() + + async with timeout_at(now + 1.5): + await inner() + + +Please note: it is not POSIX time but a time with +undefined starting base, e.g. the time of the system power on. + + +Context manager has ``.expired`` property for check if timeout happens +exactly in context manager:: + + async with timeout(1.5) as cm: + await inner() + print(cm.expired) + +The property is ``True`` if ``inner()`` execution is cancelled by +timeout context manager. + +If ``inner()`` call explicitly raises ``TimeoutError`` ``cm.expired`` +is ``False``. + +The scheduled deadline time is available as ``.deadline`` property:: + + async with timeout(1.5) as cm: + cm.deadline + +Not finished yet timeout can be rescheduled by ``shift_by()`` +or ``shift_to()`` methods:: + + async with timeout(1.5) as cm: + cm.shift(1) # add another second on waiting + cm.update(loop.time() + 5) # reschedule to now+5 seconds + +Rescheduling is forbidden if the timeout is expired or after exit from ``async with`` +code block. + + +Installation +------------ + +:: + + $ pip install async-timeout + +The library is Python 3 only! + + + +Authors and License +------------------- + +The module is written by Andrew Svetlov. + +It's *Apache 2* licensed and freely available. diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/RECORD b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/RECORD new file mode 100644 index 0000000..3b07f09 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/RECORD @@ -0,0 +1,10 @@ +async_timeout-4.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +async_timeout-4.0.3.dist-info/LICENSE,sha256=4Y17uPUT4sRrtYXJS1hb0wcg3TzLId2weG9y0WZY-Sw,568 +async_timeout-4.0.3.dist-info/METADATA,sha256=WQVcnDIXQ2ntebcm-vYjhNLg_VMeTWw13_ReT-U36J4,4209 +async_timeout-4.0.3.dist-info/RECORD,, +async_timeout-4.0.3.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +async_timeout-4.0.3.dist-info/top_level.txt,sha256=9oM4e7Twq8iD_7_Q3Mz0E6GPIB6vJvRFo-UBwUQtBDU,14 +async_timeout-4.0.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +async_timeout/__init__.py,sha256=A0VOqDGQ3cCPFp0NZJKIbx_VRP1Y2xPtQOZebVIUB88,7242 +async_timeout/__pycache__/__init__.cpython-37.pyc,, +async_timeout/py.typed,sha256=tyozzRT1fziXETDxokmuyt6jhOmtjUbnVNJdZcG7ik0,12 diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/top_level.txt new file mode 100644 index 0000000..ad29955 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/top_level.txt @@ -0,0 +1 @@ +async_timeout diff --git a/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/zip-safe b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout-4.0.3.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/.venv/lib/python3.7/site-packages/async_timeout/__init__.py b/.venv/lib/python3.7/site-packages/async_timeout/__init__.py new file mode 100644 index 0000000..1ffb069 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/async_timeout/__init__.py @@ -0,0 +1,239 @@ +import asyncio +import enum +import sys +import warnings +from types import TracebackType +from typing import Optional, Type + + +if sys.version_info >= (3, 8): + from typing import final +else: + from typing_extensions import final + + +if sys.version_info >= (3, 11): + + def _uncancel_task(task: "asyncio.Task[object]") -> None: + task.uncancel() + +else: + + def _uncancel_task(task: "asyncio.Task[object]") -> None: + pass + + +__version__ = "4.0.3" + + +__all__ = ("timeout", "timeout_at", "Timeout") + + +def timeout(delay: Optional[float]) -> "Timeout": + """timeout context manager. + + Useful in cases when you want to apply timeout logic around block + of code or in cases when asyncio.wait_for is not suitable. For example: + + >>> async with timeout(0.001): + ... async with aiohttp.get('https://github.com') as r: + ... await r.text() + + + delay - value in seconds or None to disable timeout logic + """ + loop = asyncio.get_running_loop() + if delay is not None: + deadline = loop.time() + delay # type: Optional[float] + else: + deadline = None + return Timeout(deadline, loop) + + +def timeout_at(deadline: Optional[float]) -> "Timeout": + """Schedule the timeout at absolute time. + + deadline argument points on the time in the same clock system + as loop.time(). + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + + >>> async with timeout_at(loop.time() + 10): + ... async with aiohttp.get('https://github.com') as r: + ... await r.text() + + + """ + loop = asyncio.get_running_loop() + return Timeout(deadline, loop) + + +class _State(enum.Enum): + INIT = "INIT" + ENTER = "ENTER" + TIMEOUT = "TIMEOUT" + EXIT = "EXIT" + + +@final +class Timeout: + # Internal class, please don't instantiate it directly + # Use timeout() and timeout_at() public factories instead. + # + # Implementation note: `async with timeout()` is preferred + # over `with timeout()`. + # While technically the Timeout class implementation + # doesn't need to be async at all, + # the `async with` statement explicitly points that + # the context manager should be used from async function context. + # + # This design allows to avoid many silly misusages. + # + # TimeoutError is raised immediately when scheduled + # if the deadline is passed. + # The purpose is to time out as soon as possible + # without waiting for the next await expression. + + __slots__ = ("_deadline", "_loop", "_state", "_timeout_handler", "_task") + + def __init__( + self, deadline: Optional[float], loop: asyncio.AbstractEventLoop + ) -> None: + self._loop = loop + self._state = _State.INIT + + self._task: Optional["asyncio.Task[object]"] = None + self._timeout_handler = None # type: Optional[asyncio.Handle] + if deadline is None: + self._deadline = None # type: Optional[float] + else: + self.update(deadline) + + def __enter__(self) -> "Timeout": + warnings.warn( + "with timeout() is deprecated, use async with timeout() instead", + DeprecationWarning, + stacklevel=2, + ) + self._do_enter() + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + self._do_exit(exc_type) + return None + + async def __aenter__(self) -> "Timeout": + self._do_enter() + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + self._do_exit(exc_type) + return None + + @property + def expired(self) -> bool: + """Is timeout expired during execution?""" + return self._state == _State.TIMEOUT + + @property + def deadline(self) -> Optional[float]: + return self._deadline + + def reject(self) -> None: + """Reject scheduled timeout if any.""" + # cancel is maybe better name but + # task.cancel() raises CancelledError in asyncio world. + if self._state not in (_State.INIT, _State.ENTER): + raise RuntimeError(f"invalid state {self._state.value}") + self._reject() + + def _reject(self) -> None: + self._task = None + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._timeout_handler = None + + def shift(self, delay: float) -> None: + """Advance timeout on delay seconds. + + The delay can be negative. + + Raise RuntimeError if shift is called when deadline is not scheduled + """ + deadline = self._deadline + if deadline is None: + raise RuntimeError("cannot shift timeout if deadline is not scheduled") + self.update(deadline + delay) + + def update(self, deadline: float) -> None: + """Set deadline to absolute value. + + deadline argument points on the time in the same clock system + as loop.time(). + + If new deadline is in the past the timeout is raised immediately. + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + """ + if self._state == _State.EXIT: + raise RuntimeError("cannot reschedule after exit from context manager") + if self._state == _State.TIMEOUT: + raise RuntimeError("cannot reschedule expired timeout") + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._deadline = deadline + if self._state != _State.INIT: + self._reschedule() + + def _reschedule(self) -> None: + assert self._state == _State.ENTER + deadline = self._deadline + if deadline is None: + return + + now = self._loop.time() + if self._timeout_handler is not None: + self._timeout_handler.cancel() + + self._task = asyncio.current_task() + if deadline <= now: + self._timeout_handler = self._loop.call_soon(self._on_timeout) + else: + self._timeout_handler = self._loop.call_at(deadline, self._on_timeout) + + def _do_enter(self) -> None: + if self._state != _State.INIT: + raise RuntimeError(f"invalid state {self._state.value}") + self._state = _State.ENTER + self._reschedule() + + def _do_exit(self, exc_type: Optional[Type[BaseException]]) -> None: + if exc_type is asyncio.CancelledError and self._state == _State.TIMEOUT: + assert self._task is not None + _uncancel_task(self._task) + self._timeout_handler = None + self._task = None + raise asyncio.TimeoutError + # timeout has not expired + self._state = _State.EXIT + self._reject() + return None + + def _on_timeout(self) -> None: + assert self._task is not None + self._task.cancel() + self._state = _State.TIMEOUT + # drop the reference early + self._timeout_handler = None diff --git a/.venv/lib/python3.7/site-packages/async_timeout/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/async_timeout/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8976033fb9a45c9808575c1dea252eee0ca5781d GIT binary patch literal 6484 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 e5D*OMUln!Y+O9ekd!QCj4bC=3.5 + +.. image:: https://img.shields.io/pypi/v/asynctest.svg + :target: https://pypi.python.org/pypi/asynctest + :alt: PyPI +.. image:: https://travis-ci.org/Martiusweb/asynctest.svg?branch=master + :target: https://travis-ci.org/Martiusweb/asynctest + :alt: Travis +.. image:: https://ci.appveyor.com/api/projects/status/github/Martiusweb/asynctest?branch=master&svg=true + :target: https://ci.appveyor.com/project/Martiusweb/asynctest/branch/master + :alt: AppVeyor +.. image:: https://img.shields.io/pypi/pyversions/asynctest.svg + :target: https://github.com/Martiusweb/asynctest + :alt: Supported Python versions + +========= +asynctest +========= + +The package asynctest is built on top of the standard unittest module and +cuts down boilerplate code when testing libraries for asyncio. + +Currently, asynctest targets the "selector" model, hence, some features +will not (yet?) work with Windows' proactor. + +.. warning:: + + Since asynctest 0.13, Python 3.4 is not supported anymore. + +Author & license +---------------- + +Authored by Martin Richard and licensed under the +Apache 2 license. + +See the AUTHORS file for a comprehensive list of the authors. + +Documentation +------------- + +.. image:: https://readthedocs.org/projects/asynctest/badge/ + :target: http://asynctest.readthedocs.org/en/latest/ + +Full documentation is available at http://asynctest.readthedocs.org/en/latest/. +It includes a tutorial with tested examples of how to use ``TestCase`` or +mocks. + +Features +-------- + +TestCases +~~~~~~~~~ + + - Initialize and close a loop created for each test (it can be + configurated), if the loop uses a selector, it will be updated with + a TestSelector object wrapping the original selector (see below), + + - if the test function is a coroutine function or returns a coroutine, it + will run on the loop, + + - TestCase.setUp() and TestCase.tearDown() can be coroutine functions, + + - control post-test checks with `@fail_on`, for instance, the test fail if + the loop didn't run, some optional checks can be activated, + + - ClockedTestCase allows to control the loop clock and run timed events + without waiting the wall clock. + +Mock and CoroutineMock +~~~~~~~~~~~~~~~~~~~~~~ + + - CoroutineMock is a new Mock class which mocks a coroutine function, and + returns a coroutine when called, + + - MagicMock supports asynchronous context managers and asynchronous + iterators, + + - NonCallableMock, Mock and CoroutineMock can return CoroutineMock objects + when its attributes are get if there is a matching attribute in the spec + (or spec_set) object which is a coroutine function, + + - patch(), patch.object(), patch.multiple() return a MagickMock or + CoroutineMock object by default, according to the patched target, + + - patch(), patch.object(), patch.multiple() handle generators and coroutines + and their behavior can be controled when the generator or coroutine pauses, + + - all the patch() methods can decorate coroutine functions, + + - mock_open() returns a MagickMock object by default. + + - return_once() can be used with Mock.side_effect to return a value only + once when a mock is called. + +Selectors +~~~~~~~~~ + +The module asynctest.selector provides classes to mock objects performing IO +(files, sockets, etc). + + - FileMock is a special type of mock which represents a file. + FileMock.fileno() returns a special value which allows to identify uniquely + the mock, + + - SocketMock is a special type of FileMock which uses socket.socket as spec, + + - TestSelector is a custom selector able to wrap a real selector + implementation and deal with FileMock objects, it can replace a selector + loop by calling `loop._selector = TestSelector(loop._selector)`, and will + intercept mock so they don't get registered to the actual selector. + + - set_read_ready() and set_write_ready() to force read and write event + callbacks to be scheduled on the loop, as if the selector scheduled them. + +Helpers +~~~~~~~ + + - the coroutine exhaust_callbacks(loop) returns once all the callbacks which + should be called immediately are executed, which is useful when the test + author needs to assert things which are not yet executed by the loop. + +Roadmap +------- + +I hope I will find time to develop and release the following features: + +- set of warnings against common mistakes +- proactor support + +Tests +----- + +asynctest is unit tested. You can run asynctest test suite with this command:: + +$ PYTHONPATH=. python -m unittest test + + diff --git a/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/RECORD b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/RECORD new file mode 100644 index 0000000..5951129 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/RECORD @@ -0,0 +1,19 @@ +asynctest-0.13.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +asynctest-0.13.0.dist-info/LICENSE.md,sha256=N92n5NWo9gBrsaAIM9pwlEFUXI5Ochqwc3mm7jjWU7k,566 +asynctest-0.13.0.dist-info/METADATA,sha256=7B8Egkv18tUVoTu8sa4AwxxhUFLs4PgPuckM5ajb9x0,5375 +asynctest-0.13.0.dist-info/RECORD,, +asynctest-0.13.0.dist-info/WHEEL,sha256=S8S5VL-stOTSZDYxHyf0KP7eds0J72qrK0Evu3TfyAY,92 +asynctest-0.13.0.dist-info/top_level.txt,sha256=nMxIbZ7H0Gsr_yqW6FR5IRtuBHrXjCmyeLx2HkmpDXM,10 +asynctest-0.13.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +asynctest/__init__.py,sha256=MgO982exy23YDu9vXL1yse3Q_FFtAk1MRxpkNUkk_tU,884 +asynctest/__pycache__/__init__.cpython-37.pyc,, +asynctest/__pycache__/_fail_on.cpython-37.pyc,, +asynctest/__pycache__/case.cpython-37.pyc,, +asynctest/__pycache__/helpers.cpython-37.pyc,, +asynctest/__pycache__/mock.cpython-37.pyc,, +asynctest/__pycache__/selector.cpython-37.pyc,, +asynctest/_fail_on.py,sha256=e4K7zHO02VnI2Gnc93eaRHX17U2GYh9IaLEh-dQxPV8,4265 +asynctest/case.py,sha256=o76pu70nSfdi2krBKPhAr-CJ6qq2TSvEVwMoI55CbME,17653 +asynctest/helpers.py,sha256=X5lxIN_Dad_KimV8eE2kZsSq5enVY5uW0-orY5szKmk,527 +asynctest/mock.py,sha256=FtWuAAMJqq6vtClKzijUBY0Hd7K9oMW5_qu_AKMQyhY,48928 +asynctest/selector.py,sha256=eWtnlnv06-R27_dpUyVVK6qOvmFKt_q9eD7LfmRz-zg,11692 diff --git a/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/WHEEL new file mode 100644 index 0000000..c57a597 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.4) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/top_level.txt new file mode 100644 index 0000000..efa007b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/top_level.txt @@ -0,0 +1 @@ +asynctest diff --git a/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/zip-safe b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest-0.13.0.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/.venv/lib/python3.7/site-packages/asynctest/__init__.py b/.venv/lib/python3.7/site-packages/asynctest/__init__.py new file mode 100644 index 0000000..d6364be --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest/__init__.py @@ -0,0 +1,30 @@ +# coding: utf-8 +# flake8: noqa +""" +The package asynctest is built on top of the standard :mod:`unittest` module +and cuts down boilerplate code when testing libraries for :mod:`asyncio`. + +asynctest imports the standard unittest package, overrides some of its features +and adds new ones. A test author can import asynctest in place of +:mod:`unittest` safely. + +It is divided in submodules, but they are all imported at the top level, +so :class:`asynctest.case.TestCase` is equivalent to :class:`asynctest.TestCase`. + +Currently, asynctest targets the "selector" model. Hence, some features will +not (yet) work with Windows' proactor. +""" + +import unittest +from unittest import * + +# Shadows unittest with our enhanced classes +from .case import * +from .mock import * + +# And load or own tools +from ._fail_on import * +from .helpers import * +from .selector import * + +__all__ = unittest.__all__ diff --git a/.venv/lib/python3.7/site-packages/asynctest/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/asynctest/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ab721a3cbe22fba8d7dd10c1c18ad205ea959c8 GIT binary patch literal 908 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 Ne#iL2`SSET{}0TnpyB`k literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/asynctest/__pycache__/helpers.cpython-37.pyc b/.venv/lib/python3.7/site-packages/asynctest/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7f418923b05b0b71ebd676395e43432f4e48476 GIT binary patch literal 732 zcma)4!HU#C5baJfJ7aVae_-f?pgBwi6+wcCEG+Cn_n?9>2a`5kv+1=bo$cUACL@23Rq%ZG0#*CRr{`;R{sWAYf?PVo?A zK?D_%q6-T2G!n5$K9P@f5sTz|HoAAR1#W7_6c0 z9f&*)oiDI!N0$i=w!P)pIhQU_|J!Tp2D~DI$>0B4_O3^~bLpCZRII=?MfE<+DRq9p zEgZgu);&Q|xd$q_yPZ``oByp>+=0QCE!U#shOfeq1p^Nq@_=T%h8Z0aFTrsZFZRkX z{V?A08AetCbQv|c8RRQ5BMd(u%-yP+ce0zw);i=kQ+My#llyn%eD_|Lvh6P9-DbD} z>xTE%l{<;9A)xioNUlz(8Dq?nVO*9%*JWw^{tZ`lQiuD%;nK0^YbFnIT~O#p9wFc* H(Iox_0zAt{ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/asynctest/__pycache__/mock.cpython-37.pyc b/.venv/lib/python3.7/site-packages/asynctest/__pycache__/mock.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9df5ba94737737cbe00f27813c1a4b10305431f0 GIT binary patch literal 39815 zcmeHw3vgW5dER~O8w(HwL5id(>WZR7Kq4WDdRT@jS`n1aCnz)nHP4je<&Yjk69XHcVn@*B; z+Qvzne&2uYYZo9T)y_;i6Oi}reVpfi{_~&zb^iOr=xD{j-}im&cP={M|)~cSl zFtSjsRbMbVyK{y&da0t8O@sejyH@>>(Xn1M-eF&bweeNypZv5Wn?s50xcfWh9 zyAQv&BmHgeex%>;-HP-M?r(P;+&i9w`#W%dhkF3`2hf89xVzImh`WQ*(mTC7+`B%R ztKEs`ce{u1{E&A*-W-%S`PxCenR2J`W?G)##TIzLE!np4AVNw zb5~mJ&IKp9=sD-R?L|*5FE#_uxpL9#I84WvO@FP^YImLG?iCL?Dy^>T%~UEU94VvK z>^SGWi_KR&By^fitE;*z$mbpAy}#_W+VgGCb=oKpwYc5Z%97U!nnAnUak}%B+16sy z_h%a)k!q5*&75UtW-7nWxjlET#h>^OlUq;oDO`94rnOPCTocpUa%~KBPESKj>w;Uv zeZegORON82eu7;&6L_i_bXD)sii1Bw2MzBy?dUn1id$*VMb+(eSN!DNjAUuC1^nYL zkCQlj(xtxHH|iigsL!06Hp5a}=(H8)d~b1H*+}(chRWmT>kr=-EG^%+++IG??)X7- zaq-CF(Fgqt4?obpFM&qpitwIUUJFb0dK=?duiwRLr7dRfmch==#A#Y467i3}Jfy8T zT=aD-r76><;v>1%rvh%na=qSU59)P-I<9K>rmCVu19g!Y{~~iS>slp1eGBGQ^Eo4D z1Qy8Weoa0#=?v^wF^U>$xiHu9Rs(@lIQm@BUDhK8gb62jn;AtsyGheoOuc?D8zGB^ zX_*ys%q*C_ExMo+&rKHz-%fMMtJlLyy}l%~3)j_p{qjn4F?v(1*MZ9Qx+ii2Q5kH z4yW(4Yv@78d2r@o%w!k8j~sTcAl0JZm0JCk<>jsl(2BP2w9uxw63?4;E(XD}KYQPO zSFT*aY-2$)U3K9;*L&r@WpCN%>B#*LAAR_~JKOHj2c^6ghC%)~I6QXX@bAG1g8{T( z2l4~yOKNXmUoftk>t?4E*nPPQa($T=Bp7)a@Y)2hu63!dVN(~_gvBRMoj&oc&zuW$ zoRAuOtgxC*BQpj>C&%3BES56g&j#s9P%=wq#VT371N94DP?v$Kv(TAii`^DrbR5JZ zn$gp_uqX-I-Ec?SPk<#0(nNBf|ot{p;mu2X=d<>x96lYCmEu9*Ah-4+js&WO8ZJuBBre&FN zI#>u_(NiG-VzkJhHS!lv_#ecbKaSG|V9+<;FwbD2c`8f9vBosj1wSlYy24+;eh-qT zm=G4PXjb4di(fOf$74HuuNdmG|7#rG1;rGYF}t~nu|cLBs=&t z*IRVvRd-3sh&wGjU_|(iICI_3NpK)UO%i+O_`s8R4Uhr`5+fngM=zqR$(kXLTbyD1 z<1ZIT0!o%H&NdDshR^ClDm#YZylPwnMeO7Lx((@y_-)OFSZ_Ptm3nQ z01K9>bGQlj)VBbcK^8~76EmeL7*^IxcCZOvG~d&&XJaE z8*Hs~!JIIA`?jcQGqV-<^aISR=?dAOzAV-3aofCVuiHf4zC90$@&i`idV|ZfHK#bo z(a#+FsYclhJ_!rm^9!7OTvjj{?bf2NZsXhid}{+dLs(nO3kW`e*Sh`IF0;31>-Hme z!qswk*Z~=)591;*Feqpw$l|z*Mg|s_taXb^Sdhb9d8PKom?wsCy>5%(Zdp0R}b=Hd#SytJCx|(1tA|;#4WNekIzbI`c@&Q_qyH}4eisgZ5+}p1nmG$g zCpgHQHEHs$ch}a?9O?wRC&M^~Qq(q{IG}=DVHMpC+AYm+S<0E!Ts5!wbbx@8(w}59G629n=tcHK^D1IBKok?oPdW(h7Ss~c zZELw;yDa3{Oh3%xWkoU7lekWhDPFy#eqt&JIFLtG1G596jjJi=gKI%E!Zz7+r_~ck z2G%%t9*YYAk*!Cu94s`%&oD2n(Gb=HiF~j%*-Srz#CitUJqTF-gI3_8`^GLsau#vR@@@^ zHIl2aK!LvFYG4#1s>ae&f}qZ@z#Nkg0Z2WKH$REPr^I5IyR95hdfXhd9NoT!~{y}7#;{QQCywXV>pGoH18`?Pi9=wQK^k4Yhrt~-BGj5 z%8^p}{C8ME%Cl5QLf&Ze46Ix-#THi=;kh2YHJzVb3QZ zr-IMG9VJ$B9N>?Mp)Dqh|2RPW^U2o6JV(l|)@iL>lXvMQ6R#AEHV z;Xy{E>|0M_M6a6u@j#|UkXy*R_9rpMF2=ZC=-bzdK`AKrq51r@P2>+MSS&`sqv|!B zRTt(Gq#`-s+$CA}iPU}LrE$uweaNj>t>>YlxNOOcq5ec2L<*=*teN}6GS_Qa0z||? zH&ROd_42U`9t8Mhb^Nzju&$*yHPB(K(!xTdVos8YBu^$MD2Ec%v1Kj@yh#nI^TIe+ zLmRApiXR#ms9*?7Cy_*$ky5K$pI>Z}4_{e!AtbXX_*eQFNc@Ou$o;o)oHXE@)B25t|DMUI5S!?#o;e!vZy*ZPy5h9U9!|< z-?)aQf&|%+Y@HB04>bk8@K(PPg)n%e3cbOla}{vX7b19kK^#~ z$0=SfZmv7W^f6!(tALP?gxgL~g|69Xt|HCP04YSuJK?%ctXC7wArlU16k&mg_5BGa z-k^$3N{C-=#m~bOplfLbP{J;*9fnH&5GR0t5ma;0^P$J+5w&ma|#XYt|&*A8P8`W&XxA!qO-8#2e4f@-YQh5i)+Zz4DixV%9w?a zJ==&YYfv*urS38m4amo$&aVWbQ59|@*0Ih|or_+jwm*giz>^StS+8@KJucI)Zrk&3Uh`CGbU5p~Y}L=`-AtP)j+< ztSKU80nJQiIKOnF&FYO~+%U)kK7xG|PXMzG`0Q;&1j${V>ycrbZw^vQ%GxZ&$f&+aM`S(Jc zFL99x$_tfiBV>`UgYF@B=Y>QD7}YS-(w+}~VssF8&!F8P!$ci0JEGC-;*n-t*|V?+ zU5>~AHUJ+MWBPcAsYqpN6&dkoRd;m_^n)W@t3oy8gP)*q?AJz>x73BIPv3@lSRd4y zFsmsipvl(~GLLW|H2KO|O7rfcQVmdFBqhbBMytt<5$hEsg4rq7<^Zj38*cqTsmWSLC=x5#aR0M7 z1;z$#F2E~d4REXE?*qeY18=?$m}2rbfD{Q;7FI(4W$H#Yz((U8pHgbHGP8%W~<@2=-CCzJeKO938h!(1r$AzcQ*HKb&DSYst;H5lD6uUo)D zsU-qpZcY)ES~%p7D*^jMZEd7h-T=GQHz4ssxeRJ=&Iv+5+D_C=;KfU^j!|$cvoLe% zzL(Ht$%fgxXBf7b1vurwMTDOoQ^b5l?k^qa+IC9uu`WesjtZE9!b5FDm>WHlYCG#% zUxcMZ2omTn&^nfH*vfkkpNm8T~6h>UJ3j(FM<5&2Aqpv3fvmRggKq$053nS-o3t()GFN(l9GN&I*WMg2swys#}>7#*{j;(SL$NlsTnJ z&MxIkJ4!j}OftB5FESl}ea^Chr9LkLA~@*R%C(#bhY4Ztoi9kiH5CQ&w?@*^6JMO$AJ4|OM8Zyx>-u9za5Fad$rZDU~vTkkv2PaKxo z;!b7!AQFk`tN<9Pb?eCcLrdy4VM)~s{uY^a9_`2h!@v?vARG@ibFc}SQIVDmjm$aZ zrYzw!SD3qNVy)XmF@@HvXqAY+GO~Z4@ zr8t*0t)gN+ENDW9m2ZYGgocP&rcfbBvt6V5AOtiUQ~C4?*j#^!?t(1sko-#G+#hsZ9b8R)<0F_oeDrVnT{2C@Nd5eD?O z?109-{$`CTA^zdG!ctB~mCptS67P-2aR~1*usqSR%@z%7^BJtYGIBRxjP#5LO@h3p zX{4q$&1CV)4Dt|JjmXUqMcp!ImatH2r0f+*a`b6wW>*1e^}tFHS2UouiRj8{5Z0K{ znbnKR@#Dv}9O|6zcD1lNGcyCp&T$@(*Rh09Np10KP%=oG-6{H;O%LW|ZivVlI!M1M z-}$DxX+FuorqN3W8(12-4d`yIC=g?5vfl)YgJni#a6^s_%v|tWW zT;5-U{vkPDLD zUc>}A4r4{7(1p)O93Y&7)JqaF4r3JkkfqP56FS3A1du<@Gd6drZ44IVq<=S3)%-odvq zVfx(_MGju_Q#BMd`9ql0Y)hvbWPm|GvwB_F@2v&}9FTaEIPIn7MUNiYC|ckI-#?xA z@C|5y7L*p-mpmv!(LR4=e!ksmqll zwV)ukJz7S$i*pwgJ+*?|PlyXT?~8IzTND(GwUXS)P7vIc-Ksl^GAizvyA8i1?l@SW z9nhbi;82`;1+Yy#7D$bFoWvo#6C?=nImbEip|;@DLM(=RG2o)r!;#m7b~i`~p77!1 z`G1^UXBQ2aCwh~ax)Z)oTYy+Q|3KN~xD&r(e@^Yr>(H`lE6^!ykP#=vT<@0zzc{=v zpjXo9CHH%IKuCR<%4DL3t6#q<&eNdm>nH>NDQ{s`Cq?auQ zd{@Wn8mm9)5TriJQzUN50}gYTW7>a^jB~ka_r`~-Nf2#dc<)Ab_HMyU)Rpl6pt=$R z4L6zVW;)Q#*HA+O))!D^vSgFm>fy```nPsSOt99&p>MXqCPw0yz>QNqLV?4YzFmYC z0JIaB5RYXSda9(trLKaC!EO7>yUL7EDskQWXiD-ILcn%6j3>xf~aHBP;NkneM^e0>LYj_BdH~KN-#%Ag;0r)BE_#}P;_b-ci>>L z8l<}244&GmkIcH%kFlc22sDJO*?I+I%Yxl3_6w|-&y3L$%n!YtTUMT6F9{hHE<&81 z#Kne5^VYi6I}AT2^SS|iHJ`#19#Fo+K@r#t^N@avtrIYX(GKwc4%Kt0y3AmEgg!~iS?5HeVbEF!<+VJN=4)(^-F!*V63iW-RdN#(N3k8D zaQHW4eFQ0_6P*Y4KzNFjh;1%`!V(mfa2`(D7VXQ3G;o>`87^q91>h!s1LTkxwt(d> zB8M6UgeX~>Kyi>Vgs@UiYX0{(MKe&l6wA^~@QNK1t3a~mVfRAo@=9BIibxk06->p@ zK*mb{kMbd$ZK4%Yy%x6zYbD=hRR7HXTWnMn7e={cSz-knw+2^AL02>{StAG#;vu2r z)4x<3QrFGi-o6>(A-wpZ@-wel#55WUaUElw_U}i7zY}@YU%@G?fYWQwuhpTJQXj{I zcwygQ3Yo3Rl!c3$PW&I)bS_Z_c7CAg^qSa_ok3B$q}@oLvKcgYkov>HqogJSX(^cw zKEvQz%?n7LAm>SL4~mp*32dqCrs;CcbFnOgZO0b2rFIWAi;^5H4Hv|0zXHE~*^ii% zb_HATE;x(b?s8@louG`Wz#Xhbn~{L%vd)WkIMXkz5*Q8e3>bLWQ-{j-R=pNBD?)c8 zbVfkcSJV$DcT_SASpt%#8F>CxQU;60*K^{dArq1*+Hcmi`DjHkcKlT4CN@G6}LDJ;GnFX*r0Pv8RE zprDzoj^fxcwsWjf+M)QK^ECOhqbvW1aFH_nn%TcraKZLy#va#LG&Ea}Yq+D;%4G3z z4UgbjML1)<(_=)g#VM^;jW&aiMgqWCBmiKWx4RvJz_>f%?!fPMY~beBZnHKKZSCG6 zrEq(9sWvGlyqy@9ed6ZYd=z6XSTw9P%}8T{RA(uYX^Tp%cgb4r1oNbz<`y=QXgYG) zhz0aa`2(yJWMM6B4w>bM-LV|1b&^>7x)(a23$l8(HW^~HT8Q~Hi%%gNjRPsvt6h>K zqeT_M@R&2uqA9IIq$X3O$aZ%tqu>;?>Xcl?1r#^PB1xh6lr)l9OS1$|+Ei^toSJTk zbu$Z9z03=I#55(KSqX%Lh_nKbN!oA=_2%b6%20xs8V7X_QLm5CV{kY*$WOXqQ;S9k zw6ts$E$}IHr85p;Eas5dGN=_QH>{)sH>qep-qzJ{OCBj(RD7CR9^9ndSaq^>v9kG8 zC?@&EsBmF>bPr%~jZ`m(or~Da4h;l6ytHej55n)!+Ks+O!$m^Bda()5FDzM6X^qCf zeq=q2dW#`6DN7LJAjQEu?WP@}q9(F7zEwx0^-Y2tdXhOn1h_)K?P(j$bZGYmv2qiNZGn+o^)h%a9hMHstW4Y2JrC6|t>mf6nsR$W z9b}I4b)*DHEy@XvfQ|qb4`+(1A;LIQEyk2Pll8)$R63m@VSj1j)+`1%X7aF}E3#Tx z(L%6nE8Uh}*Qu>ccm*4)Badx3e43oKahs-X8ndxK1TJ^7yHDKfSs4{vQTe;4P(8MzjD&&3TSvj86u^ZBYBHybf9v)~>=zA$Teu&klu*h>RLaCnQzNboUCmyXk)f>oacdr9 zN!<^2`d}B%RlRGgg(fF|bmym&mVXYX-agq>4PHs@+OQy4%ckWGSb5p74HJQGuo3KC zkT&WTCC0jq3Uk-;+<0xWazO~4PXuuhIp);2pll4GgP(Au?F&{=udbC0Z{V@|6i;V) z`Xo=nB9a}%W|(}POat_zf*B+nVL=oAj6j+PkH5P1JO`BS3J>lpRkXcW~Ybpd*q^lE+;dSxX zkRbKX3r$abFQ5E%oWM_0-~`%!Hy=sL@8K13P5lj=o?_3q3&+6T5qhr`a9GxUoE@uR z?HcXvzEKYo#O1_CFE$&iZtJA zMoXLHobVyfF(3ofvRq^cNti0Jc4%spsB2+pZ)MdfTUrv1CgqAm(Yy21D%_r^5;=62 ze~99z@L1f@R)8Kguhc1{E$RINogyzm;B+);^7z!?C6Z9 zNuKKw$Q*5>kOTTyM4WwtU>(emfR?CA@O}V?PXq#J;cluy>)!*=+6(6LZqQLYo40mh ziy{D=%K%v0R4JRjC4ghs_IC(h&cfd8Tf&buJ#idKC9?CR4fP5mvL;O{hu z*;=^$0lrT~J0fzpV-R|EcHr_b%&~L(j+?<;awUK#8Rzf{F{XsuH(s|ktVjVewE+bp zDb;lgKHu=$SvLUu0Lx|G)g;zlrWu9~rd>$S~Y%Yux>M~nI{lWP|H$NSC33NgtF2!yDM25GR zG;_WE$$-lAn04;*D|2M2^zbFbo=Y$RwF8HCBDSu<0wSOR(9n3=L2CPGpMVRZCbskN z0f3We9Yz%&raF)*4lAZrvan_}88XCUby2y*IW{=Dtd=ggy?5VqTnUks8V{BO^2uca zo1(JK6YA=>FCZcYS}E8FH+^|3UX*CcLFOta6nVNhgsfo+dl7};sOwBx&|01_--0;d z2?B5K?v}{R=C8B6lPE_MkSY|9<2h*X;CuX*XwCcyS`W~ZM^N6|rzfB=2qqN8D9H6b zc0+{RM7XnbMXa{p92}M9zxQB*r!iq4vI@=IfZ{-*N;;ns9QC8PeFs!$_ZC#A&aQno zM@!hhh}=(LoO*ZP6iG?4By%!U0~F|G8LHPYv95`~sHP^VwG}~zOm5Q!D+o{0OGQ-! z4MA`TY@0qNRK;EgH>JaBfMyi}#31PxNU{2P&=@N8^1YSKLmDl^w6{@MhAuT-FSXX_ z8zwbLhXFN-4I-3e7j7;9J6{@G2cc!BubbaxT?W&j=Z>jCcErHfzp66yWUl< zr$hsI8lLo?GsS5X>20Q&RmV!y`JE;1Jv<*P%itR$s;Z#fT%2*xEEqTF{R6rOrI*sW zP(L<%pe4f9g;Zs3YEo381WH60Id(@jI3`t~x;5Q!fYD*JiY6Ug zZv?`OW#=telWzjOP=60-zlma~zmKOsmmw7oZaJku3pJ_mx1<#V&Es5t5Jx7?K}^hs z;~Zqj*$tZaZ7AsHnUK|>sH+@3JJ0)W?m3aLGho>qh#1_TN-u}Ck)}dke zgyM1ZG!Z1aPgjKp(p2vdnx?&q-sF`C-6Voxj!7w2bH8C&d7eT3M1&HV9D$rx;CluU zo}7LSyb)$xt(;5{O)`aARz%>H#v@EZm+meg!nNEbJl{+?w?~vS1;$ShaEDQgF_r_* zG-2*D5rq+?(*haIVeeK6@e?STG1vy5@TzzFTVOyk*d(qzPU48=v{(eT73DODz#^wX zEEYL!SP=eDGINF*{DhzC$Pz3=K;Ne%!&^)kEdake9_K^=rh;^{5PSn}DHe-Ub}1_a z3;Qm^pijccPDF#i(TW=V+Z=_gAPnwx&?+;tInyQ}i%j+qAe~i@X(c088KVy66wWyS z-Kb;NVVgG)%|IE1oy`P4%r!|K0q0zz&q))B@ldOo zgs~L;(-t!WfRi;ok#!<1O$s{oQ|R1R6Ig-MXBZd;Egi(iwC-v1^z^P_Ybh00sT#93 zS%>u<4pFp$!($?fb0BK5w7oKQi_A#vkorNMuJJ_XSp67JR86YS^7IdRVq0$(MdTRX zm)V#7xG3F~%OgS+B$ujH9j)G0s^Z_y(r9VCa;Q`l+hvO~3jZc?kWrDqmH!zfaG$Ua z^al?F9cKu^#}H%;Y%W>aYuK(0W~9jBZ=36-zNwBA33%P9_MvTt@50k<18+*I)<>)c zFu^4kI_G`~8*(LZQ&3tj2W2oDC`qj{ZRhcRQN4lG8^MSRM&nfzafr&Dd!#j^Oy^$< z#_(h}7?RH;-RI@aHhJ@TzCr2ZZn2*O;|)#idIj5s*^)22C0v)W0SwxkKH?g=w5_@BTVd*QY|^!5D$o_i z$Ba%N(A+)%VN1DqYvL(kaFA{37p~ju6a9&P-rYv41h8uxTCC$x?daryDLeW*FnZgO zcC5eM9mnY9W%M$2NvrmuCFA`Gcl#%8kf~gMJZY<`enG}#tUu08-Gl`g+YyLk6V309 z8CdbA@tnxNC9;QUH<>1gD;U7oNG9%HWbPpJ#(PW=6GAhSBxFLx#DEsNmbAL?i1e4~ zLqeaII9HrWHj748qI6W&R-#&p)*qOdQC$P!E;I+4wYVk5Vl-WE0Rl4`l_e?w)U6|h zOS9tS5Vi0>Zb;0Vl5>vh8Z;;-TQs$205%av0R+)1q~tQ!Xb79leF0kGJPV8SY~zD) z%7qG27!paV?YL3bZnCWEotPg6ahf{^`x8NcC=SU+_1;av8f`u&rb1rUdl7lm3n@swpLqu_(I`?eCC!9g7^tMm+ES~7ypj5;`4fQrC_D-biS@2Y_ z5uH40D6Ao(=`KbE*UELcaA5~CHjwFhbuCig=U5f?XVQy#zOBFv-j!KrO5C$gzE8)j zILH=?IfG^f9dPF{UO700<82=SvYM{vw^Vx>F{#69c2s0VKwHQeid}@82oW7QZg%n_ zw3oZfwb9d2G-`(7@@r!f2_RMEoo2OS+#6c;Qm!>%l4n@Scoa||&Ay7q;kKc{Q-r4C z8ii(};}TON980F3AXlwYe-1eE9KtAhxTZW;C-9~xQ%q9-hz0#)o<7eLm&;laC2~7l zxIMcwzRsxv$37k8x0Zju1elYdq28ocjbkSft3tD>R#@N_o*v?$QV2pL*f5tB zbTm7pu`0#A)&%wyR}hbs;hQGFY-^UA&q^qx#9hbuWjPFPro${S$eFgMGWUcfZB##v z<|SUgXt3y`g%dx38?5`@|XEN31q!j;75^Grmff&NGzGWD_#+DC*+ z6_8}EGH_&CS`OCYs?V=&?vNB3scy6b#ax&p8bCRDAMj6RIMm8Q^L~*J5}5!y+%cB* zD6vf4a?;-+aY}s=Sufd`juftpF-{wKmMHcpRPYeYpTh-0%@_#B_H-W{5qyr}@y@8P zG+0qJ9ONWa?@@`Fhd{kz%7Umw-*@#S;yD`iN~Zwj8h*u&6MKAC)eaOMRv9`zi3CF` zACAZ>uR|)R$N2>DF`2Bc^j7tD+SXhKo{W2bE!bPbdm5{>8 zx{jRk!D^;%ri2p-9X=e&T z#g9rLLj*U3O|j4~(0ZsogL=ypTaYHVf%66;M$}D-2ZVM}%L?LFL}=7FsJVZ-g)Ye- zrEp4Dx8v}+RUhhD3kSYV02?wwQ>^FTG%Vn{+r8WWH-;3uJn2$GL2vdlq9R*?4a1`6=Fg~8;toq$08 zReI6DFNW?btNVgo^s+%u#|fi_Tl)DoL}sB>gUb6-cUpQvB*yyg0Z#qRm$q7G>fPlK4&>d?1MW|yfWlT^pZ z3cC1`1Xh=DdtIi0hc66u^e1pKoZ0s?>)ou`_SbwGFk9fW=DT4@QSpSuiLTuG>m*Qr zBB5G&Rhu6lV=?k`{D`{)D$rBw-nrjDGLs>KG(tGtgtaVCig`K)K9>0xImH~W0 zO2Zr%Wc4ddEu?@{Fx;kVbL;akui|?qKS2WU1l}0JkmSISkm+E^?)V=fHi0?OcUrG9 zW>xW)tjoALY16l-3h$oY!%&w%Kmo^w-FuOol2EHu^*hvpWPXtkArW~m4s92YurPLi z+A_G7slI~rnI3MB%clxgK3eou_K~FAVZj`vAK`I_n4$9;=K9XcH z50pWYFCdM4pFw}<;SSy&zzLGazrjyUXnH($HFB*5RMO%S&OiS0IElmmAWnLhFH}X?<%=cUgbN;`&*6>> zI^6N1JH(sAGlXb{{|QJSEp)iYE`)*mqL8J+oYomqquQbX$v@&2D}D}#ggFyC?1Xmd zLSQ?DUhfasVlDNnNUDAvr^Fx|?QTt`su)+k&S7Eku*1%5B1MTuWIDN08|*jSx?f9M zr+$~s9b_n^eSey^4>pN^%~Yp(qCA)aN@h$ro+ZPO-2HI-FzNCkITMh&BthK^ydA2U zEXRLi&11OW&g(eh_c(Tl-55#GF=>!bu(U4yIr~k1OHWjUCAw#e9&Z9Hzu(fjlt6$eMJNaa zSpOHse)EP@a`Raj0)>VOS1nQL68 znXq0TVUt)Q)`~4rNhcd<0GUE*z>~OGbM$7#PmO^Q6aLo);}oL}INbeUploos2;s$l zNDZ_yjhI1-ft*+W38l$I;8*bQ;R4|{{s0ee+z0OAsMp8Xhbj`%L$!hk%41LvY~353 zA>rlOarTC&;X62`eSv2KH?4!0kNXn0)YdKK;-UTsrx+35$Lmer-b`@|8;C=2xVLNb zsI$Lw19Uxs@j>K@S~U?vm`+v@!oZvkPR^)hBug-yA|lC^h`xk2ST%`U8J1!HZ+YiA zWrwKDe?_)i2U>c|=9WsSTVn$O(t~=RTc|%(joX@%5Kbt(-Lz>n9rt`|u?yF?8;`mA z@2KN;woy|A4)>&m?;1W!xh=!A&PYiE?M$W(F-5mB4IOLVq*98gu#45}ce7%dD|TUizl~2d_@>l#EV{Q)Fs{0r(@JtKOby zmqtoO#P+mH0vH3kaE89|1Fk&xqo#D(sV4$I1byQ6^D>R z2A)@_Pf2pUxVj6^%2?(#&?{VhEr zpy*4~S+I-1guzcC>TttY%JJ@vi~N&!Nb}|kHJ=qIvGV6pYsCJ5Z%O(F+DC2)OdBRDS>SFc%&D|S%@tX4avYDC#(g>BR+g`ji5Au9PHQF-olYk`?D-YA6AAK z1#OWs^=_c;sfr;oaK+9c6nW#1HM*O-lS6kdvO9XEq>2OK9Ck;I-dt*Bc*UZyrh~1f$BK~mgu4)(Yl|Ykt1ssIh-14q8`(} z9DTb1-jt%f!M)yCE#rxhDllD0aeDTr<_x_}SO;;zCR$oJ8VzWu8!#T+w|-39 zEq7QTE|q+UF*2Trc|B_(YBY3RC@I<6Dy@-r(9E#ByofJk&p1yEZQf1VsKZ|AE<`36 z*d}5tXl&zn>rMFB>x@`TtTNrse;6>6mb^XVPy~cCQ87_R89$B|l*j@z=uIW zQ9^AP-8Nf5mu#pgcpFeXn;Cu`_a@q4?>P5h_cUT_2HEgYT4meNF{hJ#*j|SQFF`%s zTzrK+XfGzH=-_Xli$uOe>Bx{gZ6DunaHgUy+-$qJDrgH;ye)A0aO@MfRnsCZbJR8g z3XoqTRtkm~L1lzCwJU8C0Ds=2!-5W=!jLZ9be)B$6xEJ*;XBS++grqEPMT3jAtqnu zW*B~3og3}rKrB;YVQe%cy$84_~)R2yr?aGK(wS0kRbOJa#H) z^6QBr8wBEIiqtJB0IpAvS{SX9TN%(R>?B|a4kl_e9@kjPXepT-0DoI=h-9kBIyIP8 zfXELtV1ZCTnikrmS9R>RkU~LsB2NMVyMBgYiadzmK?g8Itw?YrhDx?QX=F($h*@M$ zCgNDNhWfy1jn9~i8VPbqzPTZJ*>90XDJaLa6NKrI`+HjHwvPm{|Nh;-p zAQ9n=($kV2U^?oe7-$$O>w%&BqeC>~ozn}67t7A3AJEd@7}0%&KaIx1tz7aR(ZdOh z0Q+%6EEW=&bdlXm|C%XoX$Ou-%7@d&A@HuUu_5}{Oe8Xr2^OCM?1B&hMPw6-+v?AF z5|Kuv5fQVgGSIR%1y3ci&KB}?n3wJ@Cw%>haY)o~^WdkjTGScxZv+QPnD_RkZ1d~Vp( z6{|9VM+F`KsJ0r#A;9|zF8CRzt0t^kCAC*vEMQ23iv|3}<<8c3{i1&q+q`98Jw%rx zmE3U6DEG^5evbi>rUH-cJVY3HU&lhthS7$nf?ELit9V|m7gkRrJq&N(Y3(tfuz2Jx z^Nk|kD88^-^NJvvv1?xhjs)B3dV$jB(o)ibP zZfc+z?-1jpvR}$n_Sji&h+~9kIL^gUeBn>#IhVY(D_BAjiA{4pGOcFfrpX452qR?= zaf|KYAAeDe2GJNUs6T{ugCC})FiIPYAg`#`Pz3Q2KQhVF2~v!Flfq1sod`$cMx^kG z62qh7L6ipH3)tj;0$1wCd7FoO-IA}Tjc7qc0d-bVE;W~@x9M5*c1aIomumVWQ;zND zx8b1e5*T5)N0@?rL06?;GW%toMS9m{jQ=S)0 z{4H#{bb^p=L*WCMKxp$%zB(N1uVL7>JbNA=E}nYH>ZjMcS0#MAAQCQ=&P(f1nYYe32667$MA3q&Zv)SD&YPOpLKlQ*B8S300Yd+70Z5 z92^cSAfGT>z|XEC+TKJtkMHZrhkNM>7if)pP1wLgTSwX{*bElp=SAX_{r%s=FQT;o#OQQz|NNp!(ZQYQO4yF^Zew)+ZHr=o)#!c@9u;^Wy!E`P)%BDSE$mvA9d%-}~l=~IZ|Kfv#c zb0^mVd=)qe*T#9RBZAdSFge3QB3r{3waFQ)tWhtm!ZazK4zTv~st-?B{9+H-G2`;H zFGT)&cv4Xx5xq86NfQyanD!cV+_Ji&^oOF-zo<)>a!0in0aHcgqI{J5qj9+raX5#s z7?K)j@CshRQkrr2RTbV+>NwL|EGOmn?cf_NEC*U-l5HiTw^!8u@^ z@1PJkk6>@zIAT=6dETZ++g{M&3hv=x4;l?qY6jOb*U9)0f5~Xd`2035^!T9X@S%X` z&)n)UT-$)hQQEk0jbIc0EPo@&015ZdoI}qOxyCP05YXEF0=$g*l#pkR3$S6VI=CvL zyj?o3k-7*!PWT`%z^xUAoQp3Qt8;W>dg=6fPB6iS_b3R41PR!{SXJPB@GH?+?G=Ah zdMagFgPK3fak{*LumKy9-vj2VXw5$p(5!f&>iH#JPK6pYKgp41a!w#M1n;9qt zttTI=#&{xEEACf%RU+Ni^P1CC6S-S?b%HO1MDY~QYLaV7^tE_Gm#oPmtj?8crF5&j z33C((6LQ2^jPhhD_jloB51A*3f62e z)5HAiO%lTy+BB`~#3QYfPXl3gJKQe;Nm_IZog^V7XYPfQgpt5Fq_!BUQYV!NpkyAQ zb!apsH^h6pI>Hm*? z#;sSJ#~kXerZOOTOanmTQcaydz&#KLqUf>%S))LT!AO37F=%sqM@MWE0doXnRs&)VFi7SBo=L=77pfhHf@eF9XxgXTF?6 zbcqx|QDiyB*x>4vY^9I3*Ko|^Li7kwc?WdhM=1Q2^HJ~($$JyE#6tqTN%d4dE!jRp1P>L z0&QRI<-^H(25%9g3!e#fedY7j2weoDFHNg`Eapz0WSJBOWSX~6^7Ir>PxJIVPcQJ~ z^0dg)yLlq-BcI{Y+iAX?x5s$;Ii9|VQ)r)<`%qYd&lUE$dyBGHMQ{Jeogzg3ITH%G z7Zd1Laa$WXiQd1U7^FmrkByeMsCE(cfygbIj>@9&5bMd|gDpW=iUm3VM$>A#_@T?S zVsxQ)q8Rvo@LBcQXxlyKx{PiH8-y@(@S$PRdhX*QqkK0WAwC7ztAT$73+n}VNqcMu z-WDKZ-AXyDlpD87xzc#4IDQbnW%v;78s9#C%h)M6CEf;}b9DDzIPV*KY5Y6jF=RqH uGztHByR@BK_X>9D#mVioP%@uUB2Jt;KS+Zs)6gT{^Va*e|Oz5{*!;CR|SQexWkcY7{X{7!W34|Y?)7L zs${jSheqGA4ZpBamESQ9{!=aXCfZEnr$*oUT-Ov^#pJD0tAw{MCU130JSo1h)SdQcQFmI*i8FY6PMj6z@Ows_7Z>n*7X2=YOXzpW zx7N?0=Xr5iynvPq{zcyuSN5!5oARo7QCvmcrM|=3^~>TVRsXJVlKP5xS(n5$@d|pr zAYK)(;rEJoU3>$-FN%48YW=Ecyl40?`7iF7_-o2_P`;9sUl!J~(fFqK1T3ijcp$cV zzSC}pe$Vej1KDm@uOGgu=-AnC23==yb08M8-eKGE`oif9HiupmtYDIWHkL7gN z3(odh&{?Z?yuK3#n_E3E@||eScUJs0?@=(2+`H$bRB{G=)tX=Ef`eYz^R_32<8`7f zuUFk3$PI4DbENO}ve%o{FR2krUxEcj!;Ec?gWrnV^@5%|=y%whUWKF(E}-BWEmIgR zOPH;Kuv+%7jIIfxwx3p7MNt$bh(PIAhHbRUU~)OG-vzmD`(Z~0LvYvo3o_lob;}92 zRuoaVv!EYo0yti;H`rE808{!=(0!sd`Y4dxkVEQU2e*>(6jjuCM-Z4(Q*7GcIH$Y^ z={d}X$py|g+71~u*owf%)vZmeVZjL?P>;OcmXEex4?I!hkv+PWaw)vX1AixnYxe!e zk=qsN5+1JkeMoE~TMneK1I9$YSa{w5>>K(KnTdJT{AtP zn@u&0q!4uY;AJQG41U8O;xRJA%Ofki92tAYGjn7_)_P&z+AZ|YvSuAMU2|mq)*4xV zZtfN$o9)89V2spr&x$O!Fe*S8tR-n-yhbrDhFeh2xa_)pf7^9s5!G=yAyr)1^d2|t zxX|f^u?-%CacKiGjbAf_j83_(VxsH*o$=q_eIwc&zA+4j*Moi-L3Xb9-uia9`p%od z8=0czN~!uZhfib~lQwaO%37EebIv+zows(*AK+lJ$c#WF6p8c^->u^j!5ok<`{tgh zwz+f0bteaLf4(J-H`o0R$0xyz!p?=s;hJfm zMuq+R-lp%man*G-q@i4M-7lanNec)q1|1NZ=1*;0o<%91PDt7Ddp)#fD`}XL8a$^+oU=awaI_sxAd`N;v@r5Lk$}(AKmocJIYC#U7?!El({puliJ?S^=G;PN!M_JWPnio&2A-}(8B z(eSbag|7yo($9X!*UDbfM2n~HJns0zC>ZqP>Ud+&jdH@tu}~^$jIFNtAQeVq+A`0Z zbyL2CnxlpBEehksR2YY`(!mm0RbjAbgq$QMwG>$jpv1}j^U76p)_fC&$h z0z@T|XuAIZZ)qGWT4og_sax_I>N>cytB{n!c@*+yT$yl76kx(_VT&S6cu|?~5=c>s zD_l24XXi_`ViqA|ocnrCSQ0tE<)q!m(hYbCR$)lBU!@!!hmMZ&PLz9;_l02M)I6CR z1h30~gx5nyY)LwFbf3axzGlS2AfL z(ReF!cm;*T=$SNkCXC@8z-_(Y+5+&_Fd^)+gkFT@pdUnuano$AX=rd2UNs8x3_8kF zeAMtrL06%$Lf%(V8{iIUZVd2r=X6S2SO7izp@rV(3mh+kZSERere2sOxsTW;`wmTh zP_|~=RX=h&Ye7%IsB|{^990=3Yv9k4tg-(eh2=22CSt%BpDzm89KfMRz6@c>JRy9d(T(OiS?kgvY5DzhgVa;)Rd=oD zN{c*^!>}aO87&%xFzm%s8A-mnh>SHsqVkzKP6B0?;-hh%^p}XWTBV0F0~K8w@tKhH#?0!i@&*hX15B<03cE@x##7 z<_Fk*6%)rc`VQlws)T+fA-wWJa(g3$$FtO2{kn@lPdxbzmruknAo^9SYRd1T+)>bq z0)I(nwM*hC_5x>RgkKeR*~~@(&n@qF=&HnPxwGc0L`DbU&x+UCpbNSh!1t68a^wlx zZLSyIix;L2OuA;ei$OO)zi7>i)Nl-AmFvmXGTL16nL9{EN~o3j*Nea;Z!`60wFOQC zOn67f_=uDl#G!BinDfZuS!!JVQUvB&HVNCA8?2|~o))tSl#>+)? zy$E&;UIPPU%}7k0X=XNI&XGXTd z6ntB43vON@dqSNu zIXa|46s$yN$=&}81v9o*SPL%}QT;W6PTp3b?3I(NyOC3BZ^s--L{PnFZyHN}*uqNOa(sFqWrhL#G_ z>eHhB)NDGbt-Z`x%@WzL6TK;$0Xj-f!)7xNF}ET*mut5$&$HK6YJm_)H-w& zIzqNl&cZcNSx3g9aC+eA=wQ!Q;lFlCRJ1^kDP0tun8S-=kAKIl-8|$&E7s1H$z@IY zN}W{8=$i3XtNS4e$hTls;T$4kQwo#)Z3N#|ir6h^N9KJx5Btu=yd7VL5TT;GF0&ljIf$M2xG2k$RCN zN78Qc9o8{@2j5yLjB>C`+D(gXI-_v`zW8Bry@i+l1Gma`7_~X1?`JKf4XgvYluniD z5~Vb~!yn;~L(=M`(zkWpj3h*0A$fBEwIpKE=1PX-=kjb=*hH%{`{}B3&%S+51rt1`Jir`C`>-E8qZb2Vs-0H|XqwHZo&kgi^z0wStptYq;J92Ic?GkGmm!n|Q z$8qt2_(c8y+jdAmssU1(I5*pwB$^&4%iyA~ivJ7v4X@#m5N%4HW$Bqow?jdbD(O7H z&Tli~ebgJkM>|Hi#*GKb1mdL@Z^0RBF%RNZ(3rY|N}re-J<$MkxQGd=6*Sd~szu>H zK!#X<7;EmK_IjRVK$*D-Ia7l$&7S?Q9hsGU6(eaCxWy7dOj4p1S0v{-DH(ke?f-;3 zWDch?ZJTwwR;r(`&DJkgrzKl6rjc1TZYAlTqp)i1nvbsn#f*K$vfIWV)nPZxXRsYi zLwzy#kc=$|V`EBw^4MYd*uEb;G$Np(I#=e|LR@CXebXDpC3T2^qjBak`$E&WfEWpo zPN%a~S9uR#B)Kd3d#F4hqVYM7mV#N<^?T$1&wmZmHi`FD>nsnHmQWMd_35>{=J#-f zA7*r*@Dl449kizm|IXs>aN~4jpPvBeJtWB*d7lH$GP{8Da5qg~Aw8EBi!RUoasE|W zgICq_4{Sj4-0MeNE?Ho}kybUW3+b4A+r^u%{(#_XtX6)4fi+@sGWjVV%XmO~AF!+} z<=9-Z)BW*^>gL3pnWPX@nfM)3XrKNA>GO4Fe83qAy2f}u{>en6;>aJOK*KoM^T*XmmlB(z@-q!Q>l1_2Z)dF84_7i z{^RE)3N;vVY}F9ZoKK$eGt^D+g{x6?(tN?*L8CoJc+gYL7hB1{&P36ZjW4@EQe@_` zFgFuh3arh5`QZAlCtp{&D?U?dZiI8p<43`FgsEU#ru=Ds&D69^+gkX8+}bsnC|<|s zH+%3@g}I8)aUMJPAO{}m$h>ImSqh7gCVy5M*$Rv1fiL9|`U`8rmY)H&Dx&ag3NhL^ zWo|F+yc-TS{WN!);7WED3ulJ=2%T*toEhmLeApZ?W2rv(*|Dq6b*E9453$UHG{mPq zL&c4_gzuz)V{riyOUovmVtaiM^q~(#)mA-N?So_~oVBJC;wOtXHHkr~<-*2=|r#b1=)eB{l zBzO~#*ieVDl6VjokmuEh{|tn*KleIIukgV$FnNOyl`~^%Q{}tj({4WU!puE+lZ^_d z%ZO$@d_Nx6RqvN~Q90WoGV+%5=@D7GQRY O6}wWe6f3nV*z!LX= (3, 6): + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + self.loop.close() + policy.reset_watcher() + + asyncio.set_event_loop_policy(policy.original_policy) + self.loop = None + + def _patch_loop(self, loop): + if hasattr(loop, '_asynctest_ran'): + # The loop is already patched + return loop + + loop._asynctest_ran = False + + def wraps(method): + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + try: + return method(*args, **kwargs) + finally: + loop._asynctest_ran = True + + return types.MethodType(wrapper, loop) + + for method in ('run_forever', 'run_until_complete', ): + setattr(loop, method, wraps(getattr(loop, method))) + + if isinstance(loop, asyncio.selector_events.BaseSelectorEventLoop): + loop._selector = asynctest.selector.TestSelector(loop._selector) + + return loop + + def _setUp(self): + self._init_loop() + + # initialize post-test checks + test = getattr(self, self._testMethodName) + checker = getattr(test, asynctest._fail_on._FAIL_ON_ATTR, None) + self._checker = checker or asynctest._fail_on._fail_on() + self._checker.before_test(self) + + if asyncio.iscoroutinefunction(self.setUp): + self.loop.run_until_complete(self.setUp()) + else: + self.setUp() + + # don't take into account if the loop ran during setUp + self.loop._asynctest_ran = False + + def _tearDown(self): + if asyncio.iscoroutinefunction(self.tearDown): + self.loop.run_until_complete(self.tearDown()) + else: + self.tearDown() + + # post-test checks + self._checker.check_test(self) + + # Override unittest.TestCase methods which call setUp() and tearDown() + def run(self, result=None): + orig_result = result + if result is None: + result = self.defaultTestResult() + startTestRun = getattr(result, 'startTestRun', None) + if startTestRun is not None: + startTestRun() + + result.startTest(self) + + testMethod = getattr(self, self._testMethodName) + if (getattr(self.__class__, "__unittest_skip__", False) or + getattr(testMethod, "__unittest_skip__", False)): + # If the class or method was skipped. + try: + skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') or + getattr(testMethod, '__unittest_skip_why__', '')) + self._addSkip(result, self, skip_why) + finally: + result.stopTest(self) + return + expecting_failure = getattr(testMethod, + "__unittest_expecting_failure__", False) + outcome = unittest.case._Outcome(result) + try: + self._outcome = outcome + + with outcome.testPartExecutor(self): + self._setUp() + if outcome.success: + outcome.expecting_failure = expecting_failure + with outcome.testPartExecutor(self, isTest=True): + self._run_test_method(testMethod) + outcome.expecting_failure = False + with outcome.testPartExecutor(self): + self._tearDown() + + self.loop.run_until_complete(self.doCleanups()) + self._unset_loop() + for test, reason in outcome.skipped: + self._addSkip(result, test, reason) + self._feedErrorsToResult(result, outcome.errors) + if outcome.success: + if expecting_failure: + if outcome.expectedFailure: + self._addExpectedFailure(result, outcome.expectedFailure) + else: + self._addUnexpectedSuccess(result) + else: + result.addSuccess(self) + return result + finally: + result.stopTest(self) + if orig_result is None: + stopTestRun = getattr(result, 'stopTestRun', None) + if stopTestRun is not None: + stopTestRun() + + # explicitly break reference cycles: + # outcome.errors -> frame -> outcome -> outcome.errors + # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure + outcome.errors.clear() + outcome.expectedFailure = None + + # clear the outcome, no more needed + self._outcome = None + + def debug(self): + self._setUp() + try: + self._run_test_method(getattr(self, self._testMethodName)) + self._tearDown() + + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + if asyncio.iscoroutinefunction(function): + self.loop.run_until_complete(function(*args, **kwargs)) + else: + function(*args, **kwargs) + except Exception: + raise + finally: + self._unset_loop() + + def _run_test_method(self, method): + # If the method is a coroutine or returns a coroutine, run it on the + # loop + result = method() + if asyncio.iscoroutine(result): + self.loop.run_until_complete(result) + + @asyncio.coroutine + def doCleanups(self): + """ + Execute all cleanup functions. Normally called for you after tearDown. + """ + outcome = self._outcome or unittest.mock._Outcome() + while self._cleanups: + function, args, kwargs = self._cleanups.pop() + with outcome.testPartExecutor(self): + if asyncio.iscoroutinefunction(function): + yield from function(*args, **kwargs) + else: + function(*args, **kwargs) + + return outcome.success + + def addCleanup(self, function, *args, **kwargs): + """ + Add a function, with arguments, to be called when the test is + completed. If function is a coroutine function, it will run on the loop + before it's cleaned. + """ + return super().addCleanup(function, *args, **kwargs) + + @asyncio.coroutine + def assertAsyncRaises(self, exception, awaitable): + """ + Test that an exception of type ``exception`` is raised when an + exception is raised when awaiting ``awaitable``, a future or coroutine. + + :see: :meth:`unittest.TestCase.assertRaises()` + """ + with self.assertRaises(exception): + return (yield from awaitable) + + @asyncio.coroutine + def assertAsyncRaisesRegex(self, exception, regex, awaitable): + """ + Like :meth:`assertAsyncRaises()` but also tests that ``regex`` matches + on the string representation of the raised exception. + + :see: :meth:`unittest.TestCase.assertRaisesRegex()` + """ + with self.assertRaisesRegex(exception, regex): + return (yield from awaitable) + + @asyncio.coroutine + def assertAsyncWarns(self, warning, awaitable): + """ + Test that a warning is triggered when awaiting ``awaitable``, a future + or a coroutine. + + :see: :meth:`unittest.TestCase.assertWarns()` + """ + with self.assertWarns(warning): + return (yield from awaitable) + + @asyncio.coroutine + def assertAsyncWarnsRegex(self, warning, regex, awaitable): + """ + Like :meth:`assertAsyncWarns()` but also tests that ``regex`` matches + on the message of the triggered warning. + + :see: :meth:`unittest.TestCase.assertWarnsRegex()` + """ + with self.assertWarnsRegex(warning, regex): + return (yield from awaitable) + + +class FunctionTestCase(TestCase, unittest.FunctionTestCase): + """ + Enables the same features as :class:`~asynctest.TestCase`, but for + :class:`~asynctest.FunctionTestCase`. + """ + + +class ClockedTestCase(TestCase): + """ + Subclass of :class:`~asynctest.TestCase` with a controlled loop clock, + useful for testing timer based behaviour without slowing test run time. + + The clock will only advance when :meth:`advance()` is called. + """ + def _init_loop(self): + super()._init_loop() + self.loop.time = functools.wraps(self.loop.time)(lambda: self._time) + self._time = 0 + + @asyncio.coroutine + def advance(self, seconds): + """ + Fast forward time by a number of ``seconds``. + + Callbacks scheduled to run up to the destination clock time will be + executed on time: + + >>> self.loop.call_later(1, print_time) + >>> self.loop.call_later(2, self.loop.call_later, 1, print_time) + >>> await self.advance(3) + 1 + 3 + + In this example, the third callback is scheduled at ``t = 2`` to be + executed at ``t + 1``. Hence, it will run at ``t = 3``. The callback as + been called on time. + """ + if seconds < 0: + raise ValueError( + 'Cannot go back in time ({} seconds)'.format(seconds)) + + yield from self._drain_loop() + + target_time = self._time + seconds + while True: + next_time = self._next_scheduled() + if next_time is None or next_time > target_time: + break + + self._time = next_time + yield from self._drain_loop() + + self._time = target_time + yield from self._drain_loop() + + def _next_scheduled(self): + try: + return self.loop._scheduled[0]._when + except IndexError: + return None + + @asyncio.coroutine + def _drain_loop(self): + while True: + next_time = self._next_scheduled() + if not self.loop._ready and (next_time is None or + next_time > self._time): + break + + yield from asyncio.sleep(0) + self.loop._TestCase_asynctest_ran = True + + +def ignore_loop(func=None): + """ + Ignore the error case where the loop did not run during the test. + """ + warnings.warn("ignore_loop() is deprecated in favor of " + "fail_on(unused_loop=False)", DeprecationWarning) + checker = asynctest._fail_on._fail_on({"unused_loop": False}) + return checker if func is None else checker(func) diff --git a/.venv/lib/python3.7/site-packages/asynctest/helpers.py b/.venv/lib/python3.7/site-packages/asynctest/helpers.py new file mode 100644 index 0000000..ceea160 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest/helpers.py @@ -0,0 +1,24 @@ +# coding: utf-8 +""" +Module ``helpers`` +------------------ + +Helper functions and coroutines for :mod:`asynctest`. +""" + +import asyncio + + +@asyncio.coroutine +def exhaust_callbacks(loop): + """ + Run the loop until all ready callbacks are executed. + + The coroutine doesn't wait for callbacks scheduled in the future with + :meth:`~asyncio.BaseEventLoop.call_at()` or + :meth:`~asyncio.BaseEventLoop.call_later()`. + + :param loop: event loop + """ + while loop._ready: + yield from asyncio.sleep(0, loop=loop) diff --git a/.venv/lib/python3.7/site-packages/asynctest/mock.py b/.venv/lib/python3.7/site-packages/asynctest/mock.py new file mode 100644 index 0000000..3ca0418 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest/mock.py @@ -0,0 +1,1382 @@ +# coding: utf-8 +""" +Module ``mock`` +--------------- + +Wrapper to unittest.mock reducing the boilerplate when testing asyncio powered +code. + +A mock can behave as a coroutine, as specified in the documentation of +:class:`~asynctest.mock.Mock`. +""" + +import asyncio +import asyncio.coroutines +import contextlib +import enum +import functools +import inspect +import sys +import types +import unittest.mock + + +# From python 3.6, a sentinel object is used to mark coroutines (rather than +# a boolean) to prevent a mock/proxy object to return a truthy value. +# see: https://github.com/python/asyncio/commit/ea776a11f632a975ad3ebbb07d8981804aa292db +try: + _is_coroutine = asyncio.coroutines._is_coroutine +except AttributeError: + _is_coroutine = True + + +class _AsyncIterator: + """ + Wraps an iterator in an asynchronous iterator. + """ + def __init__(self, iterator): + self.iterator = iterator + + def __aiter__(self): + return self + + async def __anext__(self): + try: + return next(self.iterator) + except StopIteration: + pass + raise StopAsyncIteration + + +# magic methods which must be coroutine functions +async_magic_coroutines = ("__aenter__", "__aexit__", "__anext__") +# all magic methods used in an async context +_async_magics = async_magic_coroutines + ("__aiter__", ) + +# We use unittest.mock.MagicProxy which works well, but it's not aware that +# we want __aexit__ to return a falsy value by default. +# We add the entry in unittest internal dict as it will not change the +# normal behavior of unittest. +unittest.mock._return_values["__aexit__"] = False + + +def _get_async_iter(mock): + """ + Factory of ``__aiter__`` magic methods for a MagicMock. + + It creates a function which returns an asynchronous iterator based on the + return value of ``mock.__aiter__``. + + Since __aiter__ used could be a coroutine in Python 3.5 and 3.6, we also + support this case. + + See: https://www.python.org/dev/peps/pep-0525/#id23 + """ + def __aiter__(): + return_value = mock.__aiter__._mock_return_value + if return_value is DEFAULT: + iterator = iter([]) + else: + iterator = iter(return_value) + + return _AsyncIterator(iterator) + + if asyncio.iscoroutinefunction(mock.__aiter__): + return asyncio.coroutine(__aiter__) + + return __aiter__ + + +unittest.mock._side_effect_methods["__aiter__"] = _get_async_iter + + +async_magic_coroutines = set(async_magic_coroutines) +_async_magics = set(_async_magics) + +# This changes the behavior of unittest, but the change is minor and is +# probably better than overriding __set/get/del attr__ everywhere. +unittest.mock._all_magics |= _async_magics + +def _raise(exception): + raise exception + + +def _make_native_coroutine(coroutine): + """ + Wrap a coroutine (or any function returning an awaitable) in a native + coroutine. + """ + if inspect.iscoroutinefunction(coroutine): + # Nothing to do. + return coroutine + + @functools.wraps(coroutine) + async def wrapper(*args, **kwargs): + return await coroutine(*args, **kwargs) + + return wrapper + + +def _is_started(patching): + if isinstance(patching, _patch_dict): + return patching._is_started + else: + return unittest.mock._is_started(patching) + + +class FakeInheritanceMeta(type): + """ + A metaclass which recreates the original inheritance model from + unittest.mock. + + - NonCallableMock > NonCallableMagicMock + - NonCallable > Mock + - Mock > MagicMock + """ + def __init__(self, name, bases, attrs): + attrs['__new__'] = types.MethodType(self.__new, self) + super().__init__(name, bases, attrs) + + @staticmethod + def __new(cls, *args, **kwargs): + new = type(cls.__name__, (cls, ), {'__doc__': cls.__doc__}) + return object.__new__(new, *args, **kwargs) + + def __instancecheck__(cls, obj): + # That's tricky, each type(mock) is actually a subclass of the actual + # Mock type (see __new__) + if super().__instancecheck__(obj): + return True + + _type = type(obj) + if issubclass(cls, NonCallableMock): + if issubclass(_type, (NonCallableMagicMock, Mock, )): + return True + + if issubclass(cls, Mock) and not issubclass(cls, CoroutineMock): + if issubclass(_type, (MagicMock, )): + return True + + return False + + +def _get_is_coroutine(self): + return self.__dict__['_mock_is_coroutine'] + + +def _set_is_coroutine(self, value): + # property setters and getters are overridden by Mock(), we need to + # update the dict to add values + value = _is_coroutine if bool(value) else False + self.__dict__['_mock_is_coroutine'] = value + + +# _mock_add_spec() is the actual private implementation in unittest.mock, we +# override it to support coroutines in the metaclass. +def _mock_add_spec(self, spec, *args, **kwargs): + unittest.mock.NonCallableMock._mock_add_spec(self, spec, *args, **kwargs) + + _spec_coroutines = [] + for attr in dir(spec): + if asyncio.iscoroutinefunction(getattr(spec, attr)): + _spec_coroutines.append(attr) + + self.__dict__['_spec_coroutines'] = _spec_coroutines + + +def _get_child_mock(self, *args, **kwargs): + _new_name = kwargs.get("_new_name") + if _new_name in self.__dict__['_spec_coroutines']: + return CoroutineMock(*args, **kwargs) + + _type = type(self) + + if issubclass(_type, MagicMock) and _new_name in async_magic_coroutines: + klass = CoroutineMock + elif issubclass(_type, CoroutineMock): + klass = MagicMock + elif not issubclass(_type, unittest.mock.CallableMixin): + if issubclass(_type, unittest.mock.NonCallableMagicMock): + klass = MagicMock + elif issubclass(_type, NonCallableMock): + klass = Mock + else: + klass = _type.__mro__[1] + + return klass(*args, **kwargs) + + +class MockMetaMixin(FakeInheritanceMeta): + def __new__(meta, name, base, namespace): + if not any((isinstance(baseclass, meta) for baseclass in base)): + # this ensures that inspect.iscoroutinefunction() doesn't return + # True when testing a mock. + code_mock = unittest.mock.NonCallableMock(spec_set=types.CodeType) + code_mock.co_flags = 0 + + namespace.update({ + '_mock_add_spec': _mock_add_spec, + '_get_child_mock': _get_child_mock, + '__code__': code_mock, + }) + + return super().__new__(meta, name, base, namespace) + + +class IsCoroutineArgMeta(MockMetaMixin): + def __new__(meta, name, base, namespace): + if not any((isinstance(baseclass, meta) for baseclass in base)): + namespace.update({ + '_asynctest_get_is_coroutine': _get_is_coroutine, + '_asynctest_set_is_coroutine': _set_is_coroutine, + 'is_coroutine': property(_get_is_coroutine, _set_is_coroutine, + doc="True if the object mocked is a coroutine"), + '_is_coroutine': property(_get_is_coroutine), + }) + + wrapped_setattr = namespace.get("__setattr__", base[0].__setattr__) + def __setattr__(self, attrname, value): + if attrname == 'is_coroutine': + self._asynctest_set_is_coroutine(value) + else: + return wrapped_setattr(self, attrname, value) + + namespace['__setattr__'] = __setattr__ + + return super().__new__(meta, name, base, namespace) + + +class AsyncMagicMixin: + """ + Add support for async magic methods to :class:`MagicMock` and + :class:`NonCallableMagicMock`. + + Actually, it's a shameless copy-paste of :class:`unittest.mock.MagicMixin`: + when added to our classes, it will just do exactly what its + :mod:`unittest` counterpart does, but for magic methods. It adds some + behavior but should be compatible with future additions of + :class:`MagicMock`. + """ + # Magic methods are invoked as type(obj).__magic__(obj), as seen in + # PEP-343 (with) and PEP-492 (async with) + def __init__(self, *args, **kwargs): + self._mock_set_async_magics() # make magic work for kwargs in init + unittest.mock._safe_super(AsyncMagicMixin, self).__init__(*args, **kwargs) + self._mock_set_async_magics() # fix magic broken by upper level init + + def _mock_set_async_magics(self): + these_magics = _async_magics + + if getattr(self, "_mock_methods", None) is not None: + these_magics = _async_magics.intersection(self._mock_methods) + remove_magics = _async_magics - these_magics + + for entry in remove_magics: + if entry in type(self).__dict__: + # remove unneeded magic methods + delattr(self, entry) + + # don't overwrite existing attributes if called a second time + these_magics = these_magics - set(type(self).__dict__) + + _type = type(self) + for entry in these_magics: + setattr(_type, entry, unittest.mock.MagicProxy(entry, self)) + + def mock_add_spec(self, *args, **kwargs): + unittest.mock.MagicMock.mock_add_spec(self, *args, **kwargs) + self._mock_set_async_magics() + + def __setattr__(self, name, value): + _mock_methods = getattr(self, '_mock_methods', None) + if _mock_methods is None or name in _mock_methods: + if name in _async_magics: + if not unittest.mock._is_instance_mock(value): + setattr(type(self), name, + unittest.mock._get_method(name, value)) + original = value + + def value(*args, **kwargs): + return original(self, *args, **kwargs) + else: + unittest.mock._check_and_set_parent(self, value, None, name) + setattr(type(self), name, value) + self._mock_children[name] = value + + return object.__setattr__(self, name, value) + + unittest.mock._safe_super(AsyncMagicMixin, self).__setattr__(name, value) + + +# Notes about unittest.mock: +# - MagicMock > Mock > NonCallableMock (where ">" means inherits from) +# - when a mock instance is created, a new class (type) is created +# dynamically, +# - we *must* use magic or object's internals when we want to add our own +# properties, and often override __getattr__/__setattr__ which are used +# in unittest.mock.NonCallableMock. +class NonCallableMock(unittest.mock.NonCallableMock, + metaclass=IsCoroutineArgMeta): + """ + Enhance :class:`unittest.mock.NonCallableMock` with features allowing to + mock a coroutine function. + + If ``is_coroutine`` is set to ``True``, the :class:`NonCallableMock` + object will behave so :func:`asyncio.iscoroutinefunction` will return + ``True`` with ``mock`` as parameter. + + If ``spec`` or ``spec_set`` is defined and an attribute is get, + :class:`~asynctest.CoroutineMock` is returned instead of + :class:`~asynctest.Mock` when the matching spec attribute is a coroutine + function. + + The test author can also specify a wrapped object with ``wraps``. In this + case, the :class:`~asynctest.Mock` object behavior is the same as with an + :class:`unittest.mock.Mock` object: the wrapped object may have methods + defined as coroutine functions. + + See :class:`unittest.mock.NonCallableMock` + """ + def __init__(self, spec=None, wraps=None, name=None, spec_set=None, + is_coroutine=None, parent=None, **kwargs): + super().__init__(spec=spec, wraps=wraps, name=name, spec_set=spec_set, + parent=parent, **kwargs) + + self._asynctest_set_is_coroutine(is_coroutine) + + +class NonCallableMagicMock(AsyncMagicMixin, unittest.mock.NonCallableMagicMock, + metaclass=IsCoroutineArgMeta): + """ + A version of :class:`~asynctest.MagicMock` that isn't callable. + """ + def __init__(self, spec=None, wraps=None, name=None, spec_set=None, + is_coroutine=None, parent=None, **kwargs): + + super().__init__(spec=spec, wraps=wraps, name=name, spec_set=spec_set, + parent=parent, **kwargs) + + self._asynctest_set_is_coroutine(is_coroutine) + + +class Mock(unittest.mock.Mock, metaclass=MockMetaMixin): + """ + Enhance :class:`unittest.mock.Mock` so it returns + a :class:`~asynctest.CoroutineMock` object instead of + a :class:`~asynctest.Mock` object where a method on a ``spec`` or + ``spec_set`` object is a coroutine. + + For instance: + + >>> class Foo: + ... @asyncio.coroutine + ... def foo(self): + ... pass + ... + ... def bar(self): + ... pass + + >>> type(asynctest.mock.Mock(Foo()).foo) + + + >>> type(asynctest.mock.Mock(Foo()).bar) + + + The test author can also specify a wrapped object with ``wraps``. In this + case, the :class:`~asynctest.Mock` object behavior is the same as with an + :class:`unittest.mock.Mock` object: the wrapped object may have methods + defined as coroutine functions. + + If you want to mock a coroutine function, use :class:`CoroutineMock` + instead. + + See :class:`~asynctest.NonCallableMock` for details about :mod:`asynctest` + features, and :mod:`unittest.mock` for the comprehensive documentation + about mocking. + """ + + +class MagicMock(AsyncMagicMixin, unittest.mock.MagicMock, + metaclass=MockMetaMixin): + """ + Enhance :class:`unittest.mock.MagicMock` so it returns + a :class:`~asynctest.CoroutineMock` object instead of + a :class:`~asynctest.Mock` object where a method on a ``spec`` or + ``spec_set`` object is a coroutine. + + If you want to mock a coroutine function, use :class:`CoroutineMock` + instead. + + :class:`MagicMock` allows to mock ``__aenter__``, ``__aexit__``, + ``__aiter__`` and ``__anext__``. + + When mocking an asynchronous iterator, you can set the + ``return_value`` of ``__aiter__`` to an iterable to define the list of + values to be returned during iteration. + + You can not mock ``__await__``. If you want to mock an object implementing + __await__, :class:`CoroutineMock` will likely be sufficient. + + see :class:`~asynctest.Mock`. + + .. versionadded:: 0.11 + + support of asynchronous iterators and asynchronous context managers. + """ + + +class _AwaitEvent: + def __init__(self, mock): + self._mock = mock + self._condition = None + + @asyncio.coroutine + def wait(self, skip=0): + """ + Wait for await. + + :param skip: How many awaits will be skipped. + As a result, the mock should be awaited at least + ``skip + 1`` times. + """ + def predicate(mock): + return mock.await_count > skip + + return (yield from self.wait_for(predicate)) + + @asyncio.coroutine + def wait_next(self, skip=0): + """ + Wait for the next await. + + Unlike :meth:`wait` that counts any await, mock has to be awaited once + more, disregarding to the current + :attr:`asynctest.CoroutineMock.await_count`. + + :param skip: How many awaits will be skipped. + As a result, the mock should be awaited at least + ``skip + 1`` more times. + """ + await_count = self._mock.await_count + + def predicate(mock): + return mock.await_count > await_count + skip + + return (yield from self.wait_for(predicate)) + + @asyncio.coroutine + def wait_for(self, predicate): + """ + Wait for a given predicate to become True. + + :param predicate: A callable that receives mock which result + will be interpreted as a boolean value. + The final predicate value is the return value. + """ + condition = self._get_condition() + + try: + yield from condition.acquire() + + def _predicate(): + return predicate(self._mock) + + return (yield from condition.wait_for(_predicate)) + finally: + condition.release() + + @asyncio.coroutine + def _notify(self): + condition = self._get_condition() + + try: + yield from condition.acquire() + condition.notify_all() + finally: + condition.release() + + def _get_condition(self): + """ + Creation of condition is delayed, to minimize the change of using the + wrong loop. + + A user may create a mock with _AwaitEvent before selecting the + execution loop. Requiring a user to delay creation is error-prone and + inflexible. Instead, condition is created when user actually starts to + use the mock. + """ + # No synchronization is needed: + # - asyncio is thread unsafe + # - there are no awaits here, method will be executed without + # switching asyncio context. + if self._condition is None: + self._condition = asyncio.Condition() + + return self._condition + + def __bool__(self): + return self._mock.await_count != 0 + + +class CoroutineMock(Mock): + """ + Enhance :class:`~asynctest.mock.Mock` with features allowing to mock + a coroutine function. + + The :class:`~asynctest.CoroutineMock` object will behave so the object is + recognized as coroutine function, and the result of a call as a coroutine: + + >>> mock = CoroutineMock() + >>> asyncio.iscoroutinefunction(mock) + True + >>> asyncio.iscoroutine(mock()) + True + + + The result of ``mock()`` is a coroutine which will have the outcome of + ``side_effect`` or ``return_value``: + + - if ``side_effect`` is a function, the coroutine will return the result + of that function, + - if ``side_effect`` is an exception, the coroutine will raise the + exception, + - if ``side_effect`` is an iterable, the coroutine will return the next + value of the iterable, however, if the sequence of result is exhausted, + ``StopIteration`` is raised immediately, + - if ``side_effect`` is not defined, the coroutine will return the value + defined by ``return_value``, hence, by default, the coroutine returns + a new :class:`~asynctest.CoroutineMock` object. + + If the outcome of ``side_effect`` or ``return_value`` is a coroutine, the + mock coroutine obtained when the mock object is called will be this + coroutine itself (and not a coroutine returning a coroutine). + + The test author can also specify a wrapped object with ``wraps``. In this + case, the :class:`~asynctest.Mock` object behavior is the same as with an + :class:`unittest.mock.Mock` object: the wrapped object may have methods + defined as coroutine functions. + """ + #: Property which is set when the mock is awaited. Its ``wait`` and + #: ``wait_next`` coroutine methods can be used to synchronize execution. + #: + #: .. versionadded:: 0.12 + awaited = unittest.mock._delegating_property('awaited') + #: Number of times the mock has been awaited. + #: + #: .. versionadded:: 0.12 + await_count = unittest.mock._delegating_property('await_count') + await_args = unittest.mock._delegating_property('await_args') + await_args_list = unittest.mock._delegating_property('await_args_list') + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # asyncio.iscoroutinefunction() checks this property to say if an + # object is a coroutine + # It is set through __dict__ because when spec_set is True, this + # attribute is likely undefined. + self.__dict__['_is_coroutine'] = _is_coroutine + self.__dict__['_mock_awaited'] = _AwaitEvent(self) + self.__dict__['_mock_await_count'] = 0 + self.__dict__['_mock_await_args'] = None + self.__dict__['_mock_await_args_list'] = unittest.mock._CallList() + + def _mock_call(_mock_self, *args, **kwargs): + try: + result = super()._mock_call(*args, **kwargs) + except StopIteration as e: + side_effect = _mock_self.side_effect + if side_effect is not None and not callable(side_effect): + raise + + result = asyncio.coroutine(_raise)(e) + except BaseException as e: + result = asyncio.coroutine(_raise)(e) + + _call = _mock_self.call_args + + @asyncio.coroutine + def proxy(): + try: + if inspect.isawaitable(result): + return (yield from result) + else: + return result + finally: + _mock_self.await_count += 1 + _mock_self.await_args = _call + _mock_self.await_args_list.append(_call) + yield from _mock_self.awaited._notify() + + return proxy() + + def assert_awaited(_mock_self): + """ + Assert that the mock was awaited at least once. + + .. versionadded:: 0.12 + """ + self = _mock_self + if self.await_count == 0: + msg = ("Expected '%s' to have been awaited." % + self._mock_name or 'mock') + raise AssertionError(msg) + + def assert_awaited_once(_mock_self, *args, **kwargs): + """ + Assert that the mock was awaited exactly once. + + .. versionadded:: 0.12 + """ + self = _mock_self + if not self.await_count == 1: + msg = ("Expected '%s' to have been awaited once. Awaited %s times." % + (self._mock_name or 'mock', self.await_count)) + raise AssertionError(msg) + + def assert_awaited_with(_mock_self, *args, **kwargs): + """ + Assert that the last await was with the specified arguments. + + .. versionadded:: 0.12 + """ + self = _mock_self + if self.await_args is None: + expected = self._format_mock_call_signature(args, kwargs) + raise AssertionError('Expected await: %s\nNot awaited' % (expected,)) + + def _error_message(): + msg = self._format_mock_failure_message(args, kwargs) + return msg + + expected = self._call_matcher((args, kwargs)) + actual = self._call_matcher(self.await_args) + if expected != actual: + cause = expected if isinstance(expected, Exception) else None + raise AssertionError(_error_message()) from cause + + def assert_awaited_once_with(_mock_self, *args, **kwargs): + """ + Assert that the mock was awaited exactly once and with the specified arguments. + + .. versionadded:: 0.12 + """ + self = _mock_self + if not self.await_count == 1: + msg = ("Expected '%s' to be awaited once. Awaited %s times." % + (self._mock_name or 'mock', self.await_count)) + raise AssertionError(msg) + return self.assert_awaited_with(*args, **kwargs) + + def assert_any_await(_mock_self, *args, **kwargs): + """ + Assert the mock has ever been awaited with the specified arguments. + + .. versionadded:: 0.12 + """ + self = _mock_self + expected = self._call_matcher((args, kwargs)) + actual = [self._call_matcher(c) for c in self.await_args_list] + if expected not in actual: + cause = expected if isinstance(expected, Exception) else None + expected_string = self._format_mock_call_signature(args, kwargs) + raise AssertionError( + '%s await not found' % expected_string + ) from cause + + def assert_has_awaits(_mock_self, calls, any_order=False): + """ + Assert the mock has been awaited with the specified calls. + The :attr:`await_args_list` list is checked for the awaits. + + If `any_order` is False (the default) then the awaits must be + sequential. There can be extra calls before or after the + specified awaits. + + If `any_order` is True then the awaits can be in any order, but + they must all appear in :attr:`await_args_list`. + + .. versionadded:: 0.12 + """ + self = _mock_self + expected = [self._call_matcher(c) for c in calls] + cause = expected if isinstance(expected, Exception) else None + all_awaits = unittest.mock._CallList(self._call_matcher(c) for c in self.await_args_list) + if not any_order: + if expected not in all_awaits: + raise AssertionError( + 'Awaits not found.\nExpected: %r\n' + 'Actual: %r' % (unittest.mock._CallList(calls), self.await_args_list) + ) from cause + return + + all_awaits = list(all_awaits) + + not_found = [] + for kall in expected: + try: + all_awaits.remove(kall) + except ValueError: + not_found.append(kall) + if not_found: + raise AssertionError( + '%r not all found in await list' % (tuple(not_found),) + ) from cause + + def assert_not_awaited(_mock_self): + """ + Assert that the mock was never awaited. + + .. versionadded:: 0.12 + """ + self = _mock_self + if self.await_count != 0: + msg = ("Expected '%s' to not have been awaited. Awaited %s times." % + (self._mock_name or 'mock', self.await_count)) + raise AssertionError(msg) + + def reset_mock(self, *args, **kwargs): + """ + See :func:`unittest.mock.Mock.reset_mock()` + """ + super().reset_mock(*args, **kwargs) + self.awaited = _AwaitEvent(self) + self.await_count = 0 + self.await_args = None + self.await_args_list = unittest.mock._CallList() + + +def create_autospec(spec, spec_set=False, instance=False, _parent=None, + _name=None, **kwargs): + """ + Create a mock object using another object as a spec. Attributes on the mock + will use the corresponding attribute on the spec object as their spec. + + ``spec`` can be a coroutine function, a class or object with coroutine + functions as attributes. + + If ``spec`` is a coroutine function, and ``instance`` is not ``False``, a + :exc:`RuntimeError` is raised. + + .. versionadded:: 0.12 + """ + if unittest.mock._is_list(spec): + spec = type(spec) + + is_type = isinstance(spec, type) + is_coroutine_func = asyncio.iscoroutinefunction(spec) + + _kwargs = {'spec': spec} + if spec_set: + _kwargs = {'spec_set': spec} + elif spec is None: + # None we mock with a normal mock without a spec + _kwargs = {} + if _kwargs and instance: + _kwargs['_spec_as_instance'] = True + + _kwargs.update(kwargs) + + Klass = MagicMock + if inspect.isdatadescriptor(spec): + _kwargs = {} + elif is_coroutine_func: + if instance: + raise RuntimeError("Instance can not be True when create_autospec " + "is mocking a coroutine function") + Klass = CoroutineMock + elif not unittest.mock._callable(spec): + Klass = NonCallableMagicMock + elif is_type and instance and not unittest.mock._instance_callable(spec): + Klass = NonCallableMagicMock + + _name = _kwargs.pop('name', _name) + + _new_name = _name + if _parent is None: + _new_name = '' + + mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name, + name=_name, **_kwargs) + + if isinstance(spec, unittest.mock.FunctionTypes): + wrapped_mock = mock + # _set_signature returns an object wrapping the mock, not the mock + # itself. + mock = unittest.mock._set_signature(mock, spec) + if is_coroutine_func: + # Can't wrap the mock with asyncio.coroutine because it doesn't + # detect a CoroWrapper as an awaitable in debug mode. + # It is safe to do so because the mock object wrapped by + # _set_signature returns the result of the CoroutineMock itself, + # which is a Coroutine (as defined in CoroutineMock._mock_call) + mock._is_coroutine = _is_coroutine + mock.awaited = _AwaitEvent(mock) + mock.await_count = 0 + mock.await_args = None + mock.await_args_list = unittest.mock._CallList() + + for a in ('assert_awaited', + 'assert_awaited_once', + 'assert_awaited_with', + 'assert_awaited_once_with', + 'assert_any_await', + 'assert_has_awaits', + 'assert_not_awaited'): + setattr(mock, a, getattr(wrapped_mock, a)) + else: + unittest.mock._check_signature(spec, mock, is_type, instance) + + if _parent is not None and not instance: + _parent._mock_children[_name] = mock + + if is_type and not instance and 'return_value' not in kwargs: + mock.return_value = create_autospec(spec, spec_set, instance=True, + _name='()', _parent=mock) + + for entry in dir(spec): + if unittest.mock._is_magic(entry): + continue + try: + original = getattr(spec, entry) + except AttributeError: + continue + + kwargs = {'spec': original} + if spec_set: + kwargs = {'spec_set': original} + + if not isinstance(original, unittest.mock.FunctionTypes): + new = unittest.mock._SpecState(original, spec_set, mock, entry, + instance) + mock._mock_children[entry] = new + else: + parent = mock + if isinstance(spec, unittest.mock.FunctionTypes): + parent = mock.mock + + skipfirst = unittest.mock._must_skip(spec, entry, is_type) + kwargs['_eat_self'] = skipfirst + if asyncio.iscoroutinefunction(original): + child_klass = CoroutineMock + else: + child_klass = MagicMock + new = child_klass(parent=parent, name=entry, _new_name=entry, + _new_parent=parent, **kwargs) + mock._mock_children[entry] = new + unittest.mock._check_signature(original, new, skipfirst=skipfirst) + + if isinstance(new, unittest.mock.FunctionTypes): + setattr(mock, entry, new) + + return mock + + +def mock_open(mock=None, read_data=''): + """ + A helper function to create a mock to replace the use of :func:`open()`. It + works for :func:`open()` called directly or used as a context manager. + + :param mock: mock object to configure, by default + a :class:`~asynctest.MagicMock` object is + created with the API limited to methods or attributes + available on standard file handles. + + :param read_data: string for the :func:`read()` and :func:`readlines()` of + the file handle to return. This is an empty string by + default. + """ + if mock is None: + mock = MagicMock(name='open', spec=open) + + return unittest.mock.mock_open(mock, read_data) + + +ANY = unittest.mock.ANY +DEFAULT = unittest.mock.sentinel.DEFAULT + + +def _update_new_callable(patcher, new, new_callable): + if new == DEFAULT and not new_callable: + original = patcher.get_original()[0] + if isinstance(original, (classmethod, staticmethod)): + # the original object is the raw descriptor, if it's a classmethod + # or a static method, we need to unwrap it + original = original.__get__(None, object) + + if asyncio.iscoroutinefunction(original): + patcher.new_callable = CoroutineMock + else: + patcher.new_callable = MagicMock + + return patcher + + +# Documented in doc/asynctest.mock.rst +PatchScope = enum.Enum('PatchScope', 'LIMITED GLOBAL') +LIMITED = PatchScope.LIMITED +GLOBAL = PatchScope.GLOBAL + + +def _decorate_coroutine_callable(func, new_patching): + if hasattr(func, 'patchings'): + func.patchings.append(new_patching) + return func + + # Python 3.5 returns True for is_generator_func(new_style_coroutine) if + # there is an "await" statement in the function body, which is wrong. It is + # fixed in 3.6, but I can't find which commit fixes this. + # The only way to work correctly with 3.5 and 3.6 seems to use + # inspect.iscoroutinefunction() + is_generator_func = inspect.isgeneratorfunction(func) + is_coroutine_func = asyncio.iscoroutinefunction(func) + try: + is_native_coroutine_func = inspect.iscoroutinefunction(func) + except AttributeError: + is_native_coroutine_func = False + + if not (is_generator_func or is_coroutine_func): + return None + + patchings = [new_patching] + + def patched_factory(*args, **kwargs): + extra_args = [] + patchers_to_exit = [] + patch_dict_with_limited_scope = [] + + exc_info = tuple() + try: + for patching in patchings: + arg = patching.__enter__() + if patching.scope == LIMITED: + patchers_to_exit.append(patching) + if isinstance(patching, _patch_dict): + if patching.scope == GLOBAL: + for limited_patching in patch_dict_with_limited_scope: + if limited_patching.in_dict is patching.in_dict: + limited_patching._keep_global_patch(patching) + else: + patch_dict_with_limited_scope.append(patching) + else: + if patching.attribute_name is not None: + kwargs.update(arg) + if patching.new is DEFAULT: + patching.new = arg[patching.attribute_name] + elif patching.new is DEFAULT: + patching.mock_to_reuse = arg + extra_args.append(arg) + + args += tuple(extra_args) + gen = func(*args, **kwargs) + return _PatchedGenerator(gen, patchings, + asyncio.iscoroutinefunction(func)) + except BaseException: + if patching not in patchers_to_exit and _is_started(patching): + # the patcher may have been started, but an exception + # raised whilst entering one of its additional_patchers + patchers_to_exit.append(patching) + # Pass the exception to __exit__ + exc_info = sys.exc_info() + # re-raise the exception + raise + finally: + for patching in reversed(patchers_to_exit): + patching.__exit__(*exc_info) + + # wrap the factory in a native coroutine or a generator to respect + # introspection. + if is_native_coroutine_func: + # inspect.iscoroutinefunction() returns True + patched = _make_native_coroutine(patched_factory) + elif is_generator_func: + # inspect.isgeneratorfunction() returns True + def patched_generator(*args, **kwargs): + return (yield from patched_factory(*args, **kwargs)) + + patched = patched_generator + + if is_coroutine_func: + # asyncio.iscoroutinefunction() returns True + patched = asyncio.coroutine(patched) + else: + patched = patched_factory + + patched.patchings = patchings + return functools.wraps(func)(patched) + + +class _PatchedGenerator(asyncio.coroutines.CoroWrapper): + # Inheriting from asyncio.CoroWrapper gives us a comprehensive wrapper + # implementing one or more workarounds for cpython bugs + def __init__(self, gen, patchings, is_coroutine): + self.gen = gen + self._is_coroutine = is_coroutine + self.__name__ = getattr(gen, '__name__', None) + self.__qualname__ = getattr(gen, '__qualname__', None) + self.patchings = patchings + self.global_patchings = [p for p in patchings if p.scope == GLOBAL] + self.limited_patchings = [p for p in patchings if p.scope == LIMITED] + + # GLOBAL patches have been started in the _patch/patched() wrapper + + def _limited_patchings_stack(self): + with contextlib.ExitStack() as stack: + for patching in self.limited_patchings: + stack.enter_context(patching) + + return stack.pop_all() + + def _stop_global_patchings(self): + for patching in reversed(self.global_patchings): + if _is_started(patching): + patching.stop() + + def __repr__(self): + return repr(self.generator) + + def __next__(self): + try: + with self._limited_patchings_stack(): + return self.gen.send(None) + except BaseException: + # the generator/coroutine terminated, stop the patchings + self._stop_global_patchings() + raise + + def send(self, value): + with self._limited_patchings_stack(): + return super().send(value) + + def throw(self, exc, value=None, traceback=None): + with self._limited_patchings_stack(): + return self.gen.throw(exc, value, traceback) + + def close(self): + try: + with self._limited_patchings_stack(): + return self.gen.close() + finally: + self._stop_global_patchings() + + def __del__(self): + # The generator/coroutine is deleted before it terminated, we must + # still stop the patchings + self._stop_global_patchings() + + +class _patch(unittest.mock._patch): + def __init__(self, *args, scope=GLOBAL, **kwargs): + super().__init__(*args, **kwargs) + self.scope = scope + self.mock_to_reuse = None + + def copy(self): + patcher = _patch( + self.getter, self.attribute, self.new, self.spec, + self.create, self.spec_set, + self.autospec, self.new_callable, self.kwargs, + scope=self.scope) + patcher.attribute_name = self.attribute_name + patcher.additional_patchers = [ + p.copy() for p in self.additional_patchers + ] + return patcher + + def __enter__(self): + # When patching a coroutine, we reuse the same mock object + if self.mock_to_reuse is not None: + self.target = self.getter() + self.temp_original, self.is_local = self.get_original() + setattr(self.target, self.attribute, self.mock_to_reuse) + if self.attribute_name is not None: + for patching in self.additional_patchers: + patching.__enter__() + return self.mock_to_reuse + else: + return self._perform_patch() + + def _perform_patch(self): + # This will intercept the result of super().__enter__() if we need to + # override the default behavior (ie: we need to use our own autospec). + original, local = self.get_original() + result = super().__enter__() + + if self.autospec is None or not self.autospec: + # no need to override the default behavior + return result + + if self.autospec is True: + autospec = original + else: + autospec = self.autospec + + new = create_autospec(autospec, spec_set=bool(self.spec_set), + _name=self.attribute, **self.kwargs) + + self.temp_original = original + self.is_local = local + setattr(self.target, self.attribute, new) + + if self.attribute_name is not None: + if self.new is DEFAULT: + result[self.attribute_name] = new + return result + + return new + + def decorate_callable(self, func): + wrapped = _decorate_coroutine_callable(func, self) + if wrapped is None: + return super().decorate_callable(func) + else: + return wrapped + + +def patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, + autospec=None, new_callable=None, scope=GLOBAL, **kwargs): + """ + A context manager, function decorator or class decorator which patches the + target with the value given by the ``new`` argument. + + ``new`` specifies which object will replace the ``target`` when the patch + is applied. By default, the target will be patched with an instance of + :class:`~asynctest.CoroutineMock` if it is a coroutine, or + a :class:`~asynctest.MagicMock` object. + + It is a replacement to :func:`unittest.mock.patch`, but using + :mod:`asynctest.mock` objects. + + When a generator or a coroutine is patched using the decorator, the patch + is activated or deactivated according to the ``scope`` argument value: + + * :const:`asynctest.GLOBAL`: the default, enables the patch until the + generator or the coroutine finishes (returns or raises an exception), + + * :const:`asynctest.LIMITED`: the patch will be activated when the + generator or coroutine is being executed, and deactivated when it + yields a value and pauses its execution (with ``yield``, ``yield from`` + or ``await``). + + The behavior differs from :func:`unittest.mock.patch` for generators. + + When used as a context manager, the patch is still active even if the + generator or coroutine is paused, which may affect concurrent tasks:: + + @asyncio.coroutine + def coro(): + with asynctest.mock.patch("module.function"): + yield from asyncio.get_event_loop().sleep(1) + + @asyncio.coroutine + def independent_coro(): + assert not isinstance(module.function, asynctest.mock.Mock) + + asyncio.create_task(coro()) + asyncio.create_task(independent_coro()) + # this will raise an AssertionError(coro() is scheduled first)! + loop.run_forever() + + :param scope: :const:`asynctest.GLOBAL` or :const:`asynctest.LIMITED`, + controls when the patch is activated on generators and coroutines + + When used as a decorator with a generator based coroutine, the order of + the decorators matters. The order of the ``@patch()`` decorators is in + the reverse order of the parameters produced by these patches for the + patched function. And the ``@asyncio.coroutine`` decorator should be + the last since ``@patch()`` conceptually patches the coroutine, not + the function:: + + @patch("module.function2") + @patch("module.function1") + @asyncio.coroutine + def test_coro(self, mock_function1, mock_function2): + yield from asyncio.get_event_loop().sleep(1) + + see :func:`unittest.mock.patch()`. + + .. versionadded:: 0.6 patch into generators and coroutines with + a decorator. + """ + getter, attribute = unittest.mock._get_target(target) + patcher = _patch(getter, attribute, new, spec, create, spec_set, autospec, + new_callable, kwargs, scope=scope) + + return _update_new_callable(patcher, new, new_callable) + + +def _patch_object(target, attribute, new=DEFAULT, spec=None, create=False, + spec_set=None, autospec=None, new_callable=None, + scope=GLOBAL, **kwargs): + patcher = _patch(lambda: target, attribute, new, spec, create, spec_set, + autospec, new_callable, kwargs, scope=scope) + + return _update_new_callable(patcher, new, new_callable) + + +def _patch_multiple(target, spec=None, create=False, spec_set=None, + autospec=None, new_callable=None, scope=GLOBAL, **kwargs): + if type(target) is str: + def getter(): + return unittest.mock._importer(target) + else: + def getter(): + return target + + if not kwargs: + raise ValueError('Must supply at least one keyword argument with ' + 'patch.multiple') + + items = list(kwargs.items()) + attribute, new = items[0] + patcher = _patch(getter, attribute, new, spec, create, spec_set, autospec, + new_callable, {}, scope=scope) + + patcher.attribute_name = attribute + for attribute, new in items[1:]: + this_patcher = _patch(getter, attribute, new, spec, create, spec_set, + autospec, new_callable, {}, scope=scope) + this_patcher.attribute_name = attribute + patcher.additional_patchers.append(this_patcher) + + def _update(patcher): + return _update_new_callable(patcher, patcher.new, new_callable) + + patcher = _update(patcher) + patcher.additional_patchers = list(map(_update, + patcher.additional_patchers)) + + return patcher + + +class _patch_dict(unittest.mock._patch_dict): + # documentation is in doc/asynctest.mock.rst + def __init__(self, in_dict, values=(), clear=False, scope=GLOBAL, + **kwargs): + super().__init__(in_dict, values, clear, **kwargs) + self.scope = scope + self._is_started = False + self._global_patchings = [] + + def _keep_global_patch(self, other_patching): + self._global_patchings.append(other_patching) + + def decorate_class(self, klass): + for attr in dir(klass): + attr_value = getattr(klass, attr) + if (attr.startswith(patch.TEST_PREFIX) and + hasattr(attr_value, "__call__")): + decorator = _patch_dict(self.in_dict, self.values, self.clear) + decorated = decorator(attr_value) + setattr(klass, attr, decorated) + return klass + + def __call__(self, func): + if isinstance(func, type): + return self.decorate_class(func) + + wrapper = _decorate_coroutine_callable(func, self) + if wrapper is None: + return super().__call__(func) + else: + return wrapper + + def _patch_dict(self): + self._is_started = True + + # Since Python 3.7.3, the moment when a dict specified by a target + # string has been corrected. (see #115) + if isinstance(self.in_dict, str): + self.in_dict = unittest.mock._importer(self.in_dict) + + try: + self._original = self.in_dict.copy() + except AttributeError: + # dict like object with no copy method + # must support iteration over keys + self._original = {} + for key in self.in_dict: + self._original[key] = self.in_dict[key] + + if self.clear: + _clear_dict(self.in_dict) + + try: + self.in_dict.update(self.values) + except AttributeError: + # dict like object with no update method + for key in self.values: + self.in_dict[key] = self.values[key] + + def _unpatch_dict(self): + self._is_started = False + + if self.scope == LIMITED: + # add to self.values the updated values which where not in + # the original dict, as the patch may be reactivated + for key in self.in_dict: + if (key not in self._original or + self._original[key] is not self.in_dict[key]): + self.values[key] = self.in_dict[key] + + _clear_dict(self.in_dict) + + originals = [self._original] + for patching in self._global_patchings: + if patching._is_started: + # keep the values of global patches + originals.append(patching.values) + + for original in originals: + try: + self.in_dict.update(original) + except AttributeError: + for key in original: + self.in_dict[key] = original[key] + + +_clear_dict = unittest.mock._clear_dict + +patch.object = _patch_object +patch.dict = _patch_dict +patch.multiple = _patch_multiple +patch.stopall = unittest.mock._patch_stopall +patch.TEST_PREFIX = 'test' + + +sentinel = unittest.mock.sentinel +call = unittest.mock.call +PropertyMock = unittest.mock.PropertyMock + + +def return_once(value, then=None): + """ + Helper to use with ``side_effect``, so a mock will return a given value + only once, then return another value. + + When used as a ``side_effect`` value, if one of ``value`` or ``then`` is an + :class:`Exception` type, an instance of this exception will be raised. + + >>> mock.recv = Mock(side_effect=return_once(b"data")) + >>> mock.recv() + b"data" + >>> repr(mock.recv()) + 'None' + >>> repr(mock.recv()) + 'None' + + >>> mock.recv = Mock(side_effect=return_once(b"data", then=BlockingIOError)) + >>> mock.recv() + b"data" + >>> mock.recv() + Traceback BlockingIOError + + :param value: value to be returned once by the mock when called. + + :param then: value returned for any subsequent call. + + .. versionadded:: 0.4 + """ + yield value + while True: + yield then diff --git a/.venv/lib/python3.7/site-packages/asynctest/selector.py b/.venv/lib/python3.7/site-packages/asynctest/selector.py new file mode 100644 index 0000000..0838a1d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/asynctest/selector.py @@ -0,0 +1,378 @@ +# coding: utf-8 +""" +Module ``selector`` +------------------- + +Mock of :mod:`selectors` and compatible objects performing asynchronous IO. + +This module provides classes to mock objects performing IO (files, sockets, +etc). These mocks are compatible with :class:`~asynctest.TestSelector`, which +can simulate the behavior of a selector on the mock objects, or forward actual +work to a real selector. +""" + +import asyncio +try: + import selectors +except ImportError: + # In the case of Python 3.3, attempt to use the selectors + # modules from within the asyncio package + import asyncio.selectors as selectors +import socket + +try: + import ssl +except ImportError: + # allow python to be compiled without ssl + ssl = None + +from . import mock +from . import _fail_on + + +class FileDescriptor(int): + """ + A subclass of int which allows to identify the virtual file-descriptor of a + :class:`~asynctest.FileMock`. + + If :class:`~asynctest.FileDescriptor()` without argument, its value will be + the value of :data:`~FileDescriptor.next_fd`. + + When an object is created, :data:`~FileDescriptor.next_fd` is set to the + highest value for a :class:`~asynctest.FileDescriptor` object + 1. + """ + next_fd = 0 + + def __new__(cls, *args, **kwargs): + if not args and not kwargs: + s = super().__new__(cls, FileDescriptor.next_fd) + else: + s = super().__new__(cls, *args, **kwargs) + + FileDescriptor.next_fd = max(FileDescriptor.next_fd + 1, s + 1) + + return s + + def __hash__(self): + # Return a different hash than the int so we can register both a + # FileDescriptor object and an int of the same value + return hash('__FileDescriptor_{}'.format(self)) + + +def fd(fileobj): + """ + Return the :class:`~asynctest.FileDescriptor` value of ``fileobj``. + + If ``fileobj`` is a :class:`~asynctest.FileDescriptor`, ``fileobj`` is + returned, else ``fileobj.fileno()`` is returned instead. + + Note that if fileobj is an int, :exc:`ValueError` is raised. + + :raise ValueError: if ``fileobj`` is not a :class:`~asynctest.FileMock`, + a file-like object or + a :class:`~asynctest.FileDescriptor`. + """ + try: + return fileobj if isinstance(fileobj, FileDescriptor) else fileobj.fileno() + except Exception: + raise ValueError + + +def isfilemock(obj): + """ + Return ``True`` if the ``obj`` or ``obj.fileno()`` is + a :class:`asynctest.FileDescriptor`. + """ + try: + return (isinstance(obj, FileDescriptor) or + isinstance(obj.fileno(), FileDescriptor)) + except AttributeError: + # obj has no attribute fileno() + return False + + +class FileMock(mock.Mock): + """ + Mock a file-like object. + + A FileMock is an intelligent mock which can work with TestSelector to + simulate IO events during tests. + + .. method:: fileno() + + Return a :class:`~asynctest.FileDescriptor` object. + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.fileno.return_value = FileDescriptor() + + def _get_child_mock(self, *args, **kwargs): + # A FileMock returns a Mock by default, not a FileMock + return mock.Mock(**kwargs) + + +class SocketMock(FileMock): + """ + Mock a socket. + + See :class:`~asynctest.FileMock`. + """ + def __init__(self, side_effect=None, return_value=mock.DEFAULT, + wraps=None, name=None, spec_set=None, parent=None, + **kwargs): + super().__init__(socket.socket, side_effect=side_effect, + return_value=return_value, wraps=wraps, name=name, + spec_set=spec_set, parent=parent, **kwargs) + + +if ssl: + class SSLSocketMock(SocketMock): + """ + Mock a socket wrapped by the :mod:`ssl` module. + + See :class:`~asynctest.FileMock`. + + .. versionadded:: 0.5 + """ + def __init__(self, side_effect=None, return_value=mock.DEFAULT, + wraps=None, name=None, spec_set=None, parent=None, + **kwargs): + FileMock.__init__(self, ssl.SSLSocket, side_effect=side_effect, + return_value=return_value, wraps=wraps, name=name, + spec_set=spec_set, parent=parent, **kwargs) + + +def _set_event_ready(fileobj, loop, event): + selector = loop._selector + fd = selector._fileobj_lookup(fileobj) + + if fd in selector._fd_to_key: + loop._process_events([(selector._fd_to_key[fd], event)]) + + +def set_read_ready(fileobj, loop): + """ + Schedule callbacks registered on ``loop`` as if the selector notified that + data is ready to be read on ``fileobj``. + + :param fileobj: file object or :class:`~asynctest.FileMock` on which the + event is mocked. + + :param loop: :class:`asyncio.SelectorEventLoop` watching for events on + ``fileobj``. + + :: + + mock = asynctest.SocketMock() + mock.recv.return_value = b"Data" + + def read_ready(sock): + print("received:", sock.recv(1024)) + + loop.add_reader(mock, read_ready, mock) + + set_read_ready(mock, loop) + + loop.run_forever() # prints received: b"Data" + + .. versionadded:: 0.4 + """ + # since the selector would notify of events at the beginning of the next + # iteration, we let this iteration finish before actually scheduling the + # reader (hence the call_soon) + loop.call_soon_threadsafe(_set_event_ready, fileobj, loop, selectors.EVENT_READ) + + +def set_write_ready(fileobj, loop): + """ + Schedule callbacks registered on ``loop`` as if the selector notified that + data can be written to ``fileobj``. + + :param fileobj: file object or :class:`~asynctest.FileMock` on which th + event is mocked. + :param loop: :class:`asyncio.SelectorEventLoop` watching for events on + ``fileobj``. + + .. versionadded:: 0.4 + """ + loop.call_soon_threadsafe(_set_event_ready, fileobj, loop, selectors.EVENT_WRITE) + + +class TestSelector(selectors._BaseSelectorImpl): + """ + A selector which supports IOMock objects. + + It can wrap an actual implementation of a selector, so the selector will + work both with mocks and real file-like objects. + + A common use case is to patch the selector loop:: + + loop._selector = asynctest.TestSelector(loop._selector) + + :param selector: optional, if provided, this selector will be used to work + with real file-like objects. + """ + def __init__(self, selector=None): + super().__init__() + self._selector = selector + + def _fileobj_lookup(self, fileobj): + if isfilemock(fileobj): + return fd(fileobj) + + return super()._fileobj_lookup(fileobj) + + def register(self, fileobj, events, data=None): + """ + Register a file object or a :class:`~asynctest.FileMock`. + + If a real selector object has been supplied to the + :class:`~asynctest.TestSelector` object and ``fileobj`` is not + a :class:`~asynctest.FileMock` or a :class:`~asynctest.FileDescriptor` + returned by :meth:`FileMock.fileno()`, the object will be registered to + the real selector. + + See :meth:`selectors.BaseSelector.register`. + """ + if isfilemock(fileobj) or self._selector is None: + key = super().register(fileobj, events, data) + else: + key = self._selector.register(fileobj, events, data) + + if key: + self._fd_to_key[key.fd] = key + + return key + + def unregister(self, fileobj): + """ + Unregister a file object or a :class:`~asynctest.FileMock`. + + See :meth:`selectors.BaseSelector.unregister`. + """ + if isfilemock(fileobj) or self._selector is None: + key = super().unregister(fileobj) + else: + key = self._selector.unregister(fileobj) + + if key and key.fd in self._fd_to_key: + del self._fd_to_key[key.fd] + + return key + + def modify(self, fileobj, events, data=None): + """ + Shortcut when calling :meth:`TestSelector.unregister` then + :meth:`TestSelector.register` to update the registration of a an object + to the selector. + + See :meth:`selectors.BaseSelector.modify`. + """ + if isfilemock(fileobj) or self._selector is None: + key = super().modify(fileobj, events, data) + else: + # del the key first because modify() fails if events is incorrect + fd = self._fileobj_lookup(fileobj) + + if fd in self._fd_to_key: + del self._fd_to_key[fd] + + key = self._selector.modify(fileobj, events, data) + + if key: + self._fd_to_key[key.fd] = key + + return key + + def select(self, timeout=None): + """ + Perform the selection. + + This method is a no-op if no actual selector has been supplied. + + See :meth:`selectors.BaseSelector.select`. + """ + if self._selector is None: + return [] + + return self._selector.select(timeout) + + def close(self): + """ + Close the selector. + + Close the actual selector if supplied, unregister all mocks. + + See :meth:`selectors.BaseSelector.close`. + """ + if self._selector is not None: + self._selector.close() + + super().close() + + +def get_registered_events(selector): + watched_events = [] + for event in selector.get_map().values(): + watched_events.append(event) + + if selector._selector is not None: + # this is our TestSelector, wrapping a true selector object + for event in selector._selector.get_map().values(): + watched_events.append(event) + + return set(watched_events) + + +if hasattr(asyncio, "format_helpers"): + # Python 3.7+ + def _format_callback(handle): + return asyncio.format_helpers._format_callback(handle._callback, + handle._args, None) +elif hasattr(asyncio.events, "_format_args_and_kwargs"): + # Python 3.5, 3.6 + def _format_callback(handle): + return asyncio.events._format_callback(handle._callback, handle._args, + None) +else: + # Python 3.4 + def _format_callback(handle): + return asyncio.events._format_callback(handle._callback, handle._args) + + +def _format_event(event): + callbacks = [] + + if event.events & selectors.EVENT_READ: + callbacks.append("add_reader({}, {})".format( + event.fileobj, _format_callback(event.data[0]))) + + if event.events & selectors.EVENT_WRITE: + callbacks.append("add_writer({}, {})".format( + event.fileobj, _format_callback(event.data[1]))) + + return callbacks + + +def fail_on_before_test_active_selector_callbacks(case): + case._active_selector_callbacks = get_registered_events( + case.loop._selector) + + +def fail_on_active_selector_callbacks(case): + ignored_events = case._active_selector_callbacks + active_events = get_registered_events(case.loop._selector) + + output = ["some events watched during the tests were not removed:"] + for c in map(_format_event, active_events - ignored_events): + output.extend(c) + + if len(output) > 1: + case.fail("\n - ".join(output)) + + +_fail_on.DEFAULTS["active_selector_callbacks"] = False +_fail_on._fail_on.active_selector_callbacks = staticmethod(fail_on_active_selector_callbacks) +_fail_on._fail_on.before_test_active_selector_callbacks = \ + staticmethod(fail_on_before_test_active_selector_callbacks) diff --git a/.venv/lib/python3.7/site-packages/attr/__init__.py b/.venv/lib/python3.7/site-packages/attr/__init__.py new file mode 100644 index 0000000..51b1c25 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/__init__.py @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: MIT + +""" +Classes Without Boilerplate +""" + +from functools import partial +from typing import Callable + +from . import converters, exceptions, filters, setters, validators +from ._cmp import cmp_using +from ._compat import Protocol +from ._config import get_run_validators, set_run_validators +from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types +from ._make import ( + NOTHING, + Attribute, + Converter, + Factory, + attrib, + attrs, + fields, + fields_dict, + make_class, + validate, +) +from ._next_gen import define, field, frozen, mutable +from ._version_info import VersionInfo + + +s = attributes = attrs +ib = attr = attrib +dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + + +class AttrsInstance(Protocol): + pass + + +__all__ = [ + "Attribute", + "AttrsInstance", + "Converter", + "Factory", + "NOTHING", + "asdict", + "assoc", + "astuple", + "attr", + "attrib", + "attributes", + "attrs", + "cmp_using", + "converters", + "define", + "evolve", + "exceptions", + "field", + "fields", + "fields_dict", + "filters", + "frozen", + "get_run_validators", + "has", + "ib", + "make_class", + "mutable", + "resolve_types", + "s", + "set_run_validators", + "setters", + "validate", + "validators", +] + + +def _make_getattr(mod_name: str) -> Callable: + """ + Create a metadata proxy for packaging information that uses *mod_name* in + its warnings and errors. + """ + + def __getattr__(name: str) -> str: + if name not in ("__version__", "__version_info__"): + msg = f"module {mod_name} has no attribute {name}" + raise AttributeError(msg) + + try: + from importlib.metadata import metadata + except ImportError: + from importlib_metadata import metadata + + meta = metadata("attrs") + + if name == "__version_info__": + return VersionInfo._from_version_string(meta["version"]) + + return meta["version"] + + return __getattr__ + + +__getattr__ = _make_getattr(__name__) diff --git a/.venv/lib/python3.7/site-packages/attr/__init__.pyi b/.venv/lib/python3.7/site-packages/attr/__init__.pyi new file mode 100644 index 0000000..6ae0a83 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/__init__.pyi @@ -0,0 +1,388 @@ +import enum +import sys + +from typing import ( + Any, + Callable, + Generic, + Mapping, + Protocol, + Sequence, + TypeVar, + overload, +) + +# `import X as X` is required to make these public +from . import converters as converters +from . import exceptions as exceptions +from . import filters as filters +from . import setters as setters +from . import validators as validators +from ._cmp import cmp_using as cmp_using +from ._typing_compat import AttrsInstance_ +from ._version_info import VersionInfo +from attrs import ( + define as define, + field as field, + mutable as mutable, + frozen as frozen, + _EqOrderType, + _ValidatorType, + _ConverterType, + _ReprArgType, + _OnSetAttrType, + _OnSetAttrArgType, + _FieldTransformer, + _ValidatorArgType, +) + +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +if sys.version_info >= (3, 11): + from typing import dataclass_transform +else: + from typing_extensions import dataclass_transform + +__version__: str +__version_info__: VersionInfo +__title__: str +__description__: str +__url__: str +__uri__: str +__author__: str +__email__: str +__license__: str +__copyright__: str + +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) + +_FilterType = Callable[["Attribute[_T]", _T], bool] + +# We subclass this here to keep the protocol's qualified name clean. +class AttrsInstance(AttrsInstance_, Protocol): + pass + +_A = TypeVar("_A", bound=type[AttrsInstance]) + +class _Nothing(enum.Enum): + NOTHING = enum.auto() + +NOTHING = _Nothing.NOTHING + +# NOTE: Factory lies about its return type to make this possible: +# `x: List[int] # = Factory(list)` +# Work around mypy issue #4554 in the common case by using an overload. +if sys.version_info >= (3, 8): + from typing import Literal + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Callable[[Any], _T], + takes_self: Literal[True], + ) -> _T: ... + @overload + def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], + ) -> _T: ... + +else: + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Union[Callable[[Any], _T], Callable[[], _T]], + takes_self: bool = ..., + ) -> _T: ... + +In = TypeVar("In") +Out = TypeVar("Out") + +class Converter(Generic[In, Out]): + @overload + def __init__(self, converter: Callable[[In], Out]) -> None: ... + @overload + def __init__( + self, + converter: Callable[[In, AttrsInstance, Attribute], Out], + *, + takes_self: Literal[True], + takes_field: Literal[True], + ) -> None: ... + @overload + def __init__( + self, + converter: Callable[[In, Attribute], Out], + *, + takes_field: Literal[True], + ) -> None: ... + @overload + def __init__( + self, + converter: Callable[[In, AttrsInstance], Out], + *, + takes_self: Literal[True], + ) -> None: ... + +class Attribute(Generic[_T]): + name: str + default: _T | None + validator: _ValidatorType[_T] | None + repr: _ReprArgType + cmp: _EqOrderType + eq: _EqOrderType + order: _EqOrderType + hash: bool | None + init: bool + converter: _ConverterType | Converter[Any, _T] | None + metadata: dict[Any, Any] + type: type[_T] | None + kw_only: bool + on_setattr: _OnSetAttrType + alias: str | None + + def evolve(self, **changes: Any) -> "Attribute[Any]": ... + +# NOTE: We had several choices for the annotation to use for type arg: +# 1) Type[_T] +# - Pros: Handles simple cases correctly +# - Cons: Might produce less informative errors in the case of conflicting +# TypeVars e.g. `attr.ib(default='bad', type=int)` +# 2) Callable[..., _T] +# - Pros: Better error messages than #1 for conflicting TypeVars +# - Cons: Terrible error messages for validator checks. +# e.g. attr.ib(type=int, validator=validate_str) +# -> error: Cannot infer function type argument +# 3) type (and do all of the work in the mypy plugin) +# - Pros: Simple here, and we could customize the plugin with our own errors. +# - Cons: Would need to write mypy plugin code to handle all the cases. +# We chose option #1. + +# `attr` lies about its return type to make the following possible: +# attr() -> Any +# attr(8) -> int +# attr(validator=) -> Whatever the callable expects. +# This makes this type of assignments possible: +# x: int = attr(8) +# +# This form catches explicit None or no default but with no other arguments +# returns Any. +@overload +def attrib( + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + type: None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def attrib( + default: None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + type: type[_T] | None = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def attrib( + default: _T, + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + type: type[_T] | None = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def attrib( + default: _T | None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + type: object = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., +) -> Any: ... +@overload +@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) +def attrs( + maybe_cls: _C, + these: dict[str, Any] | None = ..., + repr_ns: str | None = ..., + repr: bool = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., + unsafe_hash: bool | None = ..., +) -> _C: ... +@overload +@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) +def attrs( + maybe_cls: None = ..., + these: dict[str, Any] | None = ..., + repr_ns: str | None = ..., + repr: bool = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., + unsafe_hash: bool | None = ..., +) -> Callable[[_C], _C]: ... +def fields(cls: type[AttrsInstance]) -> Any: ... +def fields_dict(cls: type[AttrsInstance]) -> dict[str, Attribute[Any]]: ... +def validate(inst: AttrsInstance) -> None: ... +def resolve_types( + cls: _A, + globalns: dict[str, Any] | None = ..., + localns: dict[str, Any] | None = ..., + attribs: list[Attribute[Any]] | None = ..., + include_extras: bool = ..., +) -> _A: ... + +# TODO: add support for returning a proper attrs class from the mypy plugin +# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', +# [attr.ib()])` is valid +def make_class( + name: str, + attrs: list[str] | tuple[str, ...] | dict[str, Any], + bases: tuple[type, ...] = ..., + class_body: dict[str, Any] | None = ..., + repr_ns: str | None = ..., + repr: bool = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + collect_by_mro: bool = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., +) -> type: ... + +# _funcs -- + +# TODO: add support for returning TypedDict from the mypy plugin +# FIXME: asdict/astuple do not honor their factory args. Waiting on one of +# these: +# https://github.com/python/mypy/issues/4236 +# https://github.com/python/typing/issues/253 +# XXX: remember to fix attrs.asdict/astuple too! +def asdict( + inst: AttrsInstance, + recurse: bool = ..., + filter: _FilterType[Any] | None = ..., + dict_factory: type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Callable[[type, Attribute[Any], Any], Any] | None = ..., + tuple_keys: bool | None = ..., +) -> dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: AttrsInstance, + recurse: bool = ..., + filter: _FilterType[Any] | None = ..., + tuple_factory: type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> tuple[Any, ...]: ... +def has(cls: type) -> TypeGuard[type[AttrsInstance]]: ... +def assoc(inst: _T, **changes: Any) -> _T: ... +def evolve(inst: _T, **changes: Any) -> _T: ... + +# _config -- + +def set_run_validators(run: bool) -> None: ... +def get_run_validators() -> bool: ... + +# aliases -- + +s = attributes = attrs +ib = attr = attrib +dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97fe3733bc2f64443bd664f2cfbdc89e439bf399 GIT binary patch literal 2345 zcmbtUOK%)S5T2Qx-Pv95I_vk_9@|Omb>j6aL4cwti3Pz2Or%5v`qCP2w>KkC&n(@& z#Mkza(=S5Em0oT%#Y1AJvh^G!ditE%h!p4IDB2cDn5`?IrDcAUSk zbNS3e;|Y9f&vhK;5Qn+UOI+a*&&75jDF~nV(Dqp|DT)#)iGT#6Ov<7{DxylNcCM84 zi5jWdc97IXKk2vaa&k*FNJ9*e0o$)6gJOsbiD5D8zb4P0tK=xTdm~((C1B5NzBSYnDtYQY>z3Q-lbzwh1Dod)Eo?_v4hCqFoGoWp=_-6NsM1+(E>B zUqZqlQ9J2=_NwWUTGZ1S&5u-V%=_hod42+)ssV6^xIhe#xo~}+sbdIgCsjI1+kCfK zFl9>9NN`F`l~R$hUV`l!rQh_TB%k@ikxO98!r$v_T6EXCad$OFD@n4NY;LK}!;N^& z#%*zp(m0JZrLFF?ApE@L4%_RV+g|t{Rp=Z8UV&edvY9`)jUqfypj{R z03|^d5oQqv5K0Jh2$Kj?2mwNffXR@90LF{=(D$xk}ct1N!2~8H5S|o~J0X~IJYIvFZ&ildH2N7b0x3x3(6tnK1bgLme+mZuE!YCA6 zM^M&L*p=DQak!t!up6}xq7Kw{7{mQa5g{i+{U*|356QN2>BkBzu-0O&!fzv)!X6by zDGRxjK$Mo91kZiEJJ|xqu3ScUF+vPk9RZwz!v}#3nfIgfi^B@1fWP`@u69n{bN74q zxM6h@^z;n$^tF?QzM~5VRr$ho@U^pkKKr$kdS5xG9xI)@XJCm12cGQe;%}wX0xM5A zze6hW7Nn%I3m*1S3Oax_4F%V@?qCKeJqhw+3{M6_pk8ru;}lp3__xtQv&4 z1-VY@S9fPwhL#r3WMbG_zZ^>^={sRL|P7(kB literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/_cmp.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/_cmp.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf5ee868bbeea6cde4d014ab92730ce3f5fb1b88 GIT binary patch literal 3941 zcmcIn&2JmW6`xry$t5k(vYptCZM2i1MNC7cEC)dgLl)B74Umftv5^8og5`=cq*hw) zQZqxVW|sw88Hjt!r9gwafPL&g(0`@Co(lBjbAcXw>hI0+LyD7A;U(r{=gq$N=FRVY z@K>v=O@`;&Km2oWZH=*i)64v+WAX`_*+nOrVX7wHy?d|u*2LSwus!j%@3pIir;Z9Qv1qFB1{eqGQPI4g4M&lV_7c@2t?4<3 z7NAwo%vJD~e84R`VFPBN{d50MOjf3K=}&{4$?9Q4Z_C;=u%4{v?8JMU>h$vZlRLbeH{0Y>Ho@i z57{?dUrv3_((8Hf4L2+D^0aB2dGmz-k=t`GR&sm=E)BYY=(W#SQ{cI;Rb-WjL@$Yq z5q3Yaq8FuNPl*v0loWAlGtrH#)uz*rRU*3|8qw{lqi%N{W2U9jm^yAzDzVfXj=EhD z>A`rYQVXV;=#7odhVeuR$3pbn1;!>zJ5BfHqkSc`GULR?>0qYJahxP#KYC2+^~abS zWkuE(P9$v`D!ZRaBjUb*+KGycb2OjtN;u9f=$E$q2GK_oE~sz=>S!fPZ_ri8d~%V=@^ItR6?nm@KP~#!(X6 zC!~-)&P29%pnBHK#L>5j{lA4A@52&G3wLlQK*RY>pPtd?hgEr7<~gkjuzf}whaSSy52~fHCDtl5(NKlJ zDzx0ovgAAX{LQ{fMfZ^&D>&@}lH?0-IFs`_t?XEzHB5IWv!4w|i6W;~vP)h!1G94^ zK+Itrj!e1;(&ZGoTzm;rqTDc6FWgA%&=Q=(ZRm&xsvjW=xTx{LGR}W6WA#ue(OpK5 zuIK|(!wilrm5t(L?pU3Uc&xOEvow=eDzMQ6=wGZNF%Qp-D1p!Vq~V zjMLa+wi?ci>cUrXA&gB}ilhJ#+DudG`gG@!u3;={VW^Jq8OBtFq4uz-DJ{`T0*0FM zl6xU?WA-v23T0!W3_$4-S9)lqGFOW!ADC?4I4Q)3aZZY6gieM{=hI=yF{t6=ggT^M; zKnll(;@wt~^`gXVV^Z#Vg_OZ24-gWE2FRWz3v z-o2ELhb5oTu?Nu1?)m-55EkYurT$@28JdB<3XR)bzlT9zBkdatW3S@Xe1eYM_PNhJ z9{3o&0P_}aVhniedwQQ=#=e!xRbH$3*wgg%I(YPm5j}(>0^@x&vw}{d5PHg{z!Q*E znY{0uVO9am(LYP79Y^cY=k(A>?IBtTNuIM148h2oY%XHfXSmN8`3{M`yeM%T+kJ7< z`POCaiEe@jeD36r0`k$;vKviJawR6)RZ zaS_}J1f>XP%G2VUJt^e=c`k$b4p3(-NwV+L2HFWQvIF3r`on-uH2K`wZ-xP?E2tc} zNp`yFO6;4?mY5?mQ{{WQDp(hvBC}wfYSQD_piH2c0JSM3P);rbZTQAPmbTJA!`A1d zAZdyd(0jYSL(d~ke+Ju4{UHYZKDwgn5bctR{+L$D?_3mcAadt-EJ_Jvw52R$%3&tQ diP|Q7nd|5flD(D6nvY9f{F+||t>8*f{~y1g{gMCx literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/_compat.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5c45044561b410f64065e8f6ad8f967dddff452 GIT binary patch literal 2540 zcmaJ?QEwYX5Z>K8pU;k+IBD86K*I@vimNsuZIPg$ss*Z02_lP7ActUex!XABobRr? zn^Ifh0kym$UU^F%`9($nJtsZ*{}GGDN7YB%_)lumf0yw4J>n0mO5BkQhh-_15F zs-FjW9;e;H-4ag^L>h`VEt-5oq(a8w!z2z=VRr_d!3l#IZFXY8aDrKBGg(EsHX&mk z$9Bl%soa>5n-lUZ%CvAhGSgX@B_Sl)JUH6WK8B{y>yY%w5shd}ju`~NhBxcp=-Ck3 z3(_>xfsV6OdAphPZiI=tv3lxK%yB;9!Z}3lavsH@=De`FLc=aBnDaZ4i}1C-*Vc4D zU(4hCR-7swB+0Gh_8rxIcRgMUw3f>BYdp;Qd7xMGLDAx{$mBQP!kr^##Fkf}4^bRH zXnz1rtwJXVG8tG*fx)axeLJ!u8*){NDv<-D6ICM@#%ff9(Cft_e|Q@1qvu)%q0Z#+ zdlT(Q_w*na)2PU-?*(26u>?Dbxamou4`d3d_cpUsct7kx%AX18={+HZSu0jv3a?5S z3roe_&;$f~#t{>5@^cr2K}$n^4(TyHB%A@2S8Sp!ZSOLm^J+=w2(rjoN$7|`D0H)3 zDXM^QE<#<@-~(v@n-cOWtXR~)3X%iyNXkqWwJ#waBSPkEC6e939fx8vR(6+h9watS zV@NFSOCePWWwb>X=;JW%r;jQtidNUaYTU zDzqp1xgMO+dQ;*#X}cv}b`mRH)bl_FeW8U^h4Ty%R7L%a`*Im(6t&LSsi>GW;m}^g z7mk^&&O^G0;NFUkLF<^H1T%AP{l`_ZuJ}#B#*| zO*QLTJsUtB=_5$l@PmsWElFJ>`+vZ-D~3I(#cQI&^B|X?y9rHUb#`r=Im~t3rm=K-udjw)<}83R2t^Z`a4tF`jmEiO1m?q-7U5Ga$j6L*CNHwDmjPy zoq62PGpWl8>0~=S2+MDto%JN%@eM`KOv>CvCiO)n$)JS#4JmR7H(9D-eFNeI@`g`k tRsFDJ<$Z)oVQF=#`N6?&SPiJI6F;kND()<8um*Fe%Us*7&fayce*tiQh0*{3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/_config.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/_config.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fcbf315fd51ca17dddf3c6eea0250ebe6c6244b GIT binary patch literal 958 zcmd5*Piqx15Kng3x_wXz74#-^s}I^d+v25&NX3H)9&EkzvM+CwZWpqfCCRqDM?Gl$ z5`F|fk+3JhFCm_sNoo7ggB~5o?CfOnn?JwgU~O&0P(FY7TD?vg`%XXClA!S%mj_ge zDPASVOeK=5RIyL&I8mA6_)XQFLpEL+HoOjn>)YZ?np(+VogX%;KYT|eM?4ZrfJxa4 zT>c@dz%E$emx;fx_T=~Uqy@IBuYA) zprsPgvADO1J#9kM`v6$g%vvMfjI&`>dkU0osfUcb!|Ktz(=VN~Zdm_~j&U-i2s5OO zuf8z1iX;CynS`dBbal5Kag5nEyL-NRvQtlD3sFys(zYjcCAzsI_Hts36w60E<9Sk& zeJvCbInB@r44LDLZ?TQHI`ppn2lDXM@8<>;b6z~#wcIq`P4 mD5Nn(adn6$7NeF<5<8BL5Bbx^s@~{l^jJJ)$&)P2*M9*SsRS7S literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/_funcs.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/_funcs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd07e7905fbc94f101541ded45c7e4b374c9d266 GIT binary patch literal 12101 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�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

Ig@c@o#{ef)Ln> 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/_next_gen.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/_next_gen.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fe41f737a60fc7ee0097aaa17767d26e2448251 GIT binary patch literal 23782 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/converters.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/converters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53095062d0055d43d22704195107b0329fd2fe58 GIT binary patch literal 3446 zcma)9O^+M586M7zq*+=1fa|1ini}k)K`g#F1YhbD`kkHN=ix{ppceMd0irmW9|C;ZeMdwq{N7&lUX+~_yP&3<#- z>bJ1g6fF^mjT65gh_-0Gbov{zA>5HGu88JK)^CfB*ud%);XZP@SI>Uk-p|M5JWFSM zs^w^!@?oAmmC8t^!}brj-Z}h%q3^QdR`f8-aub^*&p!FesCZ~{)%A+j;pa!6es=iB zqIF=GW`#dVCbGCLRpyyqB&IL&rXx! zDIbCf&S`0g!{88%(mnNNYX@k8P=Fk{ z;&9vjQhfe2PNxzvVebe-jv&$GOd+J$+v7VQggfE3B`*C*es$4)fu?Vvn2NYDZY~@aE!W>65h&^$7BHWk{dTb>e30hDIMpA8ihQ%N&bS+}VuHv6|u zq=`m}(k7b3Djr8Luq>LTnTz1_D#VNHQMBUbDC%FQgC#F}rrS^*FjUuwtA~6lm?>Ok ztlnK#5`hek3edfYrf;Hiu6G)NOG@0R`XSkvegqrK{CSSaE60$%-<~6j=qucF*RZ+! zf<0%JwxK?>G<=0u)2g*kjXP&A*w>Enu-kp%D)q{F>?}`~MY>qYnF2T8%b?mHF z&gLGx8^r&Hcs4G6EaQ+ON>0*vD63SdVvQfqc(1~c9!E4%uqvqmDVAS8;=NIcIK4}= zpgOxA@qeK>t`ghEIWnpWaYX(k)`kNF8aJjs}AYL9l;~T@R43P=nZ4n*CG)!>Cne<0_z- zy$N{>O%R-ta2%kN>xJb=%yqTbq^M0$Ci<6gqU8#(5PW^2RIc{;XE1*+lL@?{dcAc| zE&W2*RW>adl4=*39OveAjYFJ?+O<4Z^8a~QHS8Jal*5m z)es`15@{K3lqnY;+wdn)ctdsO7KL9s-{K1t2KcrrIe|U|eY8@swVLZV^`Z*I#*rpYKx2SXW%X*G)QmG~5Y?EtLH`$5icj<+fU&Z4|D({tLhs>TPD$m9; zGXPc(z`-p$ z!Kfz9q+U{HYm_`&o9?X6cEG~&xI~x(yzO$ZB2Brla_5M4EN>mHGTzMcC1L&ke6+rC zd-d4%LY|B0S%=deKY;O3zHy{Co{6XQD*b42wYw9(S7A*zI4XRyprWd(@L;im%?dZq z3bvytl8(B;LD8^U6>LK_D@P-%)2Q~)W;tnw0jXWdy;3LcDeF-_%1l+d==^u56C Ruv@;%=&$Jqzq$6i{{bMtmlOa1 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/exceptions.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d514e149d0e19d18ad5b7b38b47a690d153d0f6 GIT binary patch literal 3284 zcmb_eO>Y}T7@qxdY{yBQkCv7SF+xbimFhI9pimXmP$={gKAKj-C9EeqV`pK#>(0zJ zjg<>(rC#_0+~A1BAK;fD?UfT3egG%lcXrpYLxbdqwLCk|%q;{o<~1#m@p zfGdFKcolHf;5ooGUI$zkRhX{pYnaI&!bqdcG?U}Lla4<+U+lvGZ zW2IRf2%1RBw3gvsss-I=PXyf)BE~T>7;3?(PGH1rGe~&Y3k7f24ZNr6AjDG?)%*Av zd>z7eNso5BF&hZ3(_ti3w@dd9X{y4wZx$+;q5?mp1ECb_=ex6*Q%(w()d)I@u11^JRsZdca2=(sOuH_g24ZL|pgla4Xw+5ss|qyrnrpk38Jn^Q z3+9YPG@(;kL~akDeJ5MZwSTWrZ*B!&Pg%jS?)RB`skZ3}P5)cw8}E!|zTI*q-dKW@ z5{U$44V$qr^4I&_pae($igCvbOT7EACH)6(r3mNErrj6gF zN`SAc@4%;fi9FSvK((8NJI%rz?eX#ibHp<-UjwdNv7vALHK&}%hAkQ=@zs*G2@w#h z3f&GNU;w8uhDZg>%T=Xp{%@koKx}=2DB_ujp8rVnSQ_cAND9Ue?+cw%{h_d8o=+bW z#AtS~4?!7b!nh2h5Q!sHH858v!!?xxJ~I0q$6YRhL^Azfs=sk2uU-KO+!#xwA`#Cd zk&6%FB9sa~HvL>Ej|-vXIzI^YKJ9i{suLewAly^$@5od@ia~Q=VE!l+T$ZGe0;oP5 z3XoBmX-~I>8|~|7F#1(sdV9>=lZaT$&Ub5GipOaPS_jUtH~>e_H#U0}`SNt~@1Duy*MRJ&WAYV=c#6CO0|cwIx8OCI zt6q?v#cl39uXbGSa_>3mcrS=cIu%pFG$9h)VNryIN^S*D3oFRgn{!1!U^FP!o$wa4 z6Goq~C@tgzJ_1Hywkbb3T^{d^YCB+wh78sl;KkbaB^J1uXKo3p+f^d!nK5}0CZH&+`M$Ax zSZcDV$)Oiu?ko74GJ#ktR>c}!JSnkuc}9Q*13vi1ta}Fu;K7<4k#DVMR(?@CbD%6T zr?)KmD$GwLa6C7I5(rlK{x<+j{wCJw!b{FIi&}FptqJh%@-^ITp`aFsC@Se8M>zZv zE;3ZlLGKIr8>-ccYd1WJW81A|tkrrc+CO}ays`@TI@p9nO=XMIVZ_u?rrMC0k+b?k zv<#yTiHS;L5YHN4rm+qO#W+SWxzwx{ JzZ$%2{{VNl3DW=o literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/filters.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/filters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..abbefec46089f4b7f7235e7f4631cbef7cc5ce79 GIT binary patch literal 2324 zcmds2&2HQ_5GJMlkDa(p+M+)Qh#u1J!qGZ$doc{7+s!$L7H9#tftD7zYsFkiA*ncC zYz~DD*nWfd5&A?0bnU6HkW*)A~ow1W1w8Q1i{q_fcQ3uXhNvUw-;+;x`HT z9T&^y!Q?CGW)lWM_KBdvQ*`R>dz1)Y)XvDhFY2NJ&zfk87Ch^s{VnNsW`oW!olet4 zov_@UxvvkZxW1Y@q zVx%1zTt|u~3f>72ELmklSEar4d(VFQ`nf5ry`_P2n4>yPn3f z=mri5z8qROYs0VseSzn?{xpX5Z~op{`9mUAMTJET^Y8}7;>ML6p)3prLh2iIgX(pd zMYzO<&M|6?(R>O66d8#3qkl;+y-RXV&gr=~_E9fqt(SC8q2NA02i`i$47KD|0^!Q4 zF$-9j(+XEAJvOX|=z2lNSr7EY?6?`S72mMWRc!1JNSI9qdEa!TG(n}5C*9QnJoG&t zvMGy`NaaEXY{(OKfC$QOaF*~Xd<&!rFDiyF04xNu`s5H`@&hGTJLqJq$P9iCsVn0`?p(lQ>PHL!L~e*x6wZ zw}S`478^v7%q*rQP9}yO$Mz8NER}FEE=7wK#D-7ox1pD!rBBHPJ!)hh&B;@G;gz!s za@1IgwjGADmQAazoQbW;NR3f~GejUxc4(-s{ zhszRG5?xw$OAZ3(*Wir4g9Gxf>+5%M?nH-SXw+NLT%3Ck7Nvt*H@%If#`QIM{PSCR zEK;~Ad%YyJJt!OU`9GtxeDVLL^Y)6)D+Vu^&A0(MXSuDU;iMG(EwS%H(dYk2?6u|p zNZ$lIjeiYb8D7>JZ_vLI%w6q{WvxXC!T}h*#^YseDjqK_-{A54=;m!aUYy&i9F#o% z0M?JYjiMQbB8@E6Mr28+p%i1wrquG^f{tEKlX)1Ch_wbKpFqoRR=C^LNKK>J^ Ccq9@4 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/setters.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/setters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5a577071f54027db2cc47ab5ef90d63a46114ef GIT binary patch literal 1553 zcma)6-HzNe6tBFq~wBQ|{Gt>}4KB->>~~kOkleyz`o59Uk&7j3JMB55_K!`3{Vc=q*VW z^ZqeOcIThO2XZ`?P5pvRwczYb$_vd#QZd=&TA0EZmB#;2h?!8^%}d#gs#9=p94a{% z&DXGAolK4RPAREM*yb97^`Up6>pd{Pkr73}ucHNRDTMatqnJVaVcM{wuGs*B8KLxm z6%A)fn5k-*ITIUqR@76$Y# zv+nQ1s6PhNdJF&g&ELtlAVZuFxYz>;F&zMEG|&G~>x|Qcd>V4RyU=-}^$JetEYV;zioo;rd8A zd13p{R56(dp2Hb&9g#+02o1cL?s@ZDIGsMMWm(kvQTpa)7clV@W{~QmK?Dh1P3(Yg z13ZnM#wF72M`{QwddDE=IY`|4`a}2SJAu8WPeFS3OFwT@aIpHB!Ka#msueGcD*-mx>O5f8h*gH2 z75b{FcbNDJVQ25qdK2c4k{x*WaxTj}x5VjbWAVHc69W&9c3JGo z$fc%}!kx3BJUJJo$vQ_*@+VK<2#w+>m*3GtsF`Uk9-(Fq00gIfKe`_Epnvcmyhm&1 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/__pycache__/validators.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attr/__pycache__/validators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ff32112300c7b6f844efd926316b7f8057bfeeb GIT binary patch literal 21153 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attr/_cmp.py b/.venv/lib/python3.7/site-packages/attr/_cmp.py new file mode 100644 index 0000000..f367bb3 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_cmp.py @@ -0,0 +1,160 @@ +# SPDX-License-Identifier: MIT + + +import functools +import types + +from ._make import _make_ne + + +_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} + + +def cmp_using( + eq=None, + lt=None, + le=None, + gt=None, + ge=None, + require_same_type=True, + class_name="Comparable", +): + """ + Create a class that can be passed into `attrs.field`'s ``eq``, ``order``, + and ``cmp`` arguments to customize field comparison. + + The resulting class will have a full set of ordering methods if at least + one of ``{lt, le, gt, ge}`` and ``eq`` are provided. + + Args: + eq (typing.Callable | None): + Callable used to evaluate equality of two objects. + + lt (typing.Callable | None): + Callable used to evaluate whether one object is less than another + object. + + le (typing.Callable | None): + Callable used to evaluate whether one object is less than or equal + to another object. + + gt (typing.Callable | None): + Callable used to evaluate whether one object is greater than + another object. + + ge (typing.Callable | None): + Callable used to evaluate whether one object is greater than or + equal to another object. + + require_same_type (bool): + When `True`, equality and ordering methods will return + `NotImplemented` if objects are not of the same type. + + class_name (str | None): Name of class. Defaults to "Comparable". + + See `comparison` for more details. + + .. versionadded:: 21.1.0 + """ + + body = { + "__slots__": ["value"], + "__init__": _make_init(), + "_requirements": [], + "_is_comparable_to": _is_comparable_to, + } + + # Add operations. + num_order_functions = 0 + has_eq_function = False + + if eq is not None: + has_eq_function = True + body["__eq__"] = _make_operator("eq", eq) + body["__ne__"] = _make_ne() + + if lt is not None: + num_order_functions += 1 + body["__lt__"] = _make_operator("lt", lt) + + if le is not None: + num_order_functions += 1 + body["__le__"] = _make_operator("le", le) + + if gt is not None: + num_order_functions += 1 + body["__gt__"] = _make_operator("gt", gt) + + if ge is not None: + num_order_functions += 1 + body["__ge__"] = _make_operator("ge", ge) + + type_ = types.new_class( + class_name, (object,), {}, lambda ns: ns.update(body) + ) + + # Add same type requirement. + if require_same_type: + type_._requirements.append(_check_same_type) + + # Add total ordering if at least one operation was defined. + if 0 < num_order_functions < 4: + if not has_eq_function: + # functools.total_ordering requires __eq__ to be defined, + # so raise early error here to keep a nice stack. + msg = "eq must be define is order to complete ordering from lt, le, gt, ge." + raise ValueError(msg) + type_ = functools.total_ordering(type_) + + return type_ + + +def _make_init(): + """ + Create __init__ method. + """ + + def __init__(self, value): + """ + Initialize object with *value*. + """ + self.value = value + + return __init__ + + +def _make_operator(name, func): + """ + Create operator method. + """ + + def method(self, other): + if not self._is_comparable_to(other): + return NotImplemented + + result = func(self.value, other.value) + if result is NotImplemented: + return NotImplemented + + return result + + method.__name__ = f"__{name}__" + method.__doc__ = ( + f"Return a {_operation_names[name]} b. Computed by attrs." + ) + + return method + + +def _is_comparable_to(self, other): + """ + Check whether `other` is comparable to `self`. + """ + return all(func(self, other) for func in self._requirements) + + +def _check_same_type(self, other): + """ + Return True if *self* and *other* are of the same type, False otherwise. + """ + return other.value.__class__ is self.value.__class__ diff --git a/.venv/lib/python3.7/site-packages/attr/_cmp.pyi b/.venv/lib/python3.7/site-packages/attr/_cmp.pyi new file mode 100644 index 0000000..cc7893b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_cmp.pyi @@ -0,0 +1,13 @@ +from typing import Any, Callable + +_CompareWithType = Callable[[Any, Any], bool] + +def cmp_using( + eq: _CompareWithType | None = ..., + lt: _CompareWithType | None = ..., + le: _CompareWithType | None = ..., + gt: _CompareWithType | None = ..., + ge: _CompareWithType | None = ..., + require_same_type: bool = ..., + class_name: str = ..., +) -> type: ... diff --git a/.venv/lib/python3.7/site-packages/attr/_compat.py b/.venv/lib/python3.7/site-packages/attr/_compat.py new file mode 100644 index 0000000..104eeb0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_compat.py @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: MIT + +import inspect +import platform +import sys +import threading + +from collections.abc import Mapping, Sequence # noqa: F401 +from typing import _GenericAlias + + +PYPY = platform.python_implementation() == "PyPy" +PY_3_8_PLUS = sys.version_info[:2] >= (3, 8) +PY_3_9_PLUS = sys.version_info[:2] >= (3, 9) +PY_3_10_PLUS = sys.version_info[:2] >= (3, 10) +PY_3_11_PLUS = sys.version_info[:2] >= (3, 11) +PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) +PY_3_13_PLUS = sys.version_info[:2] >= (3, 13) +PY_3_14_PLUS = sys.version_info[:2] >= (3, 14) + + +if sys.version_info < (3, 8): + try: + from typing_extensions import Protocol + except ImportError: # pragma: no cover + Protocol = object +else: + from typing import Protocol # noqa: F401 + +if PY_3_14_PLUS: # pragma: no cover + import annotationlib + + _get_annotations = annotationlib.get_annotations + +else: + + def _get_annotations(cls): + """ + Get annotations for *cls*. + """ + return cls.__dict__.get("__annotations__", {}) + + +class _AnnotationExtractor: + """ + Extract type annotations from a callable, returning None whenever there + is none. + """ + + __slots__ = ["sig"] + + def __init__(self, callable): + try: + self.sig = inspect.signature(callable) + except (ValueError, TypeError): # inspect failed + self.sig = None + + def get_first_param_type(self): + """ + Return the type annotation of the first argument if it's not empty. + """ + if not self.sig: + return None + + params = list(self.sig.parameters.values()) + if params and params[0].annotation is not inspect.Parameter.empty: + return params[0].annotation + + return None + + def get_return_type(self): + """ + Return the return type if it's not empty. + """ + if ( + self.sig + and self.sig.return_annotation is not inspect.Signature.empty + ): + return self.sig.return_annotation + + return None + + +# Thread-local global to track attrs instances which are already being repr'd. +# This is needed because there is no other (thread-safe) way to pass info +# about the instances that are already being repr'd through the call stack +# in order to ensure we don't perform infinite recursion. +# +# For instance, if an instance contains a dict which contains that instance, +# we need to know that we're already repr'ing the outside instance from within +# the dict's repr() call. +# +# This lives here rather than in _make.py so that the functions in _make.py +# don't have a direct reference to the thread-local in their globals dict. +# If they have such a reference, it breaks cloudpickle. +repr_context = threading.local() + + +def get_generic_base(cl): + """If this is a generic class (A[str]), return the generic base for it.""" + if cl.__class__ is _GenericAlias: + return cl.__origin__ + return None diff --git a/.venv/lib/python3.7/site-packages/attr/_config.py b/.venv/lib/python3.7/site-packages/attr/_config.py new file mode 100644 index 0000000..9c245b1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_config.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: MIT + +__all__ = ["set_run_validators", "get_run_validators"] + +_run_validators = True + + +def set_run_validators(run): + """ + Set whether or not validators are run. By default, they are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.set_disabled()` + instead. + """ + if not isinstance(run, bool): + msg = "'run' must be bool." + raise TypeError(msg) + global _run_validators + _run_validators = run + + +def get_run_validators(): + """ + Return whether or not validators are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.get_disabled()` + instead. + """ + return _run_validators diff --git a/.venv/lib/python3.7/site-packages/attr/_funcs.py b/.venv/lib/python3.7/site-packages/attr/_funcs.py new file mode 100644 index 0000000..355cef4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_funcs.py @@ -0,0 +1,522 @@ +# SPDX-License-Identifier: MIT + + +import copy + +from ._compat import PY_3_9_PLUS, get_generic_base +from ._make import _OBJ_SETATTR, NOTHING, fields +from .exceptions import AttrsAttributeNotFoundError + + +def asdict( + inst, + recurse=True, + filter=None, + dict_factory=dict, + retain_collection_types=False, + value_serializer=None, +): + """ + Return the *attrs* attribute values of *inst* as a dict. + + Optionally recurse into other *attrs*-decorated classes. + + Args: + inst: Instance of an *attrs*-decorated class. + + recurse (bool): Recurse into classes that are also *attrs*-decorated. + + filter (~typing.Callable): + A callable whose return code determines whether an attribute or + element is included (`True`) or dropped (`False`). Is called with + the `attrs.Attribute` as the first argument and the value as the + second argument. + + dict_factory (~typing.Callable): + A callable to produce dictionaries from. For example, to produce + ordered dictionaries instead of normal Python dictionaries, pass in + ``collections.OrderedDict``. + + retain_collection_types (bool): + Do not convert to `list` when encountering an attribute whose type + is `tuple` or `set`. Only meaningful if *recurse* is `True`. + + value_serializer (typing.Callable | None): + A hook that is called for every attribute or dict key/value. It + receives the current instance, field and value and must return the + (updated) value. The hook is run *after* the optional *filter* has + been applied. + + Returns: + Return type of *dict_factory*. + + Raises: + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + .. versionadded:: 16.0.0 *dict_factory* + .. versionadded:: 16.1.0 *retain_collection_types* + .. versionadded:: 20.3.0 *value_serializer* + .. versionadded:: 21.3.0 + If a dict has a collection for a key, it is serialized as a tuple. + """ + attrs = fields(inst.__class__) + rv = dict_factory() + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + + if value_serializer is not None: + v = value_serializer(inst, a, v) + + if recurse is True: + if has(v.__class__): + rv[a.name] = asdict( + v, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain_collection_types is True else list + items = [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in v + ] + try: + rv[a.name] = cf(items) + except TypeError: + if not issubclass(cf, tuple): + raise + # Workaround for TypeError: cf.__new__() missing 1 required + # positional argument (which appears, for a namedturle) + rv[a.name] = cf(*items) + elif isinstance(v, dict): + df = dict_factory + rv[a.name] = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in v.items() + ) + else: + rv[a.name] = v + else: + rv[a.name] = v + return rv + + +def _asdict_anything( + val, + is_key, + filter, + dict_factory, + retain_collection_types, + value_serializer, +): + """ + ``asdict`` only works on attrs instances, this works on anything. + """ + if getattr(val.__class__, "__attrs_attrs__", None) is not None: + # Attrs class. + rv = asdict( + val, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(val, (tuple, list, set, frozenset)): + if retain_collection_types is True: + cf = val.__class__ + elif is_key: + cf = tuple + else: + cf = list + + rv = cf( + [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in val + ] + ) + elif isinstance(val, dict): + df = dict_factory + rv = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in val.items() + ) + else: + rv = val + if value_serializer is not None: + rv = value_serializer(None, None, rv) + + return rv + + +def astuple( + inst, + recurse=True, + filter=None, + tuple_factory=tuple, + retain_collection_types=False, +): + """ + Return the *attrs* attribute values of *inst* as a tuple. + + Optionally recurse into other *attrs*-decorated classes. + + Args: + inst: Instance of an *attrs*-decorated class. + + recurse (bool): + Recurse into classes that are also *attrs*-decorated. + + filter (~typing.Callable): + A callable whose return code determines whether an attribute or + element is included (`True`) or dropped (`False`). Is called with + the `attrs.Attribute` as the first argument and the value as the + second argument. + + tuple_factory (~typing.Callable): + A callable to produce tuples from. For example, to produce lists + instead of tuples. + + retain_collection_types (bool): + Do not convert to `list` or `dict` when encountering an attribute + which type is `tuple`, `dict` or `set`. Only meaningful if + *recurse* is `True`. + + Returns: + Return type of *tuple_factory* + + Raises: + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + .. versionadded:: 16.2.0 + """ + attrs = fields(inst.__class__) + rv = [] + retain = retain_collection_types # Very long. :/ + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv.append( + astuple( + v, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain is True else list + items = [ + ( + astuple( + j, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(j.__class__) + else j + ) + for j in v + ] + try: + rv.append(cf(items)) + except TypeError: + if not issubclass(cf, tuple): + raise + # Workaround for TypeError: cf.__new__() missing 1 required + # positional argument (which appears, for a namedturle) + rv.append(cf(*items)) + elif isinstance(v, dict): + df = v.__class__ if retain is True else dict + rv.append( + df( + ( + ( + astuple( + kk, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(kk.__class__) + else kk + ), + ( + astuple( + vv, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(vv.__class__) + else vv + ), + ) + for kk, vv in v.items() + ) + ) + else: + rv.append(v) + else: + rv.append(v) + + return rv if tuple_factory is list else tuple_factory(rv) + + +def has(cls): + """ + Check whether *cls* is a class with *attrs* attributes. + + Args: + cls (type): Class to introspect. + + Raises: + TypeError: If *cls* is not a class. + + Returns: + bool: + """ + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is not None: + return True + + # No attrs, maybe it's a specialized generic (A[str])? + generic_base = get_generic_base(cls) + if generic_base is not None: + generic_attrs = getattr(generic_base, "__attrs_attrs__", None) + if generic_attrs is not None: + # Stick it on here for speed next time. + cls.__attrs_attrs__ = generic_attrs + return generic_attrs is not None + return False + + +def assoc(inst, **changes): + """ + Copy *inst* and apply *changes*. + + This is different from `evolve` that applies the changes to the arguments + that create the new instance. + + `evolve`'s behavior is preferable, but there are `edge cases`_ where it + doesn't work. Therefore `assoc` is deprecated, but will not be removed. + + .. _`edge cases`: https://github.com/python-attrs/attrs/issues/251 + + Args: + inst: Instance of a class with *attrs* attributes. + + changes: Keyword changes in the new copy. + + Returns: + A copy of inst with *changes* incorporated. + + Raises: + attrs.exceptions.AttrsAttributeNotFoundError: + If *attr_name* couldn't be found on *cls*. + + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + .. deprecated:: 17.1.0 + Use `attrs.evolve` instead if you can. This function will not be + removed du to the slightly different approach compared to + `attrs.evolve`, though. + """ + new = copy.copy(inst) + attrs = fields(inst.__class__) + for k, v in changes.items(): + a = getattr(attrs, k, NOTHING) + if a is NOTHING: + msg = f"{k} is not an attrs attribute on {new.__class__}." + raise AttrsAttributeNotFoundError(msg) + _OBJ_SETATTR(new, k, v) + return new + + +def evolve(*args, **changes): + """ + Create a new instance, based on the first positional argument with + *changes* applied. + + Args: + + inst: + Instance of a class with *attrs* attributes. *inst* must be passed + as a positional argument. + + changes: + Keyword changes in the new copy. + + Returns: + A copy of inst with *changes* incorporated. + + Raises: + TypeError: + If *attr_name* couldn't be found in the class ``__init__``. + + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + .. versionadded:: 17.1.0 + .. deprecated:: 23.1.0 + It is now deprecated to pass the instance using the keyword argument + *inst*. It will raise a warning until at least April 2024, after which + it will become an error. Always pass the instance as a positional + argument. + .. versionchanged:: 24.1.0 + *inst* can't be passed as a keyword argument anymore. + """ + try: + (inst,) = args + except ValueError: + msg = ( + f"evolve() takes 1 positional argument, but {len(args)} were given" + ) + raise TypeError(msg) from None + + cls = inst.__class__ + attrs = fields(cls) + for a in attrs: + if not a.init: + continue + attr_name = a.name # To deal with private attributes. + init_name = a.alias + if init_name not in changes: + changes[init_name] = getattr(inst, attr_name) + + return cls(**changes) + + +def resolve_types( + cls, globalns=None, localns=None, attribs=None, include_extras=True +): + """ + Resolve any strings and forward annotations in type annotations. + + This is only required if you need concrete types in :class:`Attribute`'s + *type* field. In other words, you don't need to resolve your types if you + only use them for static type checking. + + With no arguments, names will be looked up in the module in which the class + was created. If this is not what you want, for example, if the name only + exists inside a method, you may pass *globalns* or *localns* to specify + other dictionaries in which to look up these names. See the docs of + `typing.get_type_hints` for more details. + + Args: + cls (type): Class to resolve. + + globalns (dict | None): Dictionary containing global variables. + + localns (dict | None): Dictionary containing local variables. + + attribs (list | None): + List of attribs for the given class. This is necessary when calling + from inside a ``field_transformer`` since *cls* is not an *attrs* + class yet. + + include_extras (bool): + Resolve more accurately, if possible. Pass ``include_extras`` to + ``typing.get_hints``, if supported by the typing module. On + supported Python versions (3.9+), this resolves the types more + accurately. + + Raises: + TypeError: If *cls* is not a class. + + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class and you didn't pass any attribs. + + NameError: If types cannot be resolved because of missing variables. + + Returns: + *cls* so you can use this function also as a class decorator. Please + note that you have to apply it **after** `attrs.define`. That means the + decorator has to come in the line **before** `attrs.define`. + + .. versionadded:: 20.1.0 + .. versionadded:: 21.1.0 *attribs* + .. versionadded:: 23.1.0 *include_extras* + """ + # Since calling get_type_hints is expensive we cache whether we've + # done it already. + if getattr(cls, "__attrs_types_resolved__", None) != cls: + import typing + + kwargs = {"globalns": globalns, "localns": localns} + + if PY_3_9_PLUS: + kwargs["include_extras"] = include_extras + + hints = typing.get_type_hints(cls, **kwargs) + for field in fields(cls) if attribs is None else attribs: + if field.name in hints: + # Since fields have been frozen we must work around it. + _OBJ_SETATTR(field, "type", hints[field.name]) + # We store the class we resolved so that subclasses know they haven't + # been resolved. + cls.__attrs_types_resolved__ = cls + + # Return the class so you can use it as a decorator too. + return cls diff --git a/.venv/lib/python3.7/site-packages/attr/_make.py b/.venv/lib/python3.7/site-packages/attr/_make.py new file mode 100644 index 0000000..bf00c5f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_make.py @@ -0,0 +1,2960 @@ +# SPDX-License-Identifier: MIT + +from __future__ import annotations + +import abc +import contextlib +import copy +import enum +import functools +import inspect +import itertools +import linecache +import sys +import types +import typing + +from operator import itemgetter + +# We need to import _compat itself in addition to the _compat members to avoid +# having the thread-local in the globals here. +from . import _compat, _config, setters +from ._compat import ( + PY_3_8_PLUS, + PY_3_10_PLUS, + PY_3_11_PLUS, + _AnnotationExtractor, + _get_annotations, + get_generic_base, +) +from .exceptions import ( + DefaultAlreadySetError, + FrozenInstanceError, + NotAnAttrsClassError, + UnannotatedAttributeError, +) + + +# This is used at least twice, so cache it here. +_OBJ_SETATTR = object.__setattr__ +_INIT_FACTORY_PAT = "__attr_factory_%s" +_CLASSVAR_PREFIXES = ( + "typing.ClassVar", + "t.ClassVar", + "ClassVar", + "typing_extensions.ClassVar", +) +# we don't use a double-underscore prefix because that triggers +# name mangling when trying to create a slot for the field +# (when slots=True) +_HASH_CACHE_FIELD = "_attrs_cached_hash" + +_EMPTY_METADATA_SINGLETON = types.MappingProxyType({}) + +# Unique object for unequivocal getattr() defaults. +_SENTINEL = object() + +_DEFAULT_ON_SETATTR = setters.pipe(setters.convert, setters.validate) + + +class _Nothing(enum.Enum): + """ + Sentinel to indicate the lack of a value when `None` is ambiguous. + + If extending attrs, you can use ``typing.Literal[NOTHING]`` to show + that a value may be ``NOTHING``. + + .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. + .. versionchanged:: 22.2.0 ``NOTHING`` is now an ``enum.Enum`` variant. + """ + + NOTHING = enum.auto() + + def __repr__(self): + return "NOTHING" + + def __bool__(self): + return False + + +NOTHING = _Nothing.NOTHING +""" +Sentinel to indicate the lack of a value when `None` is ambiguous. +""" + + +class _CacheHashWrapper(int): + """ + An integer subclass that pickles / copies as None + + This is used for non-slots classes with ``cache_hash=True``, to avoid + serializing a potentially (even likely) invalid hash value. Since `None` + is the default value for uncalculated hashes, whenever this is copied, + the copy's value for the hash should automatically reset. + + See GH #613 for more details. + """ + + def __reduce__(self, _none_constructor=type(None), _args=()): # noqa: B008 + return _none_constructor, _args + + +def attrib( + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, + alias=None, +): + """ + Create a new field / attribute on a class. + + Identical to `attrs.field`, except it's not keyword-only. + + Consider using `attrs.field` in new code (``attr.ib`` will *never* go away, + though). + + .. warning:: + + Does **nothing** unless the class is also decorated with + `attr.s` (or similar)! + + + .. versionadded:: 15.2.0 *convert* + .. versionadded:: 16.3.0 *metadata* + .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. + .. versionchanged:: 17.1.0 + *hash* is `None` and therefore mirrors *eq* by default. + .. versionadded:: 17.3.0 *type* + .. deprecated:: 17.4.0 *convert* + .. versionadded:: 17.4.0 + *converter* as a replacement for the deprecated *convert* to achieve + consistency with other noun-based arguments. + .. versionadded:: 18.1.0 + ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. + .. versionadded:: 18.2.0 *kw_only* + .. versionchanged:: 19.2.0 *convert* keyword argument removed. + .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 + .. versionchanged:: 21.1.0 + *eq*, *order*, and *cmp* also accept a custom callable + .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 22.2.0 *alias* + """ + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq, order, True + ) + + if hash is not None and hash is not True and hash is not False: + msg = "Invalid value for hash. Must be True, False, or None." + raise TypeError(msg) + + if factory is not None: + if default is not NOTHING: + msg = ( + "The `default` and `factory` arguments are mutually exclusive." + ) + raise ValueError(msg) + if not callable(factory): + msg = "The `factory` argument must be a callable." + raise ValueError(msg) + default = Factory(factory) + + if metadata is None: + metadata = {} + + # Apply syntactic sugar by auto-wrapping. + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + if validator and isinstance(validator, (list, tuple)): + validator = and_(*validator) + + if converter and isinstance(converter, (list, tuple)): + converter = pipe(*converter) + + return _CountingAttr( + default=default, + validator=validator, + repr=repr, + cmp=None, + hash=hash, + init=init, + converter=converter, + metadata=metadata, + type=type, + kw_only=kw_only, + eq=eq, + eq_key=eq_key, + order=order, + order_key=order_key, + on_setattr=on_setattr, + alias=alias, + ) + + +def _compile_and_eval(script, globs, locs=None, filename=""): + """ + Evaluate the script with the given global (globs) and local (locs) + variables. + """ + bytecode = compile(script, filename, "exec") + eval(bytecode, globs, locs) + + +def _make_method(name, script, filename, globs, locals=None): + """ + Create the method with the script given and return the method object. + """ + locs = {} if locals is None else locals + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + count = 1 + base_filename = filename + while True: + linecache_tuple = ( + len(script), + None, + script.splitlines(True), + filename, + ) + old_val = linecache.cache.setdefault(filename, linecache_tuple) + if old_val == linecache_tuple: + break + + filename = f"{base_filename[:-1]}-{count}>" + count += 1 + + _compile_and_eval(script, globs, locs, filename) + + return locs[name] + + +def _make_attr_tuple_class(cls_name, attr_names): + """ + Create a tuple subclass to hold `Attribute`s for an `attrs` class. + + The subclass is a bare tuple with properties for names. + + class MyClassAttributes(tuple): + __slots__ = () + x = property(itemgetter(0)) + """ + attr_class_name = f"{cls_name}Attributes" + attr_class_template = [ + f"class {attr_class_name}(tuple):", + " __slots__ = ()", + ] + if attr_names: + for i, attr_name in enumerate(attr_names): + attr_class_template.append( + f" {attr_name} = _attrs_property(_attrs_itemgetter({i}))" + ) + else: + attr_class_template.append(" pass") + globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} + _compile_and_eval("\n".join(attr_class_template), globs) + return globs[attr_class_name] + + +# Tuple class for extracted attributes from a class definition. +# `base_attrs` is a subset of `attrs`. +_Attributes = _make_attr_tuple_class( + "_Attributes", + [ + # all attributes to build dunder methods for + "attrs", + # attributes that have been inherited + "base_attrs", + # map inherited attributes to their originating classes + "base_attrs_map", + ], +) + + +def _is_class_var(annot): + """ + Check whether *annot* is a typing.ClassVar. + + The string comparison hack is used to avoid evaluating all string + annotations which would put attrs-based classes at a performance + disadvantage compared to plain old classes. + """ + annot = str(annot) + + # Annotation can be quoted. + if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): + annot = annot[1:-1] + + return annot.startswith(_CLASSVAR_PREFIXES) + + +def _has_own_attribute(cls, attrib_name): + """ + Check whether *cls* defines *attrib_name* (and doesn't just inherit it). + """ + return attrib_name in cls.__dict__ + + +def _collect_base_attrs(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in reversed(cls.__mro__[1:-1]): + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.inherited or a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) # noqa: PLW2901 + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + # For each name, only keep the freshest definition i.e. the furthest at the + # back. base_attr_map is fine because it gets overwritten with every new + # instance. + filtered = [] + seen = set() + for a in reversed(base_attrs): + if a.name in seen: + continue + filtered.insert(0, a) + seen.add(a.name) + + return filtered, base_attr_map + + +def _collect_base_attrs_broken(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + + N.B. *taken_attr_names* will be mutated. + + Adhere to the old incorrect behavior. + + Notably it collects from the front and considers inherited attributes which + leads to the buggy behavior reported in #428. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in cls.__mro__[1:-1]: + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) # noqa: PLW2901 + taken_attr_names.add(a.name) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + return base_attrs, base_attr_map + + +def _transform_attrs( + cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer +): + """ + Transform all `_CountingAttr`s on a class into `Attribute`s. + + If *these* is passed, use that and don't look for them on the class. + + If *collect_by_mro* is True, collect them in the correct MRO order, + otherwise use the old -- incorrect -- order. See #428. + + Return an `_Attributes`. + """ + cd = cls.__dict__ + anns = _get_annotations(cls) + + if these is not None: + ca_list = list(these.items()) + elif auto_attribs is True: + ca_names = { + name + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + } + ca_list = [] + annot_names = set() + for attr_name, type in anns.items(): + if _is_class_var(type): + continue + annot_names.add(attr_name) + a = cd.get(attr_name, NOTHING) + + if not isinstance(a, _CountingAttr): + a = attrib() if a is NOTHING else attrib(default=a) + ca_list.append((attr_name, a)) + + unannotated = ca_names - annot_names + if len(unannotated) > 0: + raise UnannotatedAttributeError( + "The following `attr.ib`s lack a type annotation: " + + ", ".join( + sorted(unannotated, key=lambda n: cd.get(n).counter) + ) + + "." + ) + else: + ca_list = sorted( + ( + (name, attr) + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + ), + key=lambda e: e[1].counter, + ) + + own_attrs = [ + Attribute.from_counting_attr( + name=attr_name, ca=ca, type=anns.get(attr_name) + ) + for attr_name, ca in ca_list + ] + + if collect_by_mro: + base_attrs, base_attr_map = _collect_base_attrs( + cls, {a.name for a in own_attrs} + ) + else: + base_attrs, base_attr_map = _collect_base_attrs_broken( + cls, {a.name for a in own_attrs} + ) + + if kw_only: + own_attrs = [a.evolve(kw_only=True) for a in own_attrs] + base_attrs = [a.evolve(kw_only=True) for a in base_attrs] + + attrs = base_attrs + own_attrs + + # Mandatory vs non-mandatory attr order only matters when they are part of + # the __init__ signature and when they aren't kw_only (which are moved to + # the end and can be mandatory or non-mandatory in any order, as they will + # be specified as keyword args anyway). Check the order of those attrs: + had_default = False + for a in (a for a in attrs if a.init is not False and a.kw_only is False): + if had_default is True and a.default is NOTHING: + msg = f"No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: {a!r}" + raise ValueError(msg) + + if had_default is False and a.default is not NOTHING: + had_default = True + + if field_transformer is not None: + attrs = field_transformer(cls, attrs) + + # Resolve default field alias after executing field_transformer. + # This allows field_transformer to differentiate between explicit vs + # default aliases and supply their own defaults. + attrs = [ + a.evolve(alias=_default_init_alias_for(a.name)) if not a.alias else a + for a in attrs + ] + + # Create AttrsClass *after* applying the field_transformer since it may + # add or remove attributes! + attr_names = [a.name for a in attrs] + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) + + return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map)) + + +def _make_cached_property_getattr(cached_properties, original_getattr, cls): + lines = [ + # Wrapped to get `__class__` into closure cell for super() + # (It will be replaced with the newly constructed class after construction). + "def wrapper(_cls):", + " __class__ = _cls", + " def __getattr__(self, item, cached_properties=cached_properties, original_getattr=original_getattr, _cached_setattr_get=_cached_setattr_get):", + " func = cached_properties.get(item)", + " if func is not None:", + " result = func(self)", + " _setter = _cached_setattr_get(self)", + " _setter(item, result)", + " return result", + ] + if original_getattr is not None: + lines.append( + " return original_getattr(self, item)", + ) + else: + lines.extend( + [ + " try:", + " return super().__getattribute__(item)", + " except AttributeError:", + " if not hasattr(super(), '__getattr__'):", + " raise", + " return super().__getattr__(item)", + " original_error = f\"'{self.__class__.__name__}' object has no attribute '{item}'\"", + " raise AttributeError(original_error)", + ] + ) + + lines.extend( + [ + " return __getattr__", + "__getattr__ = wrapper(_cls)", + ] + ) + + unique_filename = _generate_unique_filename(cls, "getattr") + + glob = { + "cached_properties": cached_properties, + "_cached_setattr_get": _OBJ_SETATTR.__get__, + "original_getattr": original_getattr, + } + + return _make_method( + "__getattr__", + "\n".join(lines), + unique_filename, + glob, + locals={ + "_cls": cls, + }, + ) + + +def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + if isinstance(self, BaseException) and name in ( + "__cause__", + "__context__", + "__traceback__", + ): + BaseException.__setattr__(self, name, value) + return + + raise FrozenInstanceError() + + +def _frozen_delattrs(self, name): + """ + Attached to frozen classes as __delattr__. + """ + raise FrozenInstanceError() + + +class _ClassBuilder: + """ + Iteratively build *one* class. + """ + + __slots__ = ( + "_attr_names", + "_attrs", + "_base_attr_map", + "_base_names", + "_cache_hash", + "_cls", + "_cls_dict", + "_delete_attribs", + "_frozen", + "_has_pre_init", + "_pre_init_has_args", + "_has_post_init", + "_is_exc", + "_on_setattr", + "_slots", + "_weakref_slot", + "_wrote_own_setattr", + "_has_custom_setattr", + ) + + def __init__( + self, + cls, + these, + slots, + frozen, + weakref_slot, + getstate_setstate, + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_custom_setattr, + field_transformer, + ): + attrs, base_attrs, base_map = _transform_attrs( + cls, + these, + auto_attribs, + kw_only, + collect_by_mro, + field_transformer, + ) + + self._cls = cls + self._cls_dict = dict(cls.__dict__) if slots else {} + self._attrs = attrs + self._base_names = {a.name for a in base_attrs} + self._base_attr_map = base_map + self._attr_names = tuple(a.name for a in attrs) + self._slots = slots + self._frozen = frozen + self._weakref_slot = weakref_slot + self._cache_hash = cache_hash + self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) + self._pre_init_has_args = False + if self._has_pre_init: + # Check if the pre init method has more arguments than just `self` + # We want to pass arguments if pre init expects arguments + pre_init_func = cls.__attrs_pre_init__ + pre_init_signature = inspect.signature(pre_init_func) + self._pre_init_has_args = len(pre_init_signature.parameters) > 1 + self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) + self._delete_attribs = not bool(these) + self._is_exc = is_exc + self._on_setattr = on_setattr + + self._has_custom_setattr = has_custom_setattr + self._wrote_own_setattr = False + + self._cls_dict["__attrs_attrs__"] = self._attrs + + if frozen: + self._cls_dict["__setattr__"] = _frozen_setattrs + self._cls_dict["__delattr__"] = _frozen_delattrs + + self._wrote_own_setattr = True + elif on_setattr in ( + _DEFAULT_ON_SETATTR, + setters.validate, + setters.convert, + ): + has_validator = has_converter = False + for a in attrs: + if a.validator is not None: + has_validator = True + if a.converter is not None: + has_converter = True + + if has_validator and has_converter: + break + if ( + ( + on_setattr == _DEFAULT_ON_SETATTR + and not (has_validator or has_converter) + ) + or (on_setattr == setters.validate and not has_validator) + or (on_setattr == setters.convert and not has_converter) + ): + # If class-level on_setattr is set to convert + validate, but + # there's no field to convert or validate, pretend like there's + # no on_setattr. + self._on_setattr = None + + if getstate_setstate: + ( + self._cls_dict["__getstate__"], + self._cls_dict["__setstate__"], + ) = self._make_getstate_setstate() + + def __repr__(self): + return f"<_ClassBuilder(cls={self._cls.__name__})>" + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + cls = self._create_slots_class() + else: + cls = self._patch_original_class() + if PY_3_10_PLUS: + cls = abc.update_abstractmethods(cls) + + # The method gets only called if it's not inherited from a base class. + # _has_own_attribute does NOT work properly for classmethods. + if ( + getattr(cls, "__attrs_init_subclass__", None) + and "__attrs_init_subclass__" not in cls.__dict__ + ): + cls.__attrs_init_subclass__() + + return cls + + def _patch_original_class(self): + """ + Apply accumulated methods and return the class. + """ + cls = self._cls + base_names = self._base_names + + # Clean class of attribute definitions (`attr.ib()`s). + if self._delete_attribs: + for name in self._attr_names: + if ( + name not in base_names + and getattr(cls, name, _SENTINEL) is not _SENTINEL + ): + # An AttributeError can happen if a base class defines a + # class variable and we want to set an attribute with the + # same name by using only a type annotation. + with contextlib.suppress(AttributeError): + delattr(cls, name) + + # Attach our dunder methods. + for name, value in self._cls_dict.items(): + setattr(cls, name, value) + + # If we've inherited an attrs __setattr__ and don't write our own, + # reset it to object's. + if not self._wrote_own_setattr and getattr( + cls, "__attrs_own_setattr__", False + ): + cls.__attrs_own_setattr__ = False + + if not self._has_custom_setattr: + cls.__setattr__ = _OBJ_SETATTR + + return cls + + def _create_slots_class(self): + """ + Build and return a new class with a `__slots__` attribute. + """ + cd = { + k: v + for k, v in self._cls_dict.items() + if k not in (*tuple(self._attr_names), "__dict__", "__weakref__") + } + + # If our class doesn't have its own implementation of __setattr__ + # (either from the user or by us), check the bases, if one of them has + # an attrs-made __setattr__, that needs to be reset. We don't walk the + # MRO because we only care about our immediate base classes. + # XXX: This can be confused by subclassing a slotted attrs class with + # XXX: a non-attrs class and subclass the resulting class with an attrs + # XXX: class. See `test_slotted_confused` for details. For now that's + # XXX: OK with us. + if not self._wrote_own_setattr: + cd["__attrs_own_setattr__"] = False + + if not self._has_custom_setattr: + for base_cls in self._cls.__bases__: + if base_cls.__dict__.get("__attrs_own_setattr__", False): + cd["__setattr__"] = _OBJ_SETATTR + break + + # Traverse the MRO to collect existing slots + # and check for an existing __weakref__. + existing_slots = {} + weakref_inherited = False + for base_cls in self._cls.__mro__[1:-1]: + if base_cls.__dict__.get("__weakref__", None) is not None: + weakref_inherited = True + existing_slots.update( + { + name: getattr(base_cls, name) + for name in getattr(base_cls, "__slots__", []) + } + ) + + base_names = set(self._base_names) + + names = self._attr_names + if ( + self._weakref_slot + and "__weakref__" not in getattr(self._cls, "__slots__", ()) + and "__weakref__" not in names + and not weakref_inherited + ): + names += ("__weakref__",) + + if PY_3_8_PLUS: + cached_properties = { + name: cached_property.func + for name, cached_property in cd.items() + if isinstance(cached_property, functools.cached_property) + } + else: + # `functools.cached_property` was introduced in 3.8. + # So can't be used before this. + cached_properties = {} + + # Collect methods with a `__class__` reference that are shadowed in the new class. + # To know to update them. + additional_closure_functions_to_update = [] + if cached_properties: + class_annotations = _get_annotations(self._cls) + for name, func in cached_properties.items(): + # Add cached properties to names for slotting. + names += (name,) + # Clear out function from class to avoid clashing. + del cd[name] + additional_closure_functions_to_update.append(func) + annotation = inspect.signature(func).return_annotation + if annotation is not inspect.Parameter.empty: + class_annotations[name] = annotation + + original_getattr = cd.get("__getattr__") + if original_getattr is not None: + additional_closure_functions_to_update.append(original_getattr) + + cd["__getattr__"] = _make_cached_property_getattr( + cached_properties, original_getattr, self._cls + ) + + # We only add the names of attributes that aren't inherited. + # Setting __slots__ to inherited attributes wastes memory. + slot_names = [name for name in names if name not in base_names] + + # There are slots for attributes from current class + # that are defined in parent classes. + # As their descriptors may be overridden by a child class, + # we collect them here and update the class dict + reused_slots = { + slot: slot_descriptor + for slot, slot_descriptor in existing_slots.items() + if slot in slot_names + } + slot_names = [name for name in slot_names if name not in reused_slots] + cd.update(reused_slots) + if self._cache_hash: + slot_names.append(_HASH_CACHE_FIELD) + + cd["__slots__"] = tuple(slot_names) + + cd["__qualname__"] = self._cls.__qualname__ + + # Create new class based on old class and our methods. + cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) + + # The following is a fix for + # . + # If a method mentions `__class__` or uses the no-arg super(), the + # compiler will bake a reference to the class in the method itself + # as `method.__closure__`. Since we replace the class with a + # clone, we rewrite these references so it keeps working. + for item in itertools.chain( + cls.__dict__.values(), additional_closure_functions_to_update + ): + if isinstance(item, (classmethod, staticmethod)): + # Class- and staticmethods hide their functions inside. + # These might need to be rewritten as well. + closure_cells = getattr(item.__func__, "__closure__", None) + elif isinstance(item, property): + # Workaround for property `super()` shortcut (PY3-only). + # There is no universal way for other descriptors. + closure_cells = getattr(item.fget, "__closure__", None) + else: + closure_cells = getattr(item, "__closure__", None) + + if not closure_cells: # Catch None or the empty list. + continue + for cell in closure_cells: + try: + match = cell.cell_contents is self._cls + except ValueError: # noqa: PERF203 + # ValueError: Cell is empty + pass + else: + if match: + cell.cell_contents = cls + return cls + + def add_repr(self, ns): + self._cls_dict["__repr__"] = self._add_method_dunders( + _make_repr(self._attrs, ns, self._cls) + ) + return self + + def add_str(self): + repr = self._cls_dict.get("__repr__") + if repr is None: + msg = "__str__ can only be generated if a __repr__ exists." + raise ValueError(msg) + + def __str__(self): + return self.__repr__() + + self._cls_dict["__str__"] = self._add_method_dunders(__str__) + return self + + def _make_getstate_setstate(self): + """ + Create custom __setstate__ and __getstate__ methods. + """ + # __weakref__ is not writable. + state_attr_names = tuple( + an for an in self._attr_names if an != "__weakref__" + ) + + def slots_getstate(self): + """ + Automatically created by attrs. + """ + return {name: getattr(self, name) for name in state_attr_names} + + hash_caching_enabled = self._cache_hash + + def slots_setstate(self, state): + """ + Automatically created by attrs. + """ + __bound_setattr = _OBJ_SETATTR.__get__(self) + if isinstance(state, tuple): + # Backward compatibility with attrs instances pickled with + # attrs versions before v22.2.0 which stored tuples. + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + else: + for name in state_attr_names: + if name in state: + __bound_setattr(name, state[name]) + + # The hash code cache is not included when the object is + # serialized, but it still needs to be initialized to None to + # indicate that the first call to __hash__ should be a cache + # miss. + if hash_caching_enabled: + __bound_setattr(_HASH_CACHE_FIELD, None) + + return slots_getstate, slots_setstate + + def make_unhashable(self): + self._cls_dict["__hash__"] = None + return self + + def add_hash(self): + self._cls_dict["__hash__"] = self._add_method_dunders( + _make_hash( + self._cls, + self._attrs, + frozen=self._frozen, + cache_hash=self._cache_hash, + ) + ) + + return self + + def add_init(self): + self._cls_dict["__init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._pre_init_has_args, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=False, + ) + ) + + return self + + def add_match_args(self): + self._cls_dict["__match_args__"] = tuple( + field.name + for field in self._attrs + if field.init and not field.kw_only + ) + + def add_attrs_init(self): + self._cls_dict["__attrs_init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._pre_init_has_args, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=True, + ) + ) + + return self + + def add_eq(self): + cd = self._cls_dict + + cd["__eq__"] = self._add_method_dunders( + _make_eq(self._cls, self._attrs) + ) + cd["__ne__"] = self._add_method_dunders(_make_ne()) + + return self + + def add_order(self): + cd = self._cls_dict + + cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( + self._add_method_dunders(meth) + for meth in _make_order(self._cls, self._attrs) + ) + + return self + + def add_setattr(self): + if self._frozen: + return self + + sa_attrs = {} + for a in self._attrs: + on_setattr = a.on_setattr or self._on_setattr + if on_setattr and on_setattr is not setters.NO_OP: + sa_attrs[a.name] = a, on_setattr + + if not sa_attrs: + return self + + if self._has_custom_setattr: + # We need to write a __setattr__ but there already is one! + msg = "Can't combine custom __setattr__ with on_setattr hooks." + raise ValueError(msg) + + # docstring comes from _add_method_dunders + def __setattr__(self, name, val): + try: + a, hook = sa_attrs[name] + except KeyError: + nval = val + else: + nval = hook(self, a, val) + + _OBJ_SETATTR(self, name, nval) + + self._cls_dict["__attrs_own_setattr__"] = True + self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) + self._wrote_own_setattr = True + + return self + + def _add_method_dunders(self, method): + """ + Add __module__ and __qualname__ to a *method* if possible. + """ + with contextlib.suppress(AttributeError): + method.__module__ = self._cls.__module__ + + with contextlib.suppress(AttributeError): + method.__qualname__ = f"{self._cls.__qualname__}.{method.__name__}" + + with contextlib.suppress(AttributeError): + method.__doc__ = ( + "Method generated by attrs for class " + f"{self._cls.__qualname__}." + ) + + return method + + +def _determine_attrs_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + msg = "Don't mix `cmp` with `eq' and `order`." + raise ValueError(msg) + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + return cmp, cmp + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq = default_eq + + if order is None: + order = eq + + if eq is False and order is True: + msg = "`order` can only be True if `eq` is True too." + raise ValueError(msg) + + return eq, order + + +def _determine_attrib_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + msg = "Don't mix `cmp` with `eq' and `order`." + raise ValueError(msg) + + def decide_callable_or_boolean(value): + """ + Decide whether a key function is used. + """ + if callable(value): + value, key = True, value + else: + key = None + return value, key + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + cmp, cmp_key = decide_callable_or_boolean(cmp) + return cmp, cmp_key, cmp, cmp_key + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq, eq_key = default_eq, None + else: + eq, eq_key = decide_callable_or_boolean(eq) + + if order is None: + order, order_key = eq, eq_key + else: + order, order_key = decide_callable_or_boolean(order) + + if eq is False and order is True: + msg = "`order` can only be True if `eq` is True too." + raise ValueError(msg) + + return eq, eq_key, order, order_key + + +def _determine_whether_to_implement( + cls, flag, auto_detect, dunders, default=True +): + """ + Check whether we should implement a set of methods for *cls*. + + *flag* is the argument passed into @attr.s like 'init', *auto_detect* the + same as passed into @attr.s and *dunders* is a tuple of attribute names + whose presence signal that the user has implemented it themselves. + + Return *default* if no reason for either for or against is found. + """ + if flag is True or flag is False: + return flag + + if flag is None and auto_detect is False: + return default + + # Logically, flag is None and auto_detect is True here. + for dunder in dunders: + if _has_own_attribute(cls, dunder): + return False + + return default + + +def attrs( + maybe_cls=None, + these=None, + repr_ns=None, + repr=None, + cmp=None, + hash=None, + init=None, + slots=False, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=False, + kw_only=False, + cache_hash=False, + auto_exc=False, + eq=None, + order=None, + auto_detect=False, + collect_by_mro=False, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, + unsafe_hash=None, +): + r""" + A class decorator that adds :term:`dunder methods` according to the + specified attributes using `attr.ib` or the *these* argument. + + Consider using `attrs.define` / `attrs.frozen` in new code (``attr.s`` will + *never* go away, though). + + Args: + repr_ns (str): + When using nested classes, there was no way in Python 2 to + automatically detect that. This argument allows to set a custom + name for a more meaningful ``repr`` output. This argument is + pointless in Python 3 and is therefore deprecated. + + .. caution:: + Refer to `attrs.define` for the rest of the parameters, but note that they + can have different defaults. + + Notably, leaving *on_setattr* as `None` will **not** add any hooks. + + .. versionadded:: 16.0.0 *slots* + .. versionadded:: 16.1.0 *frozen* + .. versionadded:: 16.3.0 *str* + .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. + .. versionchanged:: 17.1.0 + *hash* supports `None` as value which is also the default now. + .. versionadded:: 17.3.0 *auto_attribs* + .. versionchanged:: 18.1.0 + If *these* is passed, no attributes are deleted from the class body. + .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. + .. versionadded:: 18.2.0 *weakref_slot* + .. deprecated:: 18.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a + `DeprecationWarning` if the classes compared are subclasses of + each other. ``__eq`` and ``__ne__`` never tried to compared subclasses + to each other. + .. versionchanged:: 19.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider + subclasses comparable anymore. + .. versionadded:: 18.2.0 *kw_only* + .. versionadded:: 18.2.0 *cache_hash* + .. versionadded:: 19.1.0 *auto_exc* + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *auto_detect* + .. versionadded:: 20.1.0 *collect_by_mro* + .. versionadded:: 20.1.0 *getstate_setstate* + .. versionadded:: 20.1.0 *on_setattr* + .. versionadded:: 20.3.0 *field_transformer* + .. versionchanged:: 21.1.0 + ``init=False`` injects ``__attrs_init__`` + .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` + .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 21.3.0 *match_args* + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). + .. deprecated:: 24.1.0 *repr_ns* + .. versionchanged:: 24.1.0 + Instances are not compared as tuples of attributes anymore, but using a + big ``and`` condition. This is faster and has more correct behavior for + uncomparable values like `math.nan`. + .. versionadded:: 24.1.0 + If a class has an *inherited* classmethod called + ``__attrs_init_subclass__``, it is executed after the class is created. + .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*. + """ + if repr_ns is not None: + import warnings + + warnings.warn( + DeprecationWarning( + "The `repr_ns` argument is deprecated and will be removed in or after August 2025." + ), + stacklevel=2, + ) + + eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) + + # unsafe_hash takes precedence due to PEP 681. + if unsafe_hash is not None: + hash = unsafe_hash + + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + def wrap(cls): + is_frozen = frozen or _has_frozen_base_class(cls) + is_exc = auto_exc is True and issubclass(cls, BaseException) + has_own_setattr = auto_detect and _has_own_attribute( + cls, "__setattr__" + ) + + if has_own_setattr and is_frozen: + msg = "Can't freeze a class with a custom __setattr__." + raise ValueError(msg) + + builder = _ClassBuilder( + cls, + these, + slots, + is_frozen, + weakref_slot, + _determine_whether_to_implement( + cls, + getstate_setstate, + auto_detect, + ("__getstate__", "__setstate__"), + default=slots, + ), + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_own_setattr, + field_transformer, + ) + if _determine_whether_to_implement( + cls, repr, auto_detect, ("__repr__",) + ): + builder.add_repr(repr_ns) + if str is True: + builder.add_str() + + eq = _determine_whether_to_implement( + cls, eq_, auto_detect, ("__eq__", "__ne__") + ) + if not is_exc and eq is True: + builder.add_eq() + if not is_exc and _determine_whether_to_implement( + cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") + ): + builder.add_order() + + builder.add_setattr() + + nonlocal hash + if ( + hash is None + and auto_detect is True + and _has_own_attribute(cls, "__hash__") + ): + hash = False + + if hash is not True and hash is not False and hash is not None: + # Can't use `hash in` because 1 == True for example. + msg = "Invalid value for hash. Must be True, False, or None." + raise TypeError(msg) + + if hash is False or (hash is None and eq is False) or is_exc: + # Don't do anything. Should fall back to __object__'s __hash__ + # which is by id. + if cache_hash: + msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." + raise TypeError(msg) + elif hash is True or ( + hash is None and eq is True and is_frozen is True + ): + # Build a __hash__ if told so, or if it's safe. + builder.add_hash() + else: + # Raise TypeError on attempts to hash. + if cache_hash: + msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." + raise TypeError(msg) + builder.make_unhashable() + + if _determine_whether_to_implement( + cls, init, auto_detect, ("__init__",) + ): + builder.add_init() + else: + builder.add_attrs_init() + if cache_hash: + msg = "Invalid value for cache_hash. To use hash caching, init must be True." + raise TypeError(msg) + + if ( + PY_3_10_PLUS + and match_args + and not _has_own_attribute(cls, "__match_args__") + ): + builder.add_match_args() + + return builder.build_class() + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but `None` if used as `@attrs()`. + if maybe_cls is None: + return wrap + + return wrap(maybe_cls) + + +_attrs = attrs +""" +Internal alias so we can use it in functions that take an argument called +*attrs*. +""" + + +def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ is _frozen_setattrs + + +def _generate_unique_filename(cls, func_name): + """ + Create a "filename" suitable for a function being generated. + """ + return ( + f"" + ) + + +def _make_hash(cls, attrs, frozen, cache_hash): + attrs = tuple( + a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) + ) + + tab = " " + + unique_filename = _generate_unique_filename(cls, "hash") + type_hash = hash(unique_filename) + # If eq is custom generated, we need to include the functions in globs + globs = {} + + hash_def = "def __hash__(self" + hash_func = "hash((" + closing_braces = "))" + if not cache_hash: + hash_def += "):" + else: + hash_def += ", *" + + hash_def += ", _cache_wrapper=__import__('attr._make')._make._CacheHashWrapper):" + hash_func = "_cache_wrapper(" + hash_func + closing_braces += ")" + + method_lines = [hash_def] + + def append_hash_computation_lines(prefix, indent): + """ + Generate the code for actually computing the hash code. + Below this will either be returned directly or used to compute + a value which is then cached, depending on the value of cache_hash + """ + + method_lines.extend( + [ + indent + prefix + hash_func, + indent + f" {type_hash},", + ] + ) + + for a in attrs: + if a.eq_key: + cmp_name = f"_{a.name}_key" + globs[cmp_name] = a.eq_key + method_lines.append( + indent + f" {cmp_name}(self.{a.name})," + ) + else: + method_lines.append(indent + f" self.{a.name},") + + method_lines.append(indent + " " + closing_braces) + + if cache_hash: + method_lines.append(tab + f"if self.{_HASH_CACHE_FIELD} is None:") + if frozen: + append_hash_computation_lines( + f"object.__setattr__(self, '{_HASH_CACHE_FIELD}', ", tab * 2 + ) + method_lines.append(tab * 2 + ")") # close __setattr__ + else: + append_hash_computation_lines( + f"self.{_HASH_CACHE_FIELD} = ", tab * 2 + ) + method_lines.append(tab + f"return self.{_HASH_CACHE_FIELD}") + else: + append_hash_computation_lines("return ", tab) + + script = "\n".join(method_lines) + return _make_method("__hash__", script, unique_filename, globs) + + +def _add_hash(cls, attrs): + """ + Add a hash method to *cls*. + """ + cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) + return cls + + +def _make_ne(): + """ + Create __ne__ method. + """ + + def __ne__(self, other): + """ + Check equality and either forward a NotImplemented or + return the result negated. + """ + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + + return not result + + return __ne__ + + +def _make_eq(cls, attrs): + """ + Create __eq__ method for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.eq] + + unique_filename = _generate_unique_filename(cls, "eq") + lines = [ + "def __eq__(self, other):", + " if other.__class__ is not self.__class__:", + " return NotImplemented", + ] + + # We can't just do a big self.x = other.x and... clause due to + # irregularities like nan == nan is false but (nan,) == (nan,) is true. + globs = {} + if attrs: + lines.append(" return (") + for a in attrs: + if a.eq_key: + cmp_name = f"_{a.name}_key" + # Add the key function to the global namespace + # of the evaluated function. + globs[cmp_name] = a.eq_key + lines.append( + f" {cmp_name}(self.{a.name}) == {cmp_name}(other.{a.name})" + ) + else: + lines.append(f" self.{a.name} == other.{a.name}") + if a is not attrs[-1]: + lines[-1] = f"{lines[-1]} and" + lines.append(" )") + else: + lines.append(" return True") + + script = "\n".join(lines) + + return _make_method("__eq__", script, unique_filename, globs) + + +def _make_order(cls, attrs): + """ + Create ordering methods for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.order] + + def attrs_to_tuple(obj): + """ + Save us some typing. + """ + return tuple( + key(value) if key else value + for value, key in ( + (getattr(obj, a.name), a.order_key) for a in attrs + ) + ) + + def __lt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) < attrs_to_tuple(other) + + return NotImplemented + + def __le__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) <= attrs_to_tuple(other) + + return NotImplemented + + def __gt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) > attrs_to_tuple(other) + + return NotImplemented + + def __ge__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) >= attrs_to_tuple(other) + + return NotImplemented + + return __lt__, __le__, __gt__, __ge__ + + +def _add_eq(cls, attrs=None): + """ + Add equality methods to *cls* with *attrs*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__eq__ = _make_eq(cls, attrs) + cls.__ne__ = _make_ne() + + return cls + + +def _make_repr(attrs, ns, cls): + unique_filename = _generate_unique_filename(cls, "repr") + # Figure out which attributes to include, and which function to use to + # format them. The a.repr value can be either bool or a custom + # callable. + attr_names_with_reprs = tuple( + (a.name, (repr if a.repr is True else a.repr), a.init) + for a in attrs + if a.repr is not False + ) + globs = { + name + "_repr": r for name, r, _ in attr_names_with_reprs if r != repr + } + globs["_compat"] = _compat + globs["AttributeError"] = AttributeError + globs["NOTHING"] = NOTHING + attribute_fragments = [] + for name, r, i in attr_names_with_reprs: + accessor = ( + "self." + name if i else 'getattr(self, "' + name + '", NOTHING)' + ) + fragment = ( + "%s={%s!r}" % (name, accessor) + if r == repr + else "%s={%s_repr(%s)}" % (name, name, accessor) + ) + attribute_fragments.append(fragment) + repr_fragment = ", ".join(attribute_fragments) + + if ns is None: + cls_name_fragment = '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}' + else: + cls_name_fragment = ns + ".{self.__class__.__name__}" + + lines = [ + "def __repr__(self):", + " try:", + " already_repring = _compat.repr_context.already_repring", + " except AttributeError:", + " already_repring = {id(self),}", + " _compat.repr_context.already_repring = already_repring", + " else:", + " if id(self) in already_repring:", + " return '...'", + " else:", + " already_repring.add(id(self))", + " try:", + f" return f'{cls_name_fragment}({repr_fragment})'", + " finally:", + " already_repring.remove(id(self))", + ] + + return _make_method( + "__repr__", "\n".join(lines), unique_filename, globs=globs + ) + + +def _add_repr(cls, ns=None, attrs=None): + """ + Add a repr method to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__repr__ = _make_repr(attrs, ns, cls) + return cls + + +def fields(cls): + """ + Return the tuple of *attrs* attributes for a class. + + The tuple also allows accessing the fields by their names (see below for + examples). + + Args: + cls (type): Class to introspect. + + Raises: + TypeError: If *cls* is not a class. + + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + Returns: + tuple (with name accessors) of `attrs.Attribute` + + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + .. versionchanged:: 23.1.0 Add support for generic classes. + """ + generic_base = get_generic_base(cls) + + if generic_base is None and not isinstance(cls, type): + msg = "Passed object must be a class." + raise TypeError(msg) + + attrs = getattr(cls, "__attrs_attrs__", None) + + if attrs is None: + if generic_base is not None: + attrs = getattr(generic_base, "__attrs_attrs__", None) + if attrs is not None: + # Even though this is global state, stick it on here to speed + # it up. We rely on `cls` being cached for this to be + # efficient. + cls.__attrs_attrs__ = attrs + return attrs + msg = f"{cls!r} is not an attrs-decorated class." + raise NotAnAttrsClassError(msg) + + return attrs + + +def fields_dict(cls): + """ + Return an ordered dictionary of *attrs* attributes for a class, whose keys + are the attribute names. + + Args: + cls (type): Class to introspect. + + Raises: + TypeError: If *cls* is not a class. + + attrs.exceptions.NotAnAttrsClassError: + If *cls* is not an *attrs* class. + + Returns: + dict[str, attrs.Attribute]: Dict of attribute name to definition + + .. versionadded:: 18.1.0 + """ + if not isinstance(cls, type): + msg = "Passed object must be a class." + raise TypeError(msg) + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + msg = f"{cls!r} is not an attrs-decorated class." + raise NotAnAttrsClassError(msg) + return {a.name: a for a in attrs} + + +def validate(inst): + """ + Validate all attributes on *inst* that have a validator. + + Leaves all exceptions through. + + Args: + inst: Instance of a class with *attrs* attributes. + """ + if _config._run_validators is False: + return + + for a in fields(inst.__class__): + v = a.validator + if v is not None: + v(inst, a, getattr(inst, a.name)) + + +def _is_slot_attr(a_name, base_attr_map): + """ + Check if the attribute name comes from a slot class. + """ + cls = base_attr_map.get(a_name) + return cls and "__slots__" in cls.__dict__ + + +def _make_init( + cls, + attrs, + pre_init, + pre_init_has_args, + post_init, + frozen, + slots, + cache_hash, + base_attr_map, + is_exc, + cls_on_setattr, + attrs_init, +): + has_cls_on_setattr = ( + cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP + ) + + if frozen and has_cls_on_setattr: + msg = "Frozen classes can't use on_setattr." + raise ValueError(msg) + + needs_cached_setattr = cache_hash or frozen + filtered_attrs = [] + attr_dict = {} + for a in attrs: + if not a.init and a.default is NOTHING: + continue + + filtered_attrs.append(a) + attr_dict[a.name] = a + + if a.on_setattr is not None: + if frozen is True: + msg = "Frozen classes can't use on_setattr." + raise ValueError(msg) + + needs_cached_setattr = True + elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP: + needs_cached_setattr = True + + unique_filename = _generate_unique_filename(cls, "init") + + script, globs, annotations = _attrs_to_init_script( + filtered_attrs, + frozen, + slots, + pre_init, + pre_init_has_args, + post_init, + cache_hash, + base_attr_map, + is_exc, + needs_cached_setattr, + has_cls_on_setattr, + "__attrs_init__" if attrs_init else "__init__", + ) + if cls.__module__ in sys.modules: + # This makes typing.get_type_hints(CLS.__init__) resolve string types. + globs.update(sys.modules[cls.__module__].__dict__) + + globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) + + if needs_cached_setattr: + # Save the lookup overhead in __init__ if we need to circumvent + # setattr hooks. + globs["_cached_setattr_get"] = _OBJ_SETATTR.__get__ + + init = _make_method( + "__attrs_init__" if attrs_init else "__init__", + script, + unique_filename, + globs, + ) + init.__annotations__ = annotations + + return init + + +def _setattr(attr_name: str, value_var: str, has_on_setattr: bool) -> str: + """ + Use the cached object.setattr to set *attr_name* to *value_var*. + """ + return f"_setattr('{attr_name}', {value_var})" + + +def _setattr_with_converter( + attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter +) -> str: + """ + Use the cached object.setattr to set *attr_name* to *value_var*, but run + its converter first. + """ + return f"_setattr('{attr_name}', {converter._fmt_converter_call(attr_name, value_var)})" + + +def _assign(attr_name: str, value: str, has_on_setattr: bool) -> str: + """ + Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise + relegate to _setattr. + """ + if has_on_setattr: + return _setattr(attr_name, value, True) + + return f"self.{attr_name} = {value}" + + +def _assign_with_converter( + attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter +) -> str: + """ + Unless *attr_name* has an on_setattr hook, use normal assignment after + conversion. Otherwise relegate to _setattr_with_converter. + """ + if has_on_setattr: + return _setattr_with_converter(attr_name, value_var, True, converter) + + return f"self.{attr_name} = {converter._fmt_converter_call(attr_name, value_var)}" + + +def _determine_setters( + frozen: bool, slots: bool, base_attr_map: dict[str, type] +): + """ + Determine the correct setter functions based on whether a class is frozen + and/or slotted. + """ + if frozen is True: + if slots is True: + return (), _setattr, _setattr_with_converter + + # Dict frozen classes assign directly to __dict__. + # But only if the attribute doesn't come from an ancestor slot + # class. + # Note _inst_dict will be used again below if cache_hash is True + + def fmt_setter( + attr_name: str, value_var: str, has_on_setattr: bool + ) -> str: + if _is_slot_attr(attr_name, base_attr_map): + return _setattr(attr_name, value_var, has_on_setattr) + + return f"_inst_dict['{attr_name}'] = {value_var}" + + def fmt_setter_with_converter( + attr_name: str, + value_var: str, + has_on_setattr: bool, + converter: Converter, + ) -> str: + if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): + return _setattr_with_converter( + attr_name, value_var, has_on_setattr, converter + ) + + return f"_inst_dict['{attr_name}'] = {converter._fmt_converter_call(attr_name, value_var)}" + + return ( + ("_inst_dict = self.__dict__",), + fmt_setter, + fmt_setter_with_converter, + ) + + # Not frozen -- we can just assign directly. + return (), _assign, _assign_with_converter + + +def _attrs_to_init_script( + attrs: list[Attribute], + is_frozen: bool, + is_slotted: bool, + call_pre_init: bool, + pre_init_has_args: bool, + call_post_init: bool, + does_cache_hash: bool, + base_attr_map: dict[str, type], + is_exc: bool, + needs_cached_setattr: bool, + has_cls_on_setattr: bool, + method_name: str, +) -> tuple[str, dict, dict]: + """ + Return a script of an initializer for *attrs*, a dict of globals, and + annotations for the initializer. + + The globals are required by the generated script. + """ + lines = ["self.__attrs_pre_init__()"] if call_pre_init else [] + + if needs_cached_setattr: + lines.append( + # Circumvent the __setattr__ descriptor to save one lookup per + # assignment. Note _setattr will be used again below if + # does_cache_hash is True. + "_setattr = _cached_setattr_get(self)" + ) + + extra_lines, fmt_setter, fmt_setter_with_converter = _determine_setters( + is_frozen, is_slotted, base_attr_map + ) + lines.extend(extra_lines) + + args = [] + kw_only_args = [] + attrs_to_validate = [] + + # This is a dictionary of names to validator and converter callables. + # Injecting this into __init__ globals lets us avoid lookups. + names_for_globals = {} + annotations = {"return": None} + + for a in attrs: + if a.validator: + attrs_to_validate.append(a) + + attr_name = a.name + has_on_setattr = a.on_setattr is not None or ( + a.on_setattr is not setters.NO_OP and has_cls_on_setattr + ) + # a.alias is set to maybe-mangled attr_name in _ClassBuilder if not + # explicitly provided + arg_name = a.alias + + has_factory = isinstance(a.default, Factory) + maybe_self = "self" if has_factory and a.default.takes_self else "" + + if a.converter and not isinstance(a.converter, Converter): + converter = Converter(a.converter) + else: + converter = a.converter + + if a.init is False: + if has_factory: + init_factory_name = _INIT_FACTORY_PAT % (a.name,) + if converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + init_factory_name + f"({maybe_self})", + has_on_setattr, + converter, + ) + ) + names_for_globals[converter._get_global_name(a.name)] = ( + converter.converter + ) + else: + lines.append( + fmt_setter( + attr_name, + init_factory_name + f"({maybe_self})", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + elif converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, + converter, + ) + ) + names_for_globals[converter._get_global_name(a.name)] = ( + converter.converter + ) + else: + lines.append( + fmt_setter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, + ) + ) + elif a.default is not NOTHING and not has_factory: + arg = f"{arg_name}=attr_dict['{attr_name}'].default" + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + + if converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr, converter + ) + ) + names_for_globals[converter._get_global_name(a.name)] = ( + converter.converter + ) + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + elif has_factory: + arg = f"{arg_name}=NOTHING" + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + lines.append(f"if {arg_name} is not NOTHING:") + + init_factory_name = _INIT_FACTORY_PAT % (a.name,) + if converter is not None: + lines.append( + " " + + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr, converter + ) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter_with_converter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + converter, + ) + ) + names_for_globals[converter._get_global_name(a.name)] = ( + converter.converter + ) + else: + lines.append( + " " + fmt_setter(attr_name, arg_name, has_on_setattr) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.kw_only: + kw_only_args.append(arg_name) + else: + args.append(arg_name) + + if converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr, converter + ) + ) + names_for_globals[converter._get_global_name(a.name)] = ( + converter.converter + ) + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + if a.init is True: + if a.type is not None and converter is None: + annotations[arg_name] = a.type + elif converter is not None and converter._first_param_type: + # Use the type from the converter if present. + annotations[arg_name] = converter._first_param_type + + if attrs_to_validate: # we can skip this if there are no validators. + names_for_globals["_config"] = _config + lines.append("if _config._run_validators is True:") + for a in attrs_to_validate: + val_name = "__attr_validator_" + a.name + attr_name = "__attr_" + a.name + lines.append(f" {val_name}(self, {attr_name}, self.{a.name})") + names_for_globals[val_name] = a.validator + names_for_globals[attr_name] = a + + if call_post_init: + lines.append("self.__attrs_post_init__()") + + # Because this is set only after __attrs_post_init__ is called, a crash + # will result if post-init tries to access the hash code. This seemed + # preferable to setting this beforehand, in which case alteration to field + # values during post-init combined with post-init accessing the hash code + # would result in silent bugs. + if does_cache_hash: + if is_frozen: + if is_slotted: + init_hash_cache = f"_setattr('{_HASH_CACHE_FIELD}', None)" + else: + init_hash_cache = f"_inst_dict['{_HASH_CACHE_FIELD}'] = None" + else: + init_hash_cache = f"self.{_HASH_CACHE_FIELD} = None" + lines.append(init_hash_cache) + + # For exceptions we rely on BaseException.__init__ for proper + # initialization. + if is_exc: + vals = ",".join(f"self.{a.name}" for a in attrs if a.init) + + lines.append(f"BaseException.__init__(self, {vals})") + + args = ", ".join(args) + pre_init_args = args + if kw_only_args: + # leading comma & kw_only args + args += f"{', ' if args else ''}*, {', '.join(kw_only_args)}" + pre_init_kw_only_args = ", ".join( + [ + f"{kw_arg_name}={kw_arg_name}" + # We need to remove the defaults from the kw_only_args. + for kw_arg_name in (kwa.split("=")[0] for kwa in kw_only_args) + ] + ) + pre_init_args += ", " if pre_init_args else "" + pre_init_args += pre_init_kw_only_args + + if call_pre_init and pre_init_has_args: + # If pre init method has arguments, pass same arguments as `__init__`. + lines[0] = f"self.__attrs_pre_init__({pre_init_args})" + + # Python 3.7 doesn't allow backslashes in f strings. + NL = "\n " + return ( + f"""def {method_name}(self, {args}): + {NL.join(lines) if lines else 'pass'} +""", + names_for_globals, + annotations, + ) + + +def _default_init_alias_for(name: str) -> str: + """ + The default __init__ parameter name for a field. + + This performs private-name adjustment via leading-unscore stripping, + and is the default value of Attribute.alias if not provided. + """ + + return name.lstrip("_") + + +class Attribute: + """ + *Read-only* representation of an attribute. + + .. warning:: + + You should never instantiate this class yourself. + + The class has *all* arguments of `attr.ib` (except for ``factory`` which is + only syntactic sugar for ``default=Factory(...)`` plus the following: + + - ``name`` (`str`): The name of the attribute. + - ``alias`` (`str`): The __init__ parameter name of the attribute, after + any explicit overrides and default private-attribute-name handling. + - ``inherited`` (`bool`): Whether or not that attribute has been inherited + from a base class. + - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The + callables that are used for comparing and ordering objects by this + attribute, respectively. These are set by passing a callable to + `attr.ib`'s ``eq``, ``order``, or ``cmp`` arguments. See also + :ref:`comparison customization `. + + Instances of this class are frequently used for introspection purposes + like: + + - `fields` returns a tuple of them. + - Validators get them passed as the first argument. + - The :ref:`field transformer ` hook receives a list of + them. + - The ``alias`` property exposes the __init__ parameter name of the field, + with any overrides and default private-attribute handling applied. + + + .. versionadded:: 20.1.0 *inherited* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.2.0 *inherited* is not taken into account for + equality checks and hashing anymore. + .. versionadded:: 21.1.0 *eq_key* and *order_key* + .. versionadded:: 22.2.0 *alias* + + For the full version history of the fields, see `attr.ib`. + """ + + __slots__ = ( + "name", + "default", + "validator", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "type", + "converter", + "kw_only", + "inherited", + "on_setattr", + "alias", + ) + + def __init__( + self, + name, + default, + validator, + repr, + cmp, # XXX: unused, remove along with other cmp code. + hash, + init, + inherited, + metadata=None, + type=None, + converter=None, + kw_only=False, + eq=None, + eq_key=None, + order=None, + order_key=None, + on_setattr=None, + alias=None, + ): + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq_key or eq, order_key or order, True + ) + + # Cache this descriptor here to speed things up later. + bound_setattr = _OBJ_SETATTR.__get__(self) + + # Despite the big red warning, people *do* instantiate `Attribute` + # themselves. + bound_setattr("name", name) + bound_setattr("default", default) + bound_setattr("validator", validator) + bound_setattr("repr", repr) + bound_setattr("eq", eq) + bound_setattr("eq_key", eq_key) + bound_setattr("order", order) + bound_setattr("order_key", order_key) + bound_setattr("hash", hash) + bound_setattr("init", init) + bound_setattr("converter", converter) + bound_setattr( + "metadata", + ( + types.MappingProxyType(dict(metadata)) # Shallow copy + if metadata + else _EMPTY_METADATA_SINGLETON + ), + ) + bound_setattr("type", type) + bound_setattr("kw_only", kw_only) + bound_setattr("inherited", inherited) + bound_setattr("on_setattr", on_setattr) + bound_setattr("alias", alias) + + def __setattr__(self, name, value): + raise FrozenInstanceError() + + @classmethod + def from_counting_attr(cls, name, ca, type=None): + # type holds the annotated value. deal with conflicts: + if type is None: + type = ca.type + elif ca.type is not None: + msg = "Type annotation and type argument cannot both be present" + raise ValueError(msg) + inst_dict = { + k: getattr(ca, k) + for k in Attribute.__slots__ + if k + not in ( + "name", + "validator", + "default", + "type", + "inherited", + ) # exclude methods and deprecated alias + } + return cls( + name=name, + validator=ca._validator, + default=ca._default, + type=type, + cmp=None, + inherited=False, + **inst_dict, + ) + + # Don't use attrs.evolve since fields(Attribute) doesn't work + def evolve(self, **changes): + """ + Copy *self* and apply *changes*. + + This works similarly to `attrs.evolve` but that function does not work + with {class}`Attribute`. + + It is mainly meant to be used for `transform-fields`. + + .. versionadded:: 20.3.0 + """ + new = copy.copy(self) + + new._setattrs(changes.items()) + + return new + + # Don't use _add_pickle since fields(Attribute) doesn't work + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple( + getattr(self, name) if name != "metadata" else dict(self.metadata) + for name in self.__slots__ + ) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + self._setattrs(zip(self.__slots__, state)) + + def _setattrs(self, name_values_pairs): + bound_setattr = _OBJ_SETATTR.__get__(self) + for name, value in name_values_pairs: + if name != "metadata": + bound_setattr(name, value) + else: + bound_setattr( + name, + ( + types.MappingProxyType(dict(value)) + if value + else _EMPTY_METADATA_SINGLETON + ), + ) + + +_a = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=(name != "metadata"), + init=True, + inherited=False, + alias=_default_init_alias_for(name), + ) + for name in Attribute.__slots__ +] + +Attribute = _add_hash( + _add_eq( + _add_repr(Attribute, attrs=_a), + attrs=[a for a in _a if a.name != "inherited"], + ), + attrs=[a for a in _a if a.hash and a.name != "inherited"], +) + + +class _CountingAttr: + """ + Intermediate representation of attributes that uses a counter to preserve + the order in which the attributes have been defined. + + *Internal* data structure of the attrs library. Running into is most + likely the result of a bug like a forgotten `@attr.s` decorator. + """ + + __slots__ = ( + "counter", + "_default", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "_validator", + "converter", + "type", + "kw_only", + "on_setattr", + "alias", + ) + __attrs_attrs__ = ( + *tuple( + Attribute( + name=name, + alias=_default_init_alias_for(name), + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=True, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ) + for name in ( + "counter", + "_default", + "repr", + "eq", + "order", + "hash", + "init", + "on_setattr", + "alias", + ) + ), + Attribute( + name="metadata", + alias="metadata", + default=None, + validator=None, + repr=True, + cmp=None, + hash=False, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ), + ) + cls_counter = 0 + + def __init__( + self, + default, + validator, + repr, + cmp, + hash, + init, + converter, + metadata, + type, + kw_only, + eq, + eq_key, + order, + order_key, + on_setattr, + alias, + ): + _CountingAttr.cls_counter += 1 + self.counter = _CountingAttr.cls_counter + self._default = default + self._validator = validator + self.converter = converter + self.repr = repr + self.eq = eq + self.eq_key = eq_key + self.order = order + self.order_key = order_key + self.hash = hash + self.init = init + self.metadata = metadata + self.type = type + self.kw_only = kw_only + self.on_setattr = on_setattr + self.alias = alias + + def validator(self, meth): + """ + Decorator that adds *meth* to the list of validators. + + Returns *meth* unchanged. + + .. versionadded:: 17.1.0 + """ + if self._validator is None: + self._validator = meth + else: + self._validator = and_(self._validator, meth) + return meth + + def default(self, meth): + """ + Decorator that allows to set the default for an attribute. + + Returns *meth* unchanged. + + Raises: + DefaultAlreadySetError: If default has been set before. + + .. versionadded:: 17.1.0 + """ + if self._default is not NOTHING: + raise DefaultAlreadySetError() + + self._default = Factory(meth, takes_self=True) + + return meth + + +_CountingAttr = _add_eq(_add_repr(_CountingAttr)) + + +class Factory: + """ + Stores a factory callable. + + If passed as the default value to `attrs.field`, the factory is used to + generate a new value. + + Args: + factory (typing.Callable): + A callable that takes either none or exactly one mandatory + positional argument depending on *takes_self*. + + takes_self (bool): + Pass the partially initialized instance that is being initialized + as a positional argument. + + .. versionadded:: 17.1.0 *takes_self* + """ + + __slots__ = ("factory", "takes_self") + + def __init__(self, factory, takes_self=False): + self.factory = factory + self.takes_self = takes_self + + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple(getattr(self, name) for name in self.__slots__) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + for name, value in zip(self.__slots__, state): + setattr(self, name, value) + + +_f = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=True, + init=True, + inherited=False, + ) + for name in Factory.__slots__ +] + +Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) + + +class Converter: + """ + Stores a converter callable. + + Allows for the wrapped converter to take additional arguments. The + arguments are passed in the order they are documented. + + Args: + converter (Callable): A callable that converts the passed value. + + takes_self (bool): + Pass the partially initialized instance that is being initialized + as a positional argument. (default: `False`) + + takes_field (bool): + Pass the field definition (an :class:`Attribute`) into the + converter as a positional argument. (default: `False`) + + .. versionadded:: 24.1.0 + """ + + __slots__ = ( + "converter", + "takes_self", + "takes_field", + "_first_param_type", + "_global_name", + "__call__", + ) + + def __init__(self, converter, *, takes_self=False, takes_field=False): + self.converter = converter + self.takes_self = takes_self + self.takes_field = takes_field + + ex = _AnnotationExtractor(converter) + self._first_param_type = ex.get_first_param_type() + + if not (self.takes_self or self.takes_field): + self.__call__ = lambda value, _, __: self.converter(value) + elif self.takes_self and not self.takes_field: + self.__call__ = lambda value, instance, __: self.converter( + value, instance + ) + elif not self.takes_self and self.takes_field: + self.__call__ = lambda value, __, field: self.converter( + value, field + ) + else: + self.__call__ = lambda value, instance, field: self.converter( + value, instance, field + ) + + rt = ex.get_return_type() + if rt is not None: + self.__call__.__annotations__["return"] = rt + + @staticmethod + def _get_global_name(attr_name: str) -> str: + """ + Return the name that a converter for an attribute name *attr_name* + would have. + """ + return f"__attr_converter_{attr_name}" + + def _fmt_converter_call(self, attr_name: str, value_var: str) -> str: + """ + Return a string that calls the converter for an attribute name + *attr_name* and the value in variable named *value_var* according to + `self.takes_self` and `self.takes_field`. + """ + if not (self.takes_self or self.takes_field): + return f"{self._get_global_name(attr_name)}({value_var})" + + if self.takes_self and self.takes_field: + return f"{self._get_global_name(attr_name)}({value_var}, self, attr_dict['{attr_name}'])" + + if self.takes_self: + return f"{self._get_global_name(attr_name)}({value_var}, self)" + + return f"{self._get_global_name(attr_name)}({value_var}, attr_dict['{attr_name}'])" + + def __getstate__(self): + """ + Return a dict containing only converter and takes_self -- the rest gets + computed when loading. + """ + return { + "converter": self.converter, + "takes_self": self.takes_self, + "takes_field": self.takes_field, + } + + def __setstate__(self, state): + """ + Load instance from state. + """ + self.__init__(**state) + + +_f = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=True, + init=True, + inherited=False, + ) + for name in ("converter", "takes_self", "takes_field") +] + +Converter = _add_hash( + _add_eq(_add_repr(Converter, attrs=_f), attrs=_f), attrs=_f +) + + +def make_class( + name, attrs, bases=(object,), class_body=None, **attributes_arguments +): + r""" + A quick way to create a new class called *name* with *attrs*. + + Args: + name (str): The name for the new class. + + attrs( list | dict): + A list of names or a dictionary of mappings of names to `attr.ib`\ + s / `attrs.field`\ s. + + The order is deduced from the order of the names or attributes + inside *attrs*. Otherwise the order of the definition of the + attributes is used. + + bases (tuple[type, ...]): Classes that the new class will subclass. + + class_body (dict): + An optional dictionary of class attributes for the new class. + + attributes_arguments: Passed unmodified to `attr.s`. + + Returns: + type: A new class with *attrs*. + + .. versionadded:: 17.1.0 *bases* + .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + .. versionchanged:: 23.2.0 *class_body* + """ + if isinstance(attrs, dict): + cls_dict = attrs + elif isinstance(attrs, (list, tuple)): + cls_dict = {a: attrib() for a in attrs} + else: + msg = "attrs argument must be a dict or a list." + raise TypeError(msg) + + pre_init = cls_dict.pop("__attrs_pre_init__", None) + post_init = cls_dict.pop("__attrs_post_init__", None) + user_init = cls_dict.pop("__init__", None) + + body = {} + if class_body is not None: + body.update(class_body) + if pre_init is not None: + body["__attrs_pre_init__"] = pre_init + if post_init is not None: + body["__attrs_post_init__"] = post_init + if user_init is not None: + body["__init__"] = user_init + + type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body)) + + # For pickling to work, the __module__ variable needs to be set to the + # frame where the class is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + with contextlib.suppress(AttributeError, ValueError): + type_.__module__ = sys._getframe(1).f_globals.get( + "__name__", "__main__" + ) + + # We do it here for proper warnings with meaningful stacklevel. + cmp = attributes_arguments.pop("cmp", None) + ( + attributes_arguments["eq"], + attributes_arguments["order"], + ) = _determine_attrs_eq_order( + cmp, + attributes_arguments.get("eq"), + attributes_arguments.get("order"), + True, + ) + + cls = _attrs(these=cls_dict, **attributes_arguments)(type_) + # Only add type annotations now or "_attrs()" will complain: + cls.__annotations__ = { + k: v.type for k, v in cls_dict.items() if v.type is not None + } + return cls + + +# These are required by within this module so we define them here and merely +# import into .validators / .converters. + + +@attrs(slots=True, unsafe_hash=True) +class _AndValidator: + """ + Compose many validators to a single one. + """ + + _validators = attrib() + + def __call__(self, inst, attr, value): + for v in self._validators: + v(inst, attr, value) + + +def and_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators. + + Args: + validators (~collections.abc.Iterable[typing.Callable]): + Arbitrary number of validators. + + .. versionadded:: 17.1.0 + """ + vals = [] + for validator in validators: + vals.extend( + validator._validators + if isinstance(validator, _AndValidator) + else [validator] + ) + + return _AndValidator(tuple(vals)) + + +def pipe(*converters): + """ + A converter that composes multiple converters into one. + + When called on a value, it runs all wrapped converters, returning the + *last* value. + + Type annotations will be inferred from the wrapped converters', if they + have any. + + converters (~collections.abc.Iterable[typing.Callable]): + Arbitrary number of converters. + + .. versionadded:: 20.1.0 + """ + + def pipe_converter(val, inst, field): + for c in converters: + val = c(val, inst, field) if isinstance(c, Converter) else c(val) + + return val + + if not converters: + # If the converter list is empty, pipe_converter is the identity. + A = typing.TypeVar("A") + pipe_converter.__annotations__.update({"val": A, "return": A}) + else: + # Get parameter type from first converter. + t = _AnnotationExtractor(converters[0]).get_first_param_type() + if t: + pipe_converter.__annotations__["val"] = t + + last = converters[-1] + if not PY_3_11_PLUS and isinstance(last, Converter): + last = last.__call__ + + # Get return type from last converter. + rt = _AnnotationExtractor(last).get_return_type() + if rt: + pipe_converter.__annotations__["return"] = rt + + return Converter(pipe_converter, takes_self=True, takes_field=True) diff --git a/.venv/lib/python3.7/site-packages/attr/_next_gen.py b/.venv/lib/python3.7/site-packages/attr/_next_gen.py new file mode 100644 index 0000000..dbb65cc --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_next_gen.py @@ -0,0 +1,631 @@ +# SPDX-License-Identifier: MIT + +""" +These are keyword-only APIs that call `attr.s` and `attr.ib` with different +default values. +""" + + +from functools import partial + +from . import setters +from ._funcs import asdict as _asdict +from ._funcs import astuple as _astuple +from ._make import ( + _DEFAULT_ON_SETATTR, + NOTHING, + _frozen_setattrs, + attrib, + attrs, +) +from .exceptions import UnannotatedAttributeError + + +def define( + maybe_cls=None, + *, + these=None, + repr=None, + unsafe_hash=None, + hash=None, + init=None, + slots=True, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=None, + kw_only=False, + cache_hash=False, + auto_exc=True, + eq=None, + order=False, + auto_detect=True, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, +): + r""" + A class decorator that adds :term:`dunder methods` according to + :term:`fields ` specified using :doc:`type annotations `, + `field()` calls, or the *these* argument. + + Since *attrs* patches or replaces an existing class, you cannot use + `object.__init_subclass__` with *attrs* classes, because it runs too early. + As a replacement, you can define ``__attrs_init_subclass__`` on your class. + It will be called by *attrs* classes that subclass it after they're + created. See also :ref:`init-subclass`. + + Args: + slots (bool): + Create a :term:`slotted class ` that's more + memory-efficient. Slotted classes are generally superior to the + default dict classes, but have some gotchas you should know about, + so we encourage you to read the :term:`glossary entry `. + + auto_detect (bool): + Instead of setting the *init*, *repr*, *eq*, and *hash* arguments + explicitly, assume they are set to True **unless any** of the + involved methods for one of the arguments is implemented in the + *current* class (meaning, it is *not* inherited from some base + class). + + So, for example by implementing ``__eq__`` on a class yourself, + *attrs* will deduce ``eq=False`` and will create *neither* + ``__eq__`` *nor* ``__ne__`` (but Python classes come with a + sensible ``__ne__`` by default, so it *should* be enough to only + implement ``__eq__`` in most cases). + + Passing True or False` to *init*, *repr*, *eq*, *cmp*, or *hash* + overrides whatever *auto_detect* would determine. + + auto_exc (bool): + If the class subclasses `BaseException` (which implicitly includes + any subclass of any exception), the following happens to behave + like a well-behaved Python exception class: + + - the values for *eq*, *order*, and *hash* are ignored and the + instances compare and hash by the instance's ids [#]_ , + - all attributes that are either passed into ``__init__`` or have a + default value are additionally available as a tuple in the + ``args`` attribute, + - the value of *str* is ignored leaving ``__str__`` to base + classes. + + .. [#] + Note that *attrs* will *not* remove existing implementations of + ``__hash__`` or the equality methods. It just won't add own + ones. + + on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): + A callable that is run whenever the user attempts to set an + attribute (either by assignment like ``i.x = 42`` or by using + `setattr` like ``setattr(i, "x", 42)``). It receives the same + arguments as validators: the instance, the attribute that is being + modified, and the new value. + + If no exception is raised, the attribute is set to the return value + of the callable. + + If a list of callables is passed, they're automatically wrapped in + an `attrs.setters.pipe`. + + If left None, the default behavior is to run converters and + validators whenever an attribute is set. + + init (bool): + Create a ``__init__`` method that initializes the *attrs* + attributes. Leading underscores are stripped for the argument name, + unless an alias is set on the attribute. + + .. seealso:: + `init` shows advanced ways to customize the generated + ``__init__`` method, including executing code before and after. + + repr(bool): + Create a ``__repr__`` method with a human readable representation + of *attrs* attributes. + + str (bool): + Create a ``__str__`` method that is identical to ``__repr__``. This + is usually not necessary except for `Exception`\ s. + + eq (bool | None): + If True or None (default), add ``__eq__`` and ``__ne__`` methods + that check two instances for equality. + + .. seealso:: + `comparison` describes how to customize the comparison behavior + going as far comparing NumPy arrays. + + order (bool | None): + If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` + methods that behave like *eq* above and allow instances to be + ordered. + + They compare the instances as if they were tuples of their *attrs* + attributes if and only if the types of both classes are + *identical*. + + If `None` mirror value of *eq*. + + .. seealso:: `comparison` + + cmp (bool | None): + Setting *cmp* is equivalent to setting *eq* and *order* to the same + value. Must not be mixed with *eq* or *order*. + + unsafe_hash (bool | None): + If None (default), the ``__hash__`` method is generated according + how *eq* and *frozen* are set. + + 1. If *both* are True, *attrs* will generate a ``__hash__`` for + you. + 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set + to None, marking it unhashable (which it is). + 3. If *eq* is False, ``__hash__`` will be left untouched meaning + the ``__hash__`` method of the base class will be used. If the + base class is `object`, this means it will fall back to id-based + hashing. + + Although not recommended, you can decide for yourself and force + *attrs* to create one (for example, if the class is immutable even + though you didn't freeze it programmatically) by passing True or + not. Both of these cases are rather special and should be used + carefully. + + .. seealso:: + + - Our documentation on `hashing`, + - Python's documentation on `object.__hash__`, + - and the `GitHub issue that led to the default \ behavior + `_ for more + details. + + hash (bool | None): + Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence. + + cache_hash (bool): + Ensure that the object's hash code is computed only once and stored + on the object. If this is set to True, hashing must be either + explicitly or implicitly enabled for this class. If the hash code + is cached, avoid any reassignments of fields involved in hash code + computation or mutations of the objects those fields point to after + object creation. If such changes occur, the behavior of the + object's hash code is undefined. + + frozen (bool): + Make instances immutable after initialization. If someone attempts + to modify a frozen instance, `attrs.exceptions.FrozenInstanceError` + is raised. + + .. note:: + + 1. This is achieved by installing a custom ``__setattr__`` + method on your class, so you can't implement your own. + + 2. True immutability is impossible in Python. + + 3. This *does* have a minor a runtime performance `impact + ` when initializing new instances. In other + words: ``__init__`` is slightly slower with ``frozen=True``. + + 4. If a class is frozen, you cannot modify ``self`` in + ``__attrs_post_init__`` or a self-written ``__init__``. You + can circumvent that limitation by using + ``object.__setattr__(self, "attribute_name", value)``. + + 5. Subclasses of a frozen class are frozen too. + + kw_only (bool): + Make all attributes keyword-only in the generated ``__init__`` (if + *init* is False, this parameter is ignored). + + weakref_slot (bool): + Make instances weak-referenceable. This has no effect unless + *slots* is True. + + field_transformer (~typing.Callable | None): + A function that is called with the original class object and all + fields right before *attrs* finalizes the class. You can use this, + for example, to automatically add converters or validators to + fields based on their types. + + .. seealso:: `transform-fields` + + match_args (bool): + If True (default), set ``__match_args__`` on the class to support + :pep:`634` (*Structural Pattern Matching*). It is a tuple of all + non-keyword-only ``__init__`` parameter names on Python 3.10 and + later. Ignored on older Python versions. + + collect_by_mro (bool): + If True, *attrs* collects attributes from base classes correctly + according to the `method resolution order + `_. If False, *attrs* + will mimic the (wrong) behavior of `dataclasses` and :pep:`681`. + + See also `issue #428 + `_. + + getstate_setstate (bool | None): + .. note:: + + This is usually only interesting for slotted classes and you + should probably just set *auto_detect* to True. + + If True, ``__getstate__`` and ``__setstate__`` are generated and + attached to the class. This is necessary for slotted classes to be + pickleable. If left None, it's True by default for slotted classes + and False for dict classes. + + If *auto_detect* is True, and *getstate_setstate* is left None, and + **either** ``__getstate__`` or ``__setstate__`` is detected + directly on the class (meaning: not inherited), it is set to False + (this is usually what you want). + + auto_attribs (bool | None): + If True, look at type annotations to determine which attributes to + use, like `dataclasses`. If False, it will only look for explicit + :func:`field` class attributes, like classic *attrs*. + + If left None, it will guess: + + 1. If any attributes are annotated and no unannotated + `attrs.field`\ s are found, it assumes *auto_attribs=True*. + 2. Otherwise it assumes *auto_attribs=False* and tries to collect + `attrs.field`\ s. + + If *attrs* decides to look at type annotations, **all** fields + **must** be annotated. If *attrs* encounters a field that is set to + a :func:`field` / `attr.ib` but lacks a type annotation, an + `attrs.exceptions.UnannotatedAttributeError` is raised. Use + ``field_name: typing.Any = field(...)`` if you don't want to set a + type. + + .. warning:: + + For features that use the attribute name to create decorators + (for example, :ref:`validators `), you still *must* + assign :func:`field` / `attr.ib` to them. Otherwise Python will + either not find the name or try to use the default value to + call, for example, ``validator`` on it. + + Attributes annotated as `typing.ClassVar`, and attributes that are + neither annotated nor set to an `field()` are **ignored**. + + these (dict[str, object]): + A dictionary of name to the (private) return value of `field()` + mappings. This is useful to avoid the definition of your attributes + within the class body because you can't (for example, if you want + to add ``__repr__`` methods to Django models) or don't want to. + + If *these* is not `None`, *attrs* will *not* search the class body + for attributes and will *not* remove any attributes from it. + + The order is deduced from the order of the attributes inside + *these*. + + Arguably, this is a rather obscure feature. + + .. versionadded:: 20.1.0 + .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). + .. versionchanged:: 24.1.0 + Instances are not compared as tuples of attributes anymore, but using a + big ``and`` condition. This is faster and has more correct behavior for + uncomparable values like `math.nan`. + .. versionadded:: 24.1.0 + If a class has an *inherited* classmethod called + ``__attrs_init_subclass__``, it is executed after the class is created. + .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*. + + .. note:: + + The main differences to the classic `attr.s` are: + + - Automatically detect whether or not *auto_attribs* should be `True` + (c.f. *auto_attribs* parameter). + - Converters and validators run when attributes are set by default -- + if *frozen* is `False`. + - *slots=True* + + Usually, this has only upsides and few visible effects in everyday + programming. But it *can* lead to some surprising behaviors, so + please make sure to read :term:`slotted classes`. + + - *auto_exc=True* + - *auto_detect=True* + - *order=False* + - Some options that were only relevant on Python 2 or were kept around + for backwards-compatibility have been removed. + + """ + + def do_it(cls, auto_attribs): + return attrs( + maybe_cls=cls, + these=these, + repr=repr, + hash=hash, + unsafe_hash=unsafe_hash, + init=init, + slots=slots, + frozen=frozen, + weakref_slot=weakref_slot, + str=str, + auto_attribs=auto_attribs, + kw_only=kw_only, + cache_hash=cache_hash, + auto_exc=auto_exc, + eq=eq, + order=order, + auto_detect=auto_detect, + collect_by_mro=True, + getstate_setstate=getstate_setstate, + on_setattr=on_setattr, + field_transformer=field_transformer, + match_args=match_args, + ) + + def wrap(cls): + """ + Making this a wrapper ensures this code runs during class creation. + + We also ensure that frozen-ness of classes is inherited. + """ + nonlocal frozen, on_setattr + + had_on_setattr = on_setattr not in (None, setters.NO_OP) + + # By default, mutable classes convert & validate on setattr. + if frozen is False and on_setattr is None: + on_setattr = _DEFAULT_ON_SETATTR + + # However, if we subclass a frozen class, we inherit the immutability + # and disable on_setattr. + for base_cls in cls.__bases__: + if base_cls.__setattr__ is _frozen_setattrs: + if had_on_setattr: + msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)." + raise ValueError(msg) + + on_setattr = setters.NO_OP + break + + if auto_attribs is not None: + return do_it(cls, auto_attribs) + + try: + return do_it(cls, True) + except UnannotatedAttributeError: + return do_it(cls, False) + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but `None` if used as `@attrs()`. + if maybe_cls is None: + return wrap + + return wrap(maybe_cls) + + +mutable = define +frozen = partial(define, frozen=True, on_setattr=None) + + +def field( + *, + default=NOTHING, + validator=None, + repr=True, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, + alias=None, +): + """ + Create a new :term:`field` / :term:`attribute` on a class. + + .. warning:: + + Does **nothing** unless the class is also decorated with + `attrs.define` (or similar)! + + Args: + default: + A value that is used if an *attrs*-generated ``__init__`` is used + and no value is passed while instantiating or the attribute is + excluded using ``init=False``. + + If the value is an instance of `attrs.Factory`, its callable will + be used to construct a new value (useful for mutable data types + like lists or dicts). + + If a default is not set (or set manually to `attrs.NOTHING`), a + value *must* be supplied when instantiating; otherwise a + `TypeError` will be raised. + + .. seealso:: `defaults` + + factory (~typing.Callable): + Syntactic sugar for ``default=attr.Factory(factory)``. + + validator (~typing.Callable | list[~typing.Callable]): + Callable that is called by *attrs*-generated ``__init__`` methods + after the instance has been initialized. They receive the + initialized instance, the :func:`~attrs.Attribute`, and the passed + value. + + The return value is *not* inspected so the validator has to throw + an exception itself. + + If a `list` is passed, its items are treated as validators and must + all pass. + + Validators can be globally disabled and re-enabled using + `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. + + The validator can also be set using decorator notation as shown + below. + + .. seealso:: :ref:`validators` + + repr (bool | ~typing.Callable): + Include this attribute in the generated ``__repr__`` method. If + True, include the attribute; if False, omit it. By default, the + built-in ``repr()`` function is used. To override how the attribute + value is formatted, pass a ``callable`` that takes a single value + and returns a string. Note that the resulting string is used as-is, + which means it will be used directly *instead* of calling + ``repr()`` (the default). + + eq (bool | ~typing.Callable): + If True (default), include this attribute in the generated + ``__eq__`` and ``__ne__`` methods that check two instances for + equality. To override how the attribute value is compared, pass a + callable that takes a single value and returns the value to be + compared. + + .. seealso:: `comparison` + + order (bool | ~typing.Callable): + If True (default), include this attributes in the generated + ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To + override how the attribute value is ordered, pass a callable that + takes a single value and returns the value to be ordered. + + .. seealso:: `comparison` + + cmp(bool | ~typing.Callable): + Setting *cmp* is equivalent to setting *eq* and *order* to the same + value. Must not be mixed with *eq* or *order*. + + .. seealso:: `comparison` + + hash (bool | None): + Include this attribute in the generated ``__hash__`` method. If + None (default), mirror *eq*'s value. This is the correct behavior + according the Python spec. Setting this value to anything else + than None is *discouraged*. + + .. seealso:: `hashing` + + init (bool): + Include this attribute in the generated ``__init__`` method. + + It is possible to set this to False and set a default value. In + that case this attributed is unconditionally initialized with the + specified default value or factory. + + .. seealso:: `init` + + converter (typing.Callable | Converter): + A callable that is called by *attrs*-generated ``__init__`` methods + to convert attribute's value to the desired format. + + If a vanilla callable is passed, it is given the passed-in value as + the only positional argument. It is possible to receive additional + arguments by wrapping the callable in a `Converter`. + + Either way, the returned value will be used as the new value of the + attribute. The value is converted before being passed to the + validator, if any. + + .. seealso:: :ref:`converters` + + metadata (dict | None): + An arbitrary mapping, to be used by third-party code. + + .. seealso:: `extending-metadata`. + + type (type): + The type of the attribute. Nowadays, the preferred method to + specify the type is using a variable annotation (see :pep:`526`). + This argument is provided for backwards-compatibility and for usage + with `make_class`. Regardless of the approach used, the type will + be stored on ``Attribute.type``. + + Please note that *attrs* doesn't do anything with this metadata by + itself. You can use it as part of your own code or for `static type + checking `. + + kw_only (bool): + Make this attribute keyword-only in the generated ``__init__`` (if + ``init`` is False, this parameter is ignored). + + on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): + Allows to overwrite the *on_setattr* setting from `attr.s`. If left + None, the *on_setattr* value from `attr.s` is used. Set to + `attrs.setters.NO_OP` to run **no** `setattr` hooks for this + attribute -- regardless of the setting in `define()`. + + alias (str | None): + Override this attribute's parameter name in the generated + ``__init__`` method. If left None, default to ``name`` stripped + of leading underscores. See `private-attributes`. + + .. versionadded:: 20.1.0 + .. versionchanged:: 21.1.0 + *eq*, *order*, and *cmp* also accept a custom callable + .. versionadded:: 22.2.0 *alias* + .. versionadded:: 23.1.0 + The *type* parameter has been re-added; mostly for `attrs.make_class`. + Please note that type checkers ignore this metadata. + + .. seealso:: + + `attr.ib` + """ + return attrib( + default=default, + validator=validator, + repr=repr, + hash=hash, + init=init, + metadata=metadata, + type=type, + converter=converter, + factory=factory, + kw_only=kw_only, + eq=eq, + order=order, + on_setattr=on_setattr, + alias=alias, + ) + + +def asdict(inst, *, recurse=True, filter=None, value_serializer=None): + """ + Same as `attr.asdict`, except that collections types are always retained + and dict is always used as *dict_factory*. + + .. versionadded:: 21.3.0 + """ + return _asdict( + inst=inst, + recurse=recurse, + filter=filter, + value_serializer=value_serializer, + retain_collection_types=True, + ) + + +def astuple(inst, *, recurse=True, filter=None): + """ + Same as `attr.astuple`, except that collections types are always retained + and `tuple` is always used as the *tuple_factory*. + + .. versionadded:: 21.3.0 + """ + return _astuple( + inst=inst, recurse=recurse, filter=filter, retain_collection_types=True + ) diff --git a/.venv/lib/python3.7/site-packages/attr/_typing_compat.pyi b/.venv/lib/python3.7/site-packages/attr/_typing_compat.pyi new file mode 100644 index 0000000..ca7b71e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_typing_compat.pyi @@ -0,0 +1,15 @@ +from typing import Any, ClassVar, Protocol + +# MYPY is a special constant in mypy which works the same way as `TYPE_CHECKING`. +MYPY = False + +if MYPY: + # A protocol to be able to statically accept an attrs class. + class AttrsInstance_(Protocol): + __attrs_attrs__: ClassVar[Any] + +else: + # For type checkers without plug-in support use an empty protocol that + # will (hopefully) be combined into a union. + class AttrsInstance_(Protocol): + pass diff --git a/.venv/lib/python3.7/site-packages/attr/_version_info.py b/.venv/lib/python3.7/site-packages/attr/_version_info.py new file mode 100644 index 0000000..51a1312 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_version_info.py @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: MIT + + +from functools import total_ordering + +from ._funcs import astuple +from ._make import attrib, attrs + + +@total_ordering +@attrs(eq=False, order=False, slots=True, frozen=True) +class VersionInfo: + """ + A version object that can be compared to tuple of length 1--4: + + >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) + True + >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) + True + >>> vi = attr.VersionInfo(19, 2, 0, "final") + >>> vi < (19, 1, 1) + False + >>> vi < (19,) + False + >>> vi == (19, 2,) + True + >>> vi == (19, 2, 1) + False + + .. versionadded:: 19.2 + """ + + year = attrib(type=int) + minor = attrib(type=int) + micro = attrib(type=int) + releaselevel = attrib(type=str) + + @classmethod + def _from_version_string(cls, s): + """ + Parse *s* and return a _VersionInfo. + """ + v = s.split(".") + if len(v) == 3: + v.append("final") + + return cls( + year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] + ) + + def _ensure_tuple(self, other): + """ + Ensure *other* is a tuple of a valid length. + + Returns a possibly transformed *other* and ourselves as a tuple of + the same length as *other*. + """ + + if self.__class__ is other.__class__: + other = astuple(other) + + if not isinstance(other, tuple): + raise NotImplementedError + + if not (1 <= len(other) <= 4): + raise NotImplementedError + + return astuple(self)[: len(other)], other + + def __eq__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + return us == them + + def __lt__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't + # have to do anything special with releaselevel for now. + return us < them diff --git a/.venv/lib/python3.7/site-packages/attr/_version_info.pyi b/.venv/lib/python3.7/site-packages/attr/_version_info.pyi new file mode 100644 index 0000000..45ced08 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/_version_info.pyi @@ -0,0 +1,9 @@ +class VersionInfo: + @property + def year(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... diff --git a/.venv/lib/python3.7/site-packages/attr/converters.py b/.venv/lib/python3.7/site-packages/attr/converters.py new file mode 100644 index 0000000..9238311 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/converters.py @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful converters. +""" + + +import typing + +from ._compat import _AnnotationExtractor +from ._make import NOTHING, Factory, pipe + + +__all__ = [ + "default_if_none", + "optional", + "pipe", + "to_bool", +] + + +def optional(converter): + """ + A converter that allows an attribute to be optional. An optional attribute + is one which can be set to `None`. + + Type annotations will be inferred from the wrapped converter's, if it has + any. + + Args: + converter (typing.Callable): + the converter that is used for non-`None` values. + + .. versionadded:: 17.1.0 + """ + + def optional_converter(val): + if val is None: + return None + return converter(val) + + xtr = _AnnotationExtractor(converter) + + t = xtr.get_first_param_type() + if t: + optional_converter.__annotations__["val"] = typing.Optional[t] + + rt = xtr.get_return_type() + if rt: + optional_converter.__annotations__["return"] = typing.Optional[rt] + + return optional_converter + + +def default_if_none(default=NOTHING, factory=None): + """ + A converter that allows to replace `None` values by *default* or the result + of *factory*. + + Args: + default: + Value to be used if `None` is passed. Passing an instance of + `attrs.Factory` is supported, however the ``takes_self`` option is + *not*. + + factory (typing.Callable): + A callable that takes no parameters whose result is used if `None` + is passed. + + Raises: + TypeError: If **neither** *default* or *factory* is passed. + + TypeError: If **both** *default* and *factory* are passed. + + ValueError: + If an instance of `attrs.Factory` is passed with + ``takes_self=True``. + + .. versionadded:: 18.2.0 + """ + if default is NOTHING and factory is None: + msg = "Must pass either `default` or `factory`." + raise TypeError(msg) + + if default is not NOTHING and factory is not None: + msg = "Must pass either `default` or `factory` but not both." + raise TypeError(msg) + + if factory is not None: + default = Factory(factory) + + if isinstance(default, Factory): + if default.takes_self: + msg = "`takes_self` is not supported by default_if_none." + raise ValueError(msg) + + def default_if_none_converter(val): + if val is not None: + return val + + return default.factory() + + else: + + def default_if_none_converter(val): + if val is not None: + return val + + return default + + return default_if_none_converter + + +def to_bool(val): + """ + Convert "boolean" strings (for example, from environment variables) to real + booleans. + + Values mapping to `True`: + + - ``True`` + - ``"true"`` / ``"t"`` + - ``"yes"`` / ``"y"`` + - ``"on"`` + - ``"1"`` + - ``1`` + + Values mapping to `False`: + + - ``False`` + - ``"false"`` / ``"f"`` + - ``"no"`` / ``"n"`` + - ``"off"`` + - ``"0"`` + - ``0`` + + Raises: + ValueError: For any other value. + + .. versionadded:: 21.3.0 + """ + if isinstance(val, str): + val = val.lower() + + if val in (True, "true", "t", "yes", "y", "on", "1", 1): + return True + if val in (False, "false", "f", "no", "n", "off", "0", 0): + return False + + msg = f"Cannot convert value to bool: {val!r}" + raise ValueError(msg) diff --git a/.venv/lib/python3.7/site-packages/attr/converters.pyi b/.venv/lib/python3.7/site-packages/attr/converters.pyi new file mode 100644 index 0000000..9ef478f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/converters.pyi @@ -0,0 +1,13 @@ +from typing import Callable, TypeVar, overload + +from attrs import _ConverterType + +_T = TypeVar("_T") + +def pipe(*validators: _ConverterType) -> _ConverterType: ... +def optional(converter: _ConverterType) -> _ConverterType: ... +@overload +def default_if_none(default: _T) -> _ConverterType: ... +@overload +def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... +def to_bool(val: str) -> bool: ... diff --git a/.venv/lib/python3.7/site-packages/attr/exceptions.py b/.venv/lib/python3.7/site-packages/attr/exceptions.py new file mode 100644 index 0000000..3b7abb8 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/exceptions.py @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: MIT + +from __future__ import annotations + +from typing import ClassVar + + +class FrozenError(AttributeError): + """ + A frozen/immutable instance or attribute have been attempted to be + modified. + + It mirrors the behavior of ``namedtuples`` by using the same error message + and subclassing `AttributeError`. + + .. versionadded:: 20.1.0 + """ + + msg = "can't set attribute" + args: ClassVar[tuple[str]] = [msg] + + +class FrozenInstanceError(FrozenError): + """ + A frozen instance has been attempted to be modified. + + .. versionadded:: 16.1.0 + """ + + +class FrozenAttributeError(FrozenError): + """ + A frozen attribute has been attempted to be modified. + + .. versionadded:: 20.1.0 + """ + + +class AttrsAttributeNotFoundError(ValueError): + """ + An *attrs* function couldn't find an attribute that the user asked for. + + .. versionadded:: 16.2.0 + """ + + +class NotAnAttrsClassError(ValueError): + """ + A non-*attrs* class has been passed into an *attrs* function. + + .. versionadded:: 16.2.0 + """ + + +class DefaultAlreadySetError(RuntimeError): + """ + A default has been set when defining the field and is attempted to be reset + using the decorator. + + .. versionadded:: 17.1.0 + """ + + +class UnannotatedAttributeError(RuntimeError): + """ + A class with ``auto_attribs=True`` has a field without a type annotation. + + .. versionadded:: 17.3.0 + """ + + +class PythonTooOldError(RuntimeError): + """ + It was attempted to use an *attrs* feature that requires a newer Python + version. + + .. versionadded:: 18.2.0 + """ + + +class NotCallableError(TypeError): + """ + A field requiring a callable has been set with a value that is not + callable. + + .. versionadded:: 19.2.0 + """ + + def __init__(self, msg, value): + super(TypeError, self).__init__(msg, value) + self.msg = msg + self.value = value + + def __str__(self): + return str(self.msg) diff --git a/.venv/lib/python3.7/site-packages/attr/exceptions.pyi b/.venv/lib/python3.7/site-packages/attr/exceptions.pyi new file mode 100644 index 0000000..f268011 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/exceptions.pyi @@ -0,0 +1,17 @@ +from typing import Any + +class FrozenError(AttributeError): + msg: str = ... + +class FrozenInstanceError(FrozenError): ... +class FrozenAttributeError(FrozenError): ... +class AttrsAttributeNotFoundError(ValueError): ... +class NotAnAttrsClassError(ValueError): ... +class DefaultAlreadySetError(RuntimeError): ... +class UnannotatedAttributeError(RuntimeError): ... +class PythonTooOldError(RuntimeError): ... + +class NotCallableError(TypeError): + msg: str = ... + value: Any = ... + def __init__(self, msg: str, value: Any) -> None: ... diff --git a/.venv/lib/python3.7/site-packages/attr/filters.py b/.venv/lib/python3.7/site-packages/attr/filters.py new file mode 100644 index 0000000..689b170 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/filters.py @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful filters for `attrs.asdict` and `attrs.astuple`. +""" + +from ._make import Attribute + + +def _split_what(what): + """ + Returns a tuple of `frozenset`s of classes and attributes. + """ + return ( + frozenset(cls for cls in what if isinstance(cls, type)), + frozenset(cls for cls in what if isinstance(cls, str)), + frozenset(cls for cls in what if isinstance(cls, Attribute)), + ) + + +def include(*what): + """ + Create a filter that only allows *what*. + + Args: + what (list[type, str, attrs.Attribute]): + What to include. Can be a type, a name, or an attribute. + + Returns: + Callable: + A callable that can be passed to `attrs.asdict`'s and + `attrs.astuple`'s *filter* argument. + + .. versionchanged:: 23.1.0 Accept strings with field names. + """ + cls, names, attrs = _split_what(what) + + def include_(attribute, value): + return ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) + + return include_ + + +def exclude(*what): + """ + Create a filter that does **not** allow *what*. + + Args: + what (list[type, str, attrs.Attribute]): + What to exclude. Can be a type, a name, or an attribute. + + Returns: + Callable: + A callable that can be passed to `attrs.asdict`'s and + `attrs.astuple`'s *filter* argument. + + .. versionchanged:: 23.3.0 Accept field name string as input argument + """ + cls, names, attrs = _split_what(what) + + def exclude_(attribute, value): + return not ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) + + return exclude_ diff --git a/.venv/lib/python3.7/site-packages/attr/filters.pyi b/.venv/lib/python3.7/site-packages/attr/filters.pyi new file mode 100644 index 0000000..974abdc --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/filters.pyi @@ -0,0 +1,6 @@ +from typing import Any + +from . import Attribute, _FilterType + +def include(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... +def exclude(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... diff --git a/.venv/lib/python3.7/site-packages/attr/py.typed b/.venv/lib/python3.7/site-packages/attr/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/attr/setters.py b/.venv/lib/python3.7/site-packages/attr/setters.py new file mode 100644 index 0000000..a9ce016 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/setters.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly used hooks for on_setattr. +""" + +from . import _config +from .exceptions import FrozenAttributeError + + +def pipe(*setters): + """ + Run all *setters* and return the return value of the last one. + + .. versionadded:: 20.1.0 + """ + + def wrapped_pipe(instance, attrib, new_value): + rv = new_value + + for setter in setters: + rv = setter(instance, attrib, rv) + + return rv + + return wrapped_pipe + + +def frozen(_, __, ___): + """ + Prevent an attribute to be modified. + + .. versionadded:: 20.1.0 + """ + raise FrozenAttributeError() + + +def validate(instance, attrib, new_value): + """ + Run *attrib*'s validator on *new_value* if it has one. + + .. versionadded:: 20.1.0 + """ + if _config._run_validators is False: + return new_value + + v = attrib.validator + if not v: + return new_value + + v(instance, attrib, new_value) + + return new_value + + +def convert(instance, attrib, new_value): + """ + Run *attrib*'s converter -- if it has one -- on *new_value* and return the + result. + + .. versionadded:: 20.1.0 + """ + c = attrib.converter + if c: + # This can be removed once we drop 3.8 and use attrs.Converter instead. + from ._make import Converter + + if not isinstance(c, Converter): + return c(new_value) + + return c(new_value, instance, attrib) + + return new_value + + +# Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. +# Sphinx's autodata stopped working, so the docstring is inlined in the API +# docs. +NO_OP = object() diff --git a/.venv/lib/python3.7/site-packages/attr/setters.pyi b/.venv/lib/python3.7/site-packages/attr/setters.pyi new file mode 100644 index 0000000..73abf36 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/setters.pyi @@ -0,0 +1,20 @@ +from typing import Any, NewType, NoReturn, TypeVar + +from . import Attribute +from attrs import _OnSetAttrType + +_T = TypeVar("_T") + +def frozen( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> NoReturn: ... +def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... +def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... + +# convert is allowed to return Any, because they can be chained using pipe. +def convert( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> Any: ... + +_NoOpType = NewType("_NoOpType", object) +NO_OP: _NoOpType diff --git a/.venv/lib/python3.7/site-packages/attr/validators.py b/.venv/lib/python3.7/site-packages/attr/validators.py new file mode 100644 index 0000000..8a56717 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/validators.py @@ -0,0 +1,711 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful validators. +""" + + +import operator +import re + +from contextlib import contextmanager +from re import Pattern + +from ._config import get_run_validators, set_run_validators +from ._make import _AndValidator, and_, attrib, attrs +from .converters import default_if_none +from .exceptions import NotCallableError + + +__all__ = [ + "and_", + "deep_iterable", + "deep_mapping", + "disabled", + "ge", + "get_disabled", + "gt", + "in_", + "instance_of", + "is_callable", + "le", + "lt", + "matches_re", + "max_len", + "min_len", + "not_", + "optional", + "or_", + "set_disabled", +] + + +def set_disabled(disabled): + """ + Globally disable or enable running validators. + + By default, they are run. + + Args: + disabled (bool): If `True`, disable running all validators. + + .. warning:: + + This function is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(not disabled) + + +def get_disabled(): + """ + Return a bool indicating whether validators are currently disabled or not. + + Returns: + bool:`True` if validators are currently disabled. + + .. versionadded:: 21.3.0 + """ + return not get_run_validators() + + +@contextmanager +def disabled(): + """ + Context manager that disables running validators within its context. + + .. warning:: + + This context manager is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(False) + try: + yield + finally: + set_run_validators(True) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _InstanceOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not isinstance(value, self.type): + msg = f"'{attr.name}' must be {self.type!r} (got {value!r} that is a {value.__class__!r})." + raise TypeError( + msg, + attr, + self.type, + value, + ) + + def __repr__(self): + return f"" + + +def instance_of(type): + """ + A validator that raises a `TypeError` if the initializer is called with a + wrong type for this particular attribute (checks are performed using + `isinstance` therefore it's also valid to pass a tuple of types). + + Args: + type (type | tuple[type]): The type to check for. + + Raises: + TypeError: + With a human readable error message, the attribute (of type + `attrs.Attribute`), the expected type, and the value it got. + """ + return _InstanceOfValidator(type) + + +@attrs(repr=False, frozen=True, slots=True) +class _MatchesReValidator: + pattern = attrib() + match_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.match_func(value): + msg = f"'{attr.name}' must match regex {self.pattern.pattern!r} ({value!r} doesn't)" + raise ValueError( + msg, + attr, + self.pattern, + value, + ) + + def __repr__(self): + return f"" + + +def matches_re(regex, flags=0, func=None): + r""" + A validator that raises `ValueError` if the initializer is called with a + string that doesn't match *regex*. + + Args: + regex (str, re.Pattern): + A regex string or precompiled pattern to match against + + flags (int): + Flags that will be passed to the underlying re function (default 0) + + func (typing.Callable): + Which underlying `re` function to call. Valid options are + `re.fullmatch`, `re.search`, and `re.match`; the default `None` + means `re.fullmatch`. For performance reasons, the pattern is + always precompiled using `re.compile`. + + .. versionadded:: 19.2.0 + .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern. + """ + valid_funcs = (re.fullmatch, None, re.search, re.match) + if func not in valid_funcs: + msg = "'func' must be one of {}.".format( + ", ".join( + sorted(e and e.__name__ or "None" for e in set(valid_funcs)) + ) + ) + raise ValueError(msg) + + if isinstance(regex, Pattern): + if flags: + msg = "'flags' can only be used with a string pattern; pass flags to re.compile() instead" + raise TypeError(msg) + pattern = regex + else: + pattern = re.compile(regex, flags) + + if func is re.match: + match_func = pattern.match + elif func is re.search: + match_func = pattern.search + else: + match_func = pattern.fullmatch + + return _MatchesReValidator(pattern, match_func) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _OptionalValidator: + validator = attrib() + + def __call__(self, inst, attr, value): + if value is None: + return + + self.validator(inst, attr, value) + + def __repr__(self): + return f"" + + +def optional(validator): + """ + A validator that makes an attribute optional. An optional attribute is one + which can be set to `None` in addition to satisfying the requirements of + the sub-validator. + + Args: + validator + (typing.Callable | tuple[typing.Callable] | list[typing.Callable]): + A validator (or validators) that is used for non-`None` values. + + .. versionadded:: 15.1.0 + .. versionchanged:: 17.1.0 *validator* can be a list of validators. + .. versionchanged:: 23.1.0 *validator* can also be a tuple of validators. + """ + if isinstance(validator, (list, tuple)): + return _OptionalValidator(_AndValidator(validator)) + + return _OptionalValidator(validator) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _InValidator: + options = attrib() + _original_options = attrib(hash=False) + + def __call__(self, inst, attr, value): + try: + in_options = value in self.options + except TypeError: # e.g. `1 in "abc"` + in_options = False + + if not in_options: + msg = f"'{attr.name}' must be in {self._original_options!r} (got {value!r})" + raise ValueError( + msg, + attr, + self._original_options, + value, + ) + + def __repr__(self): + return f"" + + +def in_(options): + """ + A validator that raises a `ValueError` if the initializer is called with a + value that does not belong in the *options* provided. + + The check is performed using ``value in options``, so *options* has to + support that operation. + + To keep the validator hashable, dicts, lists, and sets are transparently + transformed into a `tuple`. + + Args: + options: Allowed options. + + Raises: + ValueError: + With a human readable error message, the attribute (of type + `attrs.Attribute`), the expected options, and the value it got. + + .. versionadded:: 17.1.0 + .. versionchanged:: 22.1.0 + The ValueError was incomplete until now and only contained the human + readable error message. Now it contains all the information that has + been promised since 17.1.0. + .. versionchanged:: 24.1.0 + *options* that are a list, dict, or a set are now transformed into a + tuple to keep the validator hashable. + """ + repr_options = options + if isinstance(options, (list, dict, set)): + options = tuple(options) + + return _InValidator(options, repr_options) + + +@attrs(repr=False, slots=False, unsafe_hash=True) +class _IsCallableValidator: + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not callable(value): + message = ( + "'{name}' must be callable " + "(got {value!r} that is a {actual!r})." + ) + raise NotCallableError( + msg=message.format( + name=attr.name, value=value, actual=value.__class__ + ), + value=value, + ) + + def __repr__(self): + return "" + + +def is_callable(): + """ + A validator that raises a `attrs.exceptions.NotCallableError` if the + initializer is called with a value for this particular attribute that is + not callable. + + .. versionadded:: 19.1.0 + + Raises: + attrs.exceptions.NotCallableError: + With a human readable error message containing the attribute + (`attrs.Attribute`) name, and the value it got. + """ + return _IsCallableValidator() + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _DeepIterable: + member_validator = attrib(validator=is_callable()) + iterable_validator = attrib( + default=None, validator=optional(is_callable()) + ) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.iterable_validator is not None: + self.iterable_validator(inst, attr, value) + + for member in value: + self.member_validator(inst, attr, member) + + def __repr__(self): + iterable_identifier = ( + "" + if self.iterable_validator is None + else f" {self.iterable_validator!r}" + ) + return ( + f"" + ) + + +def deep_iterable(member_validator, iterable_validator=None): + """ + A validator that performs deep validation of an iterable. + + Args: + member_validator: Validator to apply to iterable members. + + iterable_validator: + Validator to apply to iterable itself (optional). + + Raises + TypeError: if any sub-validators fail + + .. versionadded:: 19.1.0 + """ + if isinstance(member_validator, (list, tuple)): + member_validator = and_(*member_validator) + return _DeepIterable(member_validator, iterable_validator) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _DeepMapping: + key_validator = attrib(validator=is_callable()) + value_validator = attrib(validator=is_callable()) + mapping_validator = attrib(default=None, validator=optional(is_callable())) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.mapping_validator is not None: + self.mapping_validator(inst, attr, value) + + for key in value: + self.key_validator(inst, attr, key) + self.value_validator(inst, attr, value[key]) + + def __repr__(self): + return f"" + + +def deep_mapping(key_validator, value_validator, mapping_validator=None): + """ + A validator that performs deep validation of a dictionary. + + Args: + key_validator: Validator to apply to dictionary keys. + + value_validator: Validator to apply to dictionary values. + + mapping_validator: + Validator to apply to top-level mapping attribute (optional). + + .. versionadded:: 19.1.0 + + Raises: + TypeError: if any sub-validators fail + """ + return _DeepMapping(key_validator, value_validator, mapping_validator) + + +@attrs(repr=False, frozen=True, slots=True) +class _NumberValidator: + bound = attrib() + compare_op = attrib() + compare_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.compare_func(value, self.bound): + msg = f"'{attr.name}' must be {self.compare_op} {self.bound}: {value}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def lt(val): + """ + A validator that raises `ValueError` if the initializer is called with a + number larger or equal to *val*. + + The validator uses `operator.lt` to compare the values. + + Args: + val: Exclusive upper bound for values. + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<", operator.lt) + + +def le(val): + """ + A validator that raises `ValueError` if the initializer is called with a + number greater than *val*. + + The validator uses `operator.le` to compare the values. + + Args: + val: Inclusive upper bound for values. + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<=", operator.le) + + +def ge(val): + """ + A validator that raises `ValueError` if the initializer is called with a + number smaller than *val*. + + The validator uses `operator.ge` to compare the values. + + Args: + val: Inclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">=", operator.ge) + + +def gt(val): + """ + A validator that raises `ValueError` if the initializer is called with a + number smaller or equal to *val*. + + The validator uses `operator.ge` to compare the values. + + Args: + val: Exclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">", operator.gt) + + +@attrs(repr=False, frozen=True, slots=True) +class _MaxLengthValidator: + max_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) > self.max_length: + msg = f"Length of '{attr.name}' must be <= {self.max_length}: {len(value)}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def max_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is longer than *length*. + + Args: + length (int): Maximum length of the string or iterable + + .. versionadded:: 21.3.0 + """ + return _MaxLengthValidator(length) + + +@attrs(repr=False, frozen=True, slots=True) +class _MinLengthValidator: + min_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) < self.min_length: + msg = f"Length of '{attr.name}' must be >= {self.min_length}: {len(value)}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def min_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is shorter than *length*. + + Args: + length (int): Minimum length of the string or iterable + + .. versionadded:: 22.1.0 + """ + return _MinLengthValidator(length) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _SubclassOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not issubclass(value, self.type): + msg = f"'{attr.name}' must be a subclass of {self.type!r} (got {value!r})." + raise TypeError( + msg, + attr, + self.type, + value, + ) + + def __repr__(self): + return f"" + + +def _subclass_of(type): + """ + A validator that raises a `TypeError` if the initializer is called with a + wrong type for this particular attribute (checks are performed using + `issubclass` therefore it's also valid to pass a tuple of types). + + Args: + type (type | tuple[type, ...]): The type(s) to check for. + + Raises: + TypeError: + With a human readable error message, the attribute (of type + `attrs.Attribute`), the expected type, and the value it got. + """ + return _SubclassOfValidator(type) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _NotValidator: + validator = attrib() + msg = attrib( + converter=default_if_none( + "not_ validator child '{validator!r}' " + "did not raise a captured error" + ) + ) + exc_types = attrib( + validator=deep_iterable( + member_validator=_subclass_of(Exception), + iterable_validator=instance_of(tuple), + ), + ) + + def __call__(self, inst, attr, value): + try: + self.validator(inst, attr, value) + except self.exc_types: + pass # suppress error to invert validity + else: + raise ValueError( + self.msg.format( + validator=self.validator, + exc_types=self.exc_types, + ), + attr, + self.validator, + value, + self.exc_types, + ) + + def __repr__(self): + return f"" + + +def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)): + """ + A validator that wraps and logically 'inverts' the validator passed to it. + It will raise a `ValueError` if the provided validator *doesn't* raise a + `ValueError` or `TypeError` (by default), and will suppress the exception + if the provided validator *does*. + + Intended to be used with existing validators to compose logic without + needing to create inverted variants, for example, ``not_(in_(...))``. + + Args: + validator: A validator to be logically inverted. + + msg (str): + Message to raise if validator fails. Formatted with keys + ``exc_types`` and ``validator``. + + exc_types (tuple[type, ...]): + Exception type(s) to capture. Other types raised by child + validators will not be intercepted and pass through. + + Raises: + ValueError: + With a human readable error message, the attribute (of type + `attrs.Attribute`), the validator that failed to raise an + exception, the value it got, and the expected exception types. + + .. versionadded:: 22.2.0 + """ + try: + exc_types = tuple(exc_types) + except TypeError: + exc_types = (exc_types,) + return _NotValidator(validator, msg, exc_types) + + +@attrs(repr=False, slots=True, unsafe_hash=True) +class _OrValidator: + validators = attrib() + + def __call__(self, inst, attr, value): + for v in self.validators: + try: + v(inst, attr, value) + except Exception: # noqa: BLE001, PERF203, S112 + continue + else: + return + + msg = f"None of {self.validators!r} satisfied for value {value!r}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def or_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators until one of them is + satisfied. + + Args: + validators (~collections.abc.Iterable[typing.Callable]): + Arbitrary number of validators. + + Raises: + ValueError: + If no validator is satisfied. Raised with a human-readable error + message listing all the wrapped validators and the value that + failed all of them. + + .. versionadded:: 24.1.0 + """ + vals = [] + for v in validators: + vals.extend(v.validators if isinstance(v, _OrValidator) else [v]) + + return _OrValidator(tuple(vals)) diff --git a/.venv/lib/python3.7/site-packages/attr/validators.pyi b/.venv/lib/python3.7/site-packages/attr/validators.pyi new file mode 100644 index 0000000..a314110 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attr/validators.pyi @@ -0,0 +1,83 @@ +from typing import ( + Any, + AnyStr, + Callable, + Container, + ContextManager, + Iterable, + Mapping, + Match, + Pattern, + TypeVar, + overload, +) + +from attrs import _ValidatorType +from attrs import _ValidatorArgType + +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") +_I = TypeVar("_I", bound=Iterable) +_K = TypeVar("_K") +_V = TypeVar("_V") +_M = TypeVar("_M", bound=Mapping) + +def set_disabled(run: bool) -> None: ... +def get_disabled() -> bool: ... +def disabled() -> ContextManager[None]: ... + +# To be more precise on instance_of use some overloads. +# If there are more than 3 items in the tuple then we fall back to Any +@overload +def instance_of(type: type[_T]) -> _ValidatorType[_T]: ... +@overload +def instance_of(type: tuple[type[_T]]) -> _ValidatorType[_T]: ... +@overload +def instance_of( + type: tuple[type[_T1], type[_T2]] +) -> _ValidatorType[_T1 | _T2]: ... +@overload +def instance_of( + type: tuple[type[_T1], type[_T2], type[_T3]] +) -> _ValidatorType[_T1 | _T2 | _T3]: ... +@overload +def instance_of(type: tuple[type, ...]) -> _ValidatorType[Any]: ... +def optional( + validator: ( + _ValidatorType[_T] + | list[_ValidatorType[_T]] + | tuple[_ValidatorType[_T]] + ), +) -> _ValidatorType[_T | None]: ... +def in_(options: Container[_T]) -> _ValidatorType[_T]: ... +def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... +def matches_re( + regex: Pattern[AnyStr] | AnyStr, + flags: int = ..., + func: Callable[[AnyStr, AnyStr, int], Match[AnyStr] | None] | None = ..., +) -> _ValidatorType[AnyStr]: ... +def deep_iterable( + member_validator: _ValidatorArgType[_T], + iterable_validator: _ValidatorType[_I] | None = ..., +) -> _ValidatorType[_I]: ... +def deep_mapping( + key_validator: _ValidatorType[_K], + value_validator: _ValidatorType[_V], + mapping_validator: _ValidatorType[_M] | None = ..., +) -> _ValidatorType[_M]: ... +def is_callable() -> _ValidatorType[_T]: ... +def lt(val: _T) -> _ValidatorType[_T]: ... +def le(val: _T) -> _ValidatorType[_T]: ... +def ge(val: _T) -> _ValidatorType[_T]: ... +def gt(val: _T) -> _ValidatorType[_T]: ... +def max_len(length: int) -> _ValidatorType[_T]: ... +def min_len(length: int) -> _ValidatorType[_T]: ... +def not_( + validator: _ValidatorType[_T], + *, + msg: str | None = None, + exc_types: type[Exception] | Iterable[type[Exception]] = ..., +) -> _ValidatorType[_T]: ... +def or_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... diff --git a/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/METADATA b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/METADATA new file mode 100644 index 0000000..a85b378 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/METADATA @@ -0,0 +1,242 @@ +Metadata-Version: 2.3 +Name: attrs +Version: 24.2.0 +Summary: Classes Without Boilerplate +Project-URL: Documentation, https://www.attrs.org/ +Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html +Project-URL: GitHub, https://github.com/python-attrs/attrs +Project-URL: Funding, https://github.com/sponsors/hynek +Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi +Author-email: Hynek Schlawack +License-Expression: MIT +License-File: LICENSE +Keywords: attribute,boilerplate,class +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Typing :: Typed +Requires-Python: >=3.7 +Requires-Dist: importlib-metadata; python_version < '3.8' +Provides-Extra: benchmark +Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'benchmark' +Requires-Dist: hypothesis; extra == 'benchmark' +Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'benchmark' +Requires-Dist: pympler; extra == 'benchmark' +Requires-Dist: pytest-codspeed; extra == 'benchmark' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'benchmark' +Requires-Dist: pytest-xdist[psutil]; extra == 'benchmark' +Requires-Dist: pytest>=4.3.0; extra == 'benchmark' +Provides-Extra: cov +Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'cov' +Requires-Dist: coverage[toml]>=5.3; extra == 'cov' +Requires-Dist: hypothesis; extra == 'cov' +Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'cov' +Requires-Dist: pympler; extra == 'cov' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'cov' +Requires-Dist: pytest-xdist[psutil]; extra == 'cov' +Requires-Dist: pytest>=4.3.0; extra == 'cov' +Provides-Extra: dev +Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'dev' +Requires-Dist: hypothesis; extra == 'dev' +Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'dev' +Requires-Dist: pre-commit; extra == 'dev' +Requires-Dist: pympler; extra == 'dev' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'dev' +Requires-Dist: pytest-xdist[psutil]; extra == 'dev' +Requires-Dist: pytest>=4.3.0; extra == 'dev' +Provides-Extra: docs +Requires-Dist: cogapp; extra == 'docs' +Requires-Dist: furo; extra == 'docs' +Requires-Dist: myst-parser; extra == 'docs' +Requires-Dist: sphinx; extra == 'docs' +Requires-Dist: sphinx-notfound-page; extra == 'docs' +Requires-Dist: sphinxcontrib-towncrier; extra == 'docs' +Requires-Dist: towncrier<24.7; extra == 'docs' +Provides-Extra: tests +Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'tests' +Requires-Dist: hypothesis; extra == 'tests' +Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'tests' +Requires-Dist: pympler; extra == 'tests' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'tests' +Requires-Dist: pytest-xdist[psutil]; extra == 'tests' +Requires-Dist: pytest>=4.3.0; extra == 'tests' +Provides-Extra: tests-mypy +Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'tests-mypy' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'tests-mypy' +Description-Content-Type: text/markdown + +

+ + attrs + +

+ + +*attrs* is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka [dunder methods](https://www.attrs.org/en/latest/glossary.html#term-dunder-methods)). +[Trusted by NASA](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/personalizing-your-profile#list-of-qualifying-repositories-for-mars-2020-helicopter-contributor-achievement) for Mars missions since 2020! + +Its main goal is to help you to write **concise** and **correct** software without slowing down your code. + + +## Sponsors + +*attrs* would not be possible without our [amazing sponsors](https://github.com/sponsors/hynek). +Especially those generously supporting us at the *The Organization* tier and higher: + + + +

+ + + + + + + + +

+ + + +

+ Please consider joining them to help make attrs’s maintenance more sustainable! +

+ + + +## Example + +*attrs* gives you a class decorator and a way to declaratively define the attributes on that class: + + + +```pycon +>>> from attrs import asdict, define, make_class, Factory + +>>> @define +... class SomeClass: +... a_number: int = 42 +... list_of_numbers: list[int] = Factory(list) +... +... def hard_math(self, another_number): +... return self.a_number + sum(self.list_of_numbers) * another_number + + +>>> sc = SomeClass(1, [1, 2, 3]) +>>> sc +SomeClass(a_number=1, list_of_numbers=[1, 2, 3]) + +>>> sc.hard_math(3) +19 +>>> sc == SomeClass(1, [1, 2, 3]) +True +>>> sc != SomeClass(2, [3, 2, 1]) +True + +>>> asdict(sc) +{'a_number': 1, 'list_of_numbers': [1, 2, 3]} + +>>> SomeClass() +SomeClass(a_number=42, list_of_numbers=[]) + +>>> C = make_class("C", ["a", "b"]) +>>> C("foo", "bar") +C(a='foo', b='bar') +``` + +After *declaring* your attributes, *attrs* gives you: + +- a concise and explicit overview of the class's attributes, +- a nice human-readable `__repr__`, +- equality-checking methods, +- an initializer, +- and much more, + +*without* writing dull boilerplate code again and again and *without* runtime performance penalties. + +--- + +This example uses *attrs*'s modern APIs that have been introduced in version 20.1.0, and the *attrs* package import name that has been added in version 21.3.0. +The classic APIs (`@attr.s`, `attr.ib`, plus their serious-business aliases) and the `attr` package import name will remain **indefinitely**. + +Check out [*On The Core API Names*](https://www.attrs.org/en/latest/names.html) for an in-depth explanation! + + +### Hate Type Annotations!? + +No problem! +Types are entirely **optional** with *attrs*. +Simply assign `attrs.field()` to the attributes instead of annotating them with types: + +```python +from attrs import define, field + +@define +class SomeClass: + a_number = field(default=42) + list_of_numbers = field(factory=list) +``` + + +## Data Classes + +On the tin, *attrs* might remind you of `dataclasses` (and indeed, `dataclasses` [are a descendant](https://hynek.me/articles/import-attrs/) of *attrs*). +In practice it does a lot more and is more flexible. +For instance, it allows you to define [special handling of NumPy arrays for equality checks](https://www.attrs.org/en/stable/comparison.html#customization), allows more ways to [plug into the initialization process](https://www.attrs.org/en/stable/init.html#hooking-yourself-into-initialization), has a replacement for `__init_subclass__`, and allows for stepping through the generated methods using a debugger. + +For more details, please refer to our [comparison page](https://www.attrs.org/en/stable/why.html#data-classes), but generally speaking, we are more likely to commit crimes against nature to make things work that one would expect to work, but that are quite complicated in practice. + + +## Project Information + +- [**Changelog**](https://www.attrs.org/en/stable/changelog.html) +- [**Documentation**](https://www.attrs.org/) +- [**PyPI**](https://pypi.org/project/attrs/) +- [**Source Code**](https://github.com/python-attrs/attrs) +- [**Contributing**](https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md) +- [**Third-party Extensions**](https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs) +- **Get Help**: use the `python-attrs` tag on [Stack Overflow](https://stackoverflow.com/questions/tagged/python-attrs) + + +### *attrs* for Enterprise + +Available as part of the Tidelift Subscription. + +The maintainers of *attrs* and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. +Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. +[Learn more](https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek). + +## Release Information + +### Deprecations + +- Given the amount of warnings raised in the broader ecosystem, we've decided to only soft-deprecate the *hash* argument to `@define` / `@attr.s`. + Please don't use it in new code, but we don't intend to remove it anymore. + [#1330](https://github.com/python-attrs/attrs/issues/1330) + + +### Changes + +- `attrs.converters.pipe()` (and its syntactic sugar of passing a list for `attrs.field()`'s / `attr.ib()`'s *converter* argument) works again when passing `attrs.setters.convert` to *on_setattr* (which is default for `attrs.define`). + [#1328](https://github.com/python-attrs/attrs/issues/1328) +- Restored support for PEP [649](https://peps.python.org/pep-0649/) / [749](https://peps.python.org/pep-0749/)-implementing Pythons -- currently 3.14-dev. + [#1329](https://github.com/python-attrs/attrs/issues/1329) + + + +--- + +[Full changelog →](https://www.attrs.org/en/stable/changelog.html) diff --git a/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/RECORD b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/RECORD new file mode 100644 index 0000000..a1eb5f8 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/RECORD @@ -0,0 +1,55 @@ +attr/__init__.py,sha256=l8Ewh5KZE7CCY0i1iDfSCnFiUTIkBVoqsXjX9EZnIVA,2087 +attr/__init__.pyi,sha256=aTVHBPX6krCGvbQvOl_UKqEzmi2HFsaIVm2WKmAiqVs,11434 +attr/__pycache__/__init__.cpython-37.pyc,, +attr/__pycache__/_cmp.cpython-37.pyc,, +attr/__pycache__/_compat.cpython-37.pyc,, +attr/__pycache__/_config.cpython-37.pyc,, +attr/__pycache__/_funcs.cpython-37.pyc,, +attr/__pycache__/_make.cpython-37.pyc,, +attr/__pycache__/_next_gen.cpython-37.pyc,, +attr/__pycache__/_version_info.cpython-37.pyc,, +attr/__pycache__/converters.cpython-37.pyc,, +attr/__pycache__/exceptions.cpython-37.pyc,, +attr/__pycache__/filters.cpython-37.pyc,, +attr/__pycache__/setters.cpython-37.pyc,, +attr/__pycache__/validators.cpython-37.pyc,, +attr/_cmp.py,sha256=3umHiBtgsEYtvNP_8XrQwTCdFoZIX4DEur76N-2a3X8,4123 +attr/_cmp.pyi,sha256=U-_RU_UZOyPUEQzXE6RMYQQcjkZRY25wTH99sN0s7MM,368 +attr/_compat.py,sha256=n2Uk3c-ywv0PkFfGlvqR7SzDXp4NOhWmNV_ZK6YfWoM,2958 +attr/_config.py,sha256=z81Vt-GeT_2taxs1XZfmHx9TWlSxjPb6eZH1LTGsS54,843 +attr/_funcs.py,sha256=SGDmNlED1TM3tgO9Ap2mfRfVI24XEAcrNQs7o2eBXHQ,17386 +attr/_make.py,sha256=BjENJz5eJoojJVbCoupWjXLLEZJ7VID89lisLbQUlmQ,91479 +attr/_next_gen.py,sha256=dhGb96VFg4kXBkS9Zdz1A2uxVJ99q_RT1hw3kLA9-uI,24630 +attr/_typing_compat.pyi,sha256=XDP54TUn-ZKhD62TOQebmzrwFyomhUCoGRpclb6alRA,469 +attr/_version_info.py,sha256=exSqb3b5E-fMSsgZAlEw9XcLpEgobPORCZpcaEglAM4,2121 +attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209 +attr/converters.py,sha256=vNa58pZi9V6uxBzl4t1QrHbQfkT4iRFAodyXe7lcgg0,3506 +attr/converters.pyi,sha256=mpDoVFO3Cpx8xYSSV0iZFl7IAHuoNBglxKfxHvLj_sY,410 +attr/exceptions.py,sha256=HRFq4iybmv7-DcZwyjl6M1euM2YeJVK_hFxuaBGAngI,1977 +attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539 +attr/filters.py,sha256=ZBiKWLp3R0LfCZsq7X11pn9WX8NslS2wXM4jsnLOGc8,1795 +attr/filters.pyi,sha256=3J5BG-dTxltBk1_-RuNRUHrv2qu1v8v4aDNAQ7_mifA,208 +attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attr/setters.py,sha256=faMQeiBo_nbXYnPaQ1pq8PXeA7Zr-uNsVsPMiKCmxhc,1619 +attr/setters.pyi,sha256=NnVkaFU1BB4JB8E4JuXyrzTUgvtMpj8p3wBdJY7uix4,584 +attr/validators.py,sha256=985eTP6RHyon61YEauMJgyNy1rEOhJWiSXMJgRxPtrQ,20045 +attr/validators.pyi,sha256=LjKf7AoXZfvGSfT3LRs61Qfln94konYyMUPoJJjOxK4,2502 +attrs-24.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +attrs-24.2.0.dist-info/METADATA,sha256=3Jgk4lr9Y1SAqAcwOLPN_mpW0wc6VOGm-yHt1LsPIHw,11524 +attrs-24.2.0.dist-info/RECORD,, +attrs-24.2.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87 +attrs-24.2.0.dist-info/licenses/LICENSE,sha256=iCEVyV38KvHutnFPjsbVy8q_Znyv-HKfQkINpj9xTp8,1109 +attrs/__init__.py,sha256=5FHo-EMFOX-g4ialSK4fwOjuoHzLISJDZCwoOl02Ty8,1071 +attrs/__init__.pyi,sha256=o3l92VsD9kHz8sldEtb_tllBTs3TeL-vIBMTxo2Zc_4,7703 +attrs/__pycache__/__init__.cpython-37.pyc,, +attrs/__pycache__/converters.cpython-37.pyc,, +attrs/__pycache__/exceptions.cpython-37.pyc,, +attrs/__pycache__/filters.cpython-37.pyc,, +attrs/__pycache__/setters.cpython-37.pyc,, +attrs/__pycache__/validators.cpython-37.pyc,, +attrs/converters.py,sha256=8kQljrVwfSTRu8INwEk8SI0eGrzmWftsT7rM0EqyohM,76 +attrs/exceptions.py,sha256=ACCCmg19-vDFaDPY9vFl199SPXCQMN_bENs4DALjzms,76 +attrs/filters.py,sha256=VOUMZug9uEU6dUuA0dF1jInUK0PL3fLgP0VBS5d-CDE,73 +attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attrs/setters.py,sha256=eL1YidYQV3T2h9_SYIZSZR1FAcHGb1TuCTy0E0Lv2SU,73 +attrs/validators.py,sha256=xcy6wD5TtTkdCG1f4XWbocPSO0faBjk5IfVJfP6SUj0,76 diff --git a/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/WHEEL new file mode 100644 index 0000000..cdd68a4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.25.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/licenses/LICENSE b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000..2bd6453 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs-24.2.0.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Hynek Schlawack and the attrs contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/lib/python3.7/site-packages/attrs/__init__.py b/.venv/lib/python3.7/site-packages/attrs/__init__.py new file mode 100644 index 0000000..963b197 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs/__init__.py @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: MIT + +from attr import ( + NOTHING, + Attribute, + AttrsInstance, + Converter, + Factory, + _make_getattr, + assoc, + cmp_using, + define, + evolve, + field, + fields, + fields_dict, + frozen, + has, + make_class, + mutable, + resolve_types, + validate, +) +from attr._next_gen import asdict, astuple + +from . import converters, exceptions, filters, setters, validators + + +__all__ = [ + "__author__", + "__copyright__", + "__description__", + "__doc__", + "__email__", + "__license__", + "__title__", + "__url__", + "__version__", + "__version_info__", + "asdict", + "assoc", + "astuple", + "Attribute", + "AttrsInstance", + "cmp_using", + "Converter", + "converters", + "define", + "evolve", + "exceptions", + "Factory", + "field", + "fields_dict", + "fields", + "filters", + "frozen", + "has", + "make_class", + "mutable", + "NOTHING", + "resolve_types", + "setters", + "validate", + "validators", +] + +__getattr__ = _make_getattr(__name__) diff --git a/.venv/lib/python3.7/site-packages/attrs/__init__.pyi b/.venv/lib/python3.7/site-packages/attrs/__init__.pyi new file mode 100644 index 0000000..b2670de --- /dev/null +++ b/.venv/lib/python3.7/site-packages/attrs/__init__.pyi @@ -0,0 +1,252 @@ +import sys + +from typing import ( + Any, + Callable, + Mapping, + Sequence, + overload, + TypeVar, +) + +# Because we need to type our own stuff, we have to make everything from +# attr explicitly public too. +from attr import __author__ as __author__ +from attr import __copyright__ as __copyright__ +from attr import __description__ as __description__ +from attr import __email__ as __email__ +from attr import __license__ as __license__ +from attr import __title__ as __title__ +from attr import __url__ as __url__ +from attr import __version__ as __version__ +from attr import __version_info__ as __version_info__ +from attr import assoc as assoc +from attr import Attribute as Attribute +from attr import AttrsInstance as AttrsInstance +from attr import cmp_using as cmp_using +from attr import converters as converters +from attr import Converter as Converter +from attr import evolve as evolve +from attr import exceptions as exceptions +from attr import Factory as Factory +from attr import fields as fields +from attr import fields_dict as fields_dict +from attr import filters as filters +from attr import has as has +from attr import make_class as make_class +from attr import NOTHING as NOTHING +from attr import resolve_types as resolve_types +from attr import setters as setters +from attr import validate as validate +from attr import validators as validators +from attr import attrib, asdict as asdict, astuple as astuple + +if sys.version_info >= (3, 11): + from typing import dataclass_transform +else: + from typing_extensions import dataclass_transform + +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) + +_EqOrderType = bool | Callable[[Any], Any] +_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] +_ConverterType = Callable[[Any], Any] +_ReprType = Callable[[Any], str] +_ReprArgType = bool | _ReprType +_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] +_OnSetAttrArgType = _OnSetAttrType | list[_OnSetAttrType] | setters._NoOpType +_FieldTransformer = Callable[ + [type, list["Attribute[Any]"]], list["Attribute[Any]"] +] +# FIXME: in reality, if multiple validators are passed they must be in a list +# or tuple, but those are invariant and so would prevent subtypes of +# _ValidatorType from working when passed in a list or tuple. +_ValidatorArgType = _ValidatorType[_T] | Sequence[_ValidatorType[_T]] + +@overload +def field( + *, + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def field( + *, + default: None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def field( + *, + default: _T, + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def field( + *, + default: _T | None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | Converter[Any, _T] | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> Any: ... +@overload +@dataclass_transform(field_specifiers=(attrib, field)) +def define( + maybe_cls: _C, + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@dataclass_transform(field_specifiers=(attrib, field)) +def define( + maybe_cls: None = ..., + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... + +mutable = define + +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: _C, + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: None = ..., + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... diff --git a/.venv/lib/python3.7/site-packages/attrs/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attrs/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0b1feee65f2df33ea849bab11b0f0c2e670745f GIT binary patch literal 1136 zcmbu7$!^p@5QaUQJxgXuCKIv@1PI$mgb^Ta2(d^&Boq$h)R&fVbtWykY|GsfWw;@p zf=A$mKe7Lyw$aqeV{Xu{L zDki{+s9;r8u_kI*7jBu4wnZB|qJt}91-qh)J<-Fy=;J^Pa8<10 znpnf37*;rE)vV)4jBrD2(76V6a|JiWCT@u>+!ouoBX)2s#`LWLAwR?Q2Es!o3f{ zWb&JO3noJ!9lk$$dvN&1w_Z3`=#O)!e3wmokXjd~iSn&iS$e7prwSjvjuV#^3*VI( ze^PR$TuiaP5nG!jzLj7u=T@gPAA&m8sq&#Z&CIFtjbp70_^^Cg-#LFv(1{~wk$qOF zubsr!x68zdp^QGlxr;vs+E6QGSmjEiz08)8vn^#jcPCjPCG{wiEMF9QcH-#RmlBjs3SA~5 zM?{V+A)_Uw!dM$JJ5m~*sMM-+zthgJNwM={89=kNB!#>KDK8E>JCWE)P=rFbzA!CKnV{{qYj6P$)SY@m+s*E9Hhq2BW6AmZWeVu>jdBkPy zvTRu*;@DDNspnEfS-UJ-3iwyqvLY7~JudPwCojrM|r(D`DDWy&|{n`il c!Z)8{26LmHaohGC;b=6dj_cLR|KDNlFJ;{&D*ylh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attrs/__pycache__/converters.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attrs/__pycache__/converters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac9e21bb3d07785ce046bb7affe55937f90aa126 GIT binary patch literal 170 zcmZ?b<>g`kf|-ri(|v&SV-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{4^P(_!CP?iu986^U6|-N>Yo8S27ea1LeWQFJt|Z+yecA%mUrayyB9?oE+U8Bje(9 hQ^QPskhWqdiO{WAPg`kf|-ri(|v&SV-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{4^P(_!CP?iu6(|l2Z#xGV}9_S27ea1LeWQFJt|Z+yecA%mUrayyB9?oE+U8Bje(9 hQ^QPskhWqdiO{WAPg`kf|-ri(>;OoV-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{4^P(coIuWiuBSlb4pT+idQleF#{#R#4iK=lH3CQg3JQl%)H`~#GD-693$i6bW_7j eeUP4FC<)c7S5SG2!zMRBr8Fni4rIt@kTn3Z%qT+u literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attrs/__pycache__/setters.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attrs/__pycache__/setters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4487640bc688b4324d64834ee3492bbd03cb74e4 GIT binary patch literal 164 zcmZ?b<>g`kf|-ri(>;OoV-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{4^P(coIuWiu8(8OG;9UidQleF#{#R#4iK=lH3CQg3JQl%)H`~#GD-693$i6bW_7j eeUP4FC<)c7S5SG2!zMRBr8Fni4rIt@kTn3hc_?K7 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/attrs/__pycache__/validators.cpython-37.pyc b/.venv/lib/python3.7/site-packages/attrs/__pycache__/validators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8299aa14f76c0da57dc85f947046f811d5f8371d GIT binary patch literal 170 zcmZ?b<>g`kf|-ri(|v&SV-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{4^P(_!CP?iuB47b23vBOY)0~S27ea1LeWQFJt|Z+yecA%mUrayyB9?oE+U8Bje(9 hQ^QPskhWqdiO{WAP=3.6 +License-File: LICENSE + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. + + diff --git a/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/RECORD b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/RECORD new file mode 100644 index 0000000..b06f9e1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2023.5.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2023.5.7.dist-info/LICENSE,sha256=oC9sY4-fuE0G93ZMOrCF2K9-2luTwWbaVDEkeQd8b7A,1052 +certifi-2023.5.7.dist-info/METADATA,sha256=fpDUR-Vqju0gWBVplvFKNISMUn1UqTzr6698ttTzSLo,2190 +certifi-2023.5.7.dist-info/RECORD,, +certifi-2023.5.7.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +certifi-2023.5.7.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=q5ePznlfOw-XYIOV6RTnh45yS9haN-Nb1d__4QXc3g0,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-37.pyc,, +certifi/__pycache__/__main__.cpython-37.pyc,, +certifi/__pycache__/core.cpython-37.pyc,, +certifi/cacert.pem,sha256=swFTXcpJHZgU6ij6oyCsehnQ9dlCN5lvoKO1qTZDJRQ,278952 +certifi/core.py,sha256=lhewz0zFb2b4ULsQurElmloYwQoecjWzPqY67P8T7iM,4219 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/WHEEL new file mode 100644 index 0000000..5bad85f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/top_level.txt new file mode 100644 index 0000000..963eac5 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi-2023.5.7.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/.venv/lib/python3.7/site-packages/certifi/__init__.py b/.venv/lib/python3.7/site-packages/certifi/__init__.py new file mode 100644 index 0000000..705f416 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2023.05.07" diff --git a/.venv/lib/python3.7/site-packages/certifi/__main__.py b/.venv/lib/python3.7/site-packages/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/.venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01efc6f097718611fbc99d3c5e8fb662327c23cc GIT binary patch literal 253 zcmYk0v2MaJ5Qc3hDG>;%kI*#(NkoNMDpc_RENmHiqB$2V#ZGFwRPaRQmArQ9D|G64 zpyHSA`|ot8U$>r4$Ba~Nzwm|pI}TR~YM!aw0|6QGj%nU-EgHcY3QYE*Nic0v%(kq! z`{8s}h>*9v@zQt~vd@FG(#9N{5YFRyJ%23gMOiO5MHbSwzg>qBz^>~6!UW(bty8@L zxG+140TI88%Il#T)G$-Vc{-lGOZSQz&Q&X|S8wXy0hCc5pd3yif6_gEbaEA6bSdFp G5@XP}eooOw}q#({Cx^QQ+u z*s`MDW<_y`GwV78>2L!%^=VZ*-I+Y|qQX^Qp#?v#0iC|r$O03SAbxg%t4$lQH*o`f zI&7k!R7%P4aJci?kjB~i(V)CXZQMJ-SwuzoK3TZ7U-Y^!w6U&gn&J`cooeNF@%Qh+ irEDv0q@4H9UYxd_+B9%R1H?v>V8=|*V=7omC+r9HS#2Qz literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc b/.venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa51e33d9a28aa03a10d8d3dc15936425efecadc GIT binary patch literal 1883 zcmcgs&2A$_5T5SovB%@z{Ou-ykhKS-L5d@^mpvfF5+QL2QOE{qH5^8>)9qvud&X3E zfP^fU?2#2Ou!r~tJW^jdS}k_RMl5s^;hk7;NTd%_*4GcbDV!@ zGaq$SzQn0-P)H|oB$Ir^BBt0em+pxNJNSeRY zhS^|p7W{TQg5cmN)BSNFPe-Z`%A7*3`{qdXvs{~GG)hcXva=F$Zb8*@h}@H>ygwUv$e`mO1I}jpt6lqe~Q9j zu}*yW#4y7pyJT0ct1}%^#J1 zCCBmk*39=}EkGg0*8BNLfm%Xq?W1sfzq!m>9J;9AOPru86MuvXCQj)hOQ$76rFhFQ zNpBa3%6AjAUZT@1Lo|Jrr-jV&!_X}gga%%<4N!@Ujrzqb@~E^99sBd5g}Bokg~MP4 zWypbc*W?e2CkQB5#?8Y)Kf#k(wLUhC=zPf&Zd}8!#JwuLmq6$N0b~6`W#ZBc^)V1> zphe;q{zcd&dQb6ij%h1EOz%ZTB`)ElGzm_LjgBz755oxfWH=!MDiki1=!1?4njM@o zs1SDV`y5;2yjkeM9%8hUov0h{)C@PD*&0$QOHJt6`XotDl0#*EP`Wq;WD9w+H3d+B zh8k{Cq9zRrooZKxUjb{_rE`HT@Rt7(ycQSYicgXB-#PovOKcHLiSN#XcdaNUDlZ|j zf~t=Qe}JEZ4@r<)_y~m+GBL@WBnhZ8@gGppWiYi~1;s7043BO*ls;;lV|Imgp0d}K zE-n!3DLpoP_byKn1YT%ZLmOL{8RW?r(TK|zA&#w}W<)gE@V^mJqYQCY5&e&4J|U-7 zM_@Co;|?}Zglo1Q$FfKY1=|`P(|^IYUedctQug4|)PhQk8Zsdc=60cA3jod5s; literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/certifi/cacert.pem b/.venv/lib/python3.7/site-packages/certifi/cacert.pem new file mode 100644 index 0000000..5183934 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi/cacert.pem @@ -0,0 +1,4589 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Label: "GLOBALTRUST 2020" +# Serial: 109160994242082918454945253 +# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 +# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 +# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG +A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw +FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx +MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u +aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b +RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z +YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 +QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw +yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ +BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ +SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH +r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 +4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me +dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw +q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 +nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu +H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC +XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd +6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf ++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi +kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 +wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB +TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C +MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn +4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I +aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy +qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 +MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu +MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV +BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw +MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg +U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ +n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q +p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq +NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF +8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 +HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa +mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi +7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF +ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P +qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ +v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 +Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD +ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 +WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo +zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR +5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ +GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf +5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq +0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D +P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM +qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP +0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf +E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA RSA v3" +# Serial: 75951268308633135324246244059508261641472512052 +# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 +# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 +# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA ECC v3" +# Serial: 218504919822255052842371958738296604628416471745 +# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 +# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 +# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw +gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn +cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD +VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 +NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r +YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh +IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF +Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ +KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK +fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB +Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C +MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp +ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 +7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx +vmjkI6TZraE3 +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication RootCA3" +# Serial: 16247922307909811815 +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad +TdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- diff --git a/.venv/lib/python3.7/site-packages/certifi/core.py b/.venv/lib/python3.7/site-packages/certifi/core.py new file mode 100644 index 0000000..de02898 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/certifi/core.py @@ -0,0 +1,108 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +elif sys.version_info >= (3, 7): + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") + +else: + import os + import types + from typing import Union + + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where() -> str: + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/.venv/lib/python3.7/site-packages/certifi/py.typed b/.venv/lib/python3.7/site-packages/certifi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/LICENSE b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/LICENSE new file mode 100644 index 0000000..ad82355 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/METADATA b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/METADATA new file mode 100644 index 0000000..867b915 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/METADATA @@ -0,0 +1,616 @@ +Metadata-Version: 2.1 +Name: charset-normalizer +Version: 3.1.0 +Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. +Home-page: https://github.com/Ousret/charset_normalizer +Author: Ahmed TAHRI +Author-email: ahmed.tahri@cloudnursery.dev +License: MIT +Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest +Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Text Processing :: Linguistic +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.7.0 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: unicode_backport + +

Charset Detection, for Everyone đŸ‘‹

+ +

+ The Real First Universal Charset Detector
+ + + + + + + + Download Count Total + +

+ +> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`, +> I'm trying to resolve the issue by taking a new approach. +> All IANA character set names for which the Python core library provides codecs are supported. + +

+ >>>>> đŸ‘‰ Try Me Online Now, Then Adopt Me đŸ‘ˆ <<<<< +

+ +This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. + +| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | +|--------------------------------------------------|:---------------------------------------------:|:------------------------------------------------------------------------------------------------------:|:-----------------------------------------------:| +| `Fast` | âŒ
| ✅
| ✅
| +| `Universal**` | ⌠| ✅ | ⌠| +| `Reliable` **without** distinguishable standards | ⌠| ✅ | ✅ | +| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | +| `License` | LGPL-2.1
_restrictive_ | MIT | MPL-1.1
_restrictive_ | +| `Native Python` | ✅ | ✅ | ⌠| +| `Detect spoken language` | ⌠| ✅ | N/A | +| `UnicodeDecodeError Safety` | ⌠| ✅ | ⌠| +| `Whl Size` | 193.6 kB | 39.5 kB | ~200 kB | +| `Supported Encoding` | 33 | :tada: [90](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 | + +

+Reading Normalized TextCat Reading Text + +*\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*
+Did you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html) + +## â­ Your support + +*Fork, test-it, star-it, submit your ideas! We do listen.* + +## â¡ Performance + +This package offer better performance than its counterpart Chardet. Here are some numbers. + +| Package | Accuracy | Mean per file (ms) | File per sec (est) | +|-----------------------------------------------|:--------:|:------------------:|:------------------:| +| [chardet](https://github.com/chardet/chardet) | 86 % | 200 ms | 5 file/sec | +| charset-normalizer | **98 %** | **10 ms** | 100 file/sec | + +| Package | 99th percentile | 95th percentile | 50th percentile | +|-----------------------------------------------|:---------------:|:---------------:|:---------------:| +| [chardet](https://github.com/chardet/chardet) | 1200 ms | 287 ms | 23 ms | +| charset-normalizer | 100 ms | 50 ms | 5 ms | + +Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload. + +> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows. +> And yes, these results might change at any time. The dataset can be updated to include more files. +> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. +> Keep in mind that the stats are generous and that Chardet accuracy vs our is measured using Chardet initial capability +> (eg. Supported Encoding) Challenge-them if you want. + +## ✨ Installation + +Using PyPi for latest stable +```sh +pip install charset-normalizer -U +``` + +## đŸ€ Basic Usage + +### CLI +This package comes with a CLI. + +``` +usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] + file [file ...] + +The Real First Universal Charset Detector. Discover originating encoding used +on text file. Normalize text to unicode. + +positional arguments: + files File(s) to be analysed + +optional arguments: + -h, --help show this help message and exit + -v, --verbose Display complementary information about file if any. + Stdout will contain logs about the detection process. + -a, --with-alternative + Output complementary possibilities if any. Top-level + JSON WILL be a list. + -n, --normalize Permit to normalize input file. If not set, program + does not write anything. + -m, --minimal Only output the charset detected to STDOUT. Disabling + JSON output. + -r, --replace Replace file when trying to normalize it instead of + creating a new one. + -f, --force Replace file without asking if you are sure, use this + flag with caution. + -t THRESHOLD, --threshold THRESHOLD + Define a custom maximum amount of chaos allowed in + decoded content. 0. <= chaos <= 1. + --version Show version information and exit. +``` + +```bash +normalizer ./data/sample.1.fr.srt +``` + +:tada: Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. + +```json +{ + "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", + "encoding": "cp1252", + "encoding_aliases": [ + "1252", + "windows_1252" + ], + "alternative_encodings": [ + "cp1254", + "cp1256", + "cp1258", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + "mbcs" + ], + "language": "French", + "alphabets": [ + "Basic Latin", + "Latin-1 Supplement" + ], + "has_sig_or_bom": false, + "chaos": 0.149, + "coherence": 97.152, + "unicode_path": null, + "is_preferred": true +} +``` + +### Python +*Just print out normalized text* +```python +from charset_normalizer import from_path + +results = from_path('./my_subtitle.srt') + +print(str(results.best())) +``` + +*Upgrade your code without effort* +```python +from charset_normalizer import detect +``` + +The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. + +See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) + +## đŸ˜‡ Why + +When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a +reliable alternative using a completely different method. Also! I never back down on a good challenge! + +I **don't care** about the **originating charset** encoding, because **two different tables** can +produce **two identical rendered string.** +What I want is to get readable text, the best I can. + +In a way, **I'm brute forcing text decoding.** How cool is that ? đŸ˜ + +Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. + +## đŸ° How + + - Discard all charset encoding table that could not fit the binary content. + - Measure noise, or the mess once opened (by chunks) with a corresponding charset encoding. + - Extract matches with the lowest mess detected. + - Additionally, we measure coherence / probe for a language. + +**Wait a minute**, what is noise/mess and coherence according to **YOU ?** + +*Noise :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then +**I established** some ground rules about **what is obvious** when **it seems like** a mess. + I know that my interpretation of what is noise is probably incomplete, feel free to contribute in order to + improve or rewrite it. + +*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought +that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. + +## â¡ Known limitations + + - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) + - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. + +## â ï¸ About Python EOLs + +**If you are running:** + +- Python >=2.7,<3.5: Unsupported +- Python 3.5: charset-normalizer < 2.1 +- Python 3.6: charset-normalizer < 3.1 + +Upgrade your Python interpreter as soon as possible. + +## đŸ‘¤ Contributing + +Contributions, issues and feature requests are very much welcome.
+Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. + +## đŸ“ License + +Copyright © [Ahmed TAHRI @Ousret](https://github.com/Ousret).
+This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. + +Characters frequencies used in this project © 2012 [Denny VrandeÄić](http://simia.net/letters/) + +## đŸ’¼ For Enterprise + +Professional support for charset-normalizer is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme + +# Changelog +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) + +### Added +- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) + +### Removed +- Support for Python 3.6 (PR #260) + +### Changed +- Optional speedup provided by mypy/c 1.0.1 + +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) + +### Fixed +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) + +### Changed +- Speedup provided by mypy/c 0.990 on Python >= 3.7 + +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it +- Sphinx warnings when generating the documentation + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' + +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) + +### Added +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Removed +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) + +### Fixed +- Sphinx warnings when generating the documentation + +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) + +### Changed +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Removed +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) + +### Deprecated +- Function `normalize` scheduled for removal in 3.0 + +### Changed +- Removed useless call to decode in fn is_unprintable (#206) + +### Fixed +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) + +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) + +### Added +- Output the Unicode table version when running the CLI with `--version` (PR #194) + +### Changed +- Re-use decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) + +### Fixed +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) + +### Removed +- Support for Python 3.5 (PR #192) + +### Deprecated +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) + +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) + +### Fixed +- ASCII miss-detection on rare cases (PR #170) + +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) + +### Added +- Explicit support for Python 3.11 (PR #164) + +### Changed +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) + +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) + +### Fixed +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) + +### Changed +- Skipping the language-detection (CD) on ASCII (PR #155) + +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) + +### Changed +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) + +### Fixed +- Wrong logging level applied when setting kwarg `explain` to True (PR #146) + +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) +### Changed +- Improvement over Vietnamese detection (PR #126) +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) +- Code style as refactored by Sourcery-AI (PR #131) +- Minor adjustment on the MD around european words (PR #133) +- Remove and replace SRTs from assets / tests (PR #139) +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) + +### Fixed +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) +- Avoid using too insignificant chunk (PR #137) + +### Added +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) + +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) +### Added +- Add support for Kazakh (Cyrillic) language detection (PR #109) + +### Changed +- Further, improve inferring the language from a given single-byte code page (PR #112) +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) +- Various detection improvement (MD+CD) (PR #117) + +### Removed +- Remove redundant logging entry about detected language(s) (PR #115) + +### Fixed +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) + +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) +### Fixed +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) +- Fix CLI crash when using --minimal output in certain cases (PR #103) + +### Changed +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) + +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) +### Changed +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) +- The Unicode detection is slightly improved (PR #93) +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) + +### Removed +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) + +### Fixed +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) +- The MANIFEST.in was not exhaustive (PR #78) + +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) +### Fixed +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) +- Submatch factoring could be wrong in rare edge cases (PR #72) +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) +- Fix line endings from CRLF to LF for certain project files (PR #67) + +### Changed +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) +- Allow fallback on specified encoding if any (PR #71) + +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) +### Changed +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) + +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) +### Fixed +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) + +### Changed +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) + +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) +### Fixed +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) +- Using explain=False permanently disable the verbose output in the current runtime (PR #47) +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) + +### Changed +- Public function normalize default args values were not aligned with from_bytes (PR #53) + +### Added +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) + +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) +### Changed +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. +- Accent has been made on UTF-8 detection, should perform rather instantaneous. +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ +- utf_7 detection has been reinstated. + +### Removed +- This package no longer require anything when used with Python 3.5 (Dropped cached_property) +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, VolapĂ¼k, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. +- The exception hook on UnicodeDecodeError has been removed. + +### Deprecated +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 + +### Fixed +- The CLI output used the relative path of the file(s). Should be absolute. + +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) +### Fixed +- Logger configuration/usage no longer conflict with others (PR #44) + +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) +### Removed +- Using standard logging instead of using the package loguru. +- Dropping nose test framework in favor of the maintained pytest. +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. +- Stop support for UTF-7 that does not contain a SIG. +- Dropping PrettyTable, replaced with pure JSON output in CLI. + +### Fixed +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. +- Not searching properly for the BOM when trying utf32/16 parent codec. + +### Changed +- Improving the package final size by compressing frequencies.json. +- Huge improvement over the larges payload. + +### Added +- CLI now produces JSON consumable output. +- Return ASCII if given sequences fit. Given reasonable confidence. + +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) + +### Fixed +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) + +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) + +### Fixed +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) + +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) + +### Fixed +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) + +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) + +### Changed +- Amend the previous release to allow prettytable 2.0 (PR #35) + +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) + +### Fixed +- Fix error while using the package with a python pre-release interpreter (PR #33) + +### Changed +- Dependencies refactoring, constraints revised. + +### Added +- Add python 3.9 and 3.10 to the supported interpreters + +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/RECORD b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/RECORD new file mode 100644 index 0000000..3840a75 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/RECORD @@ -0,0 +1,33 @@ +../../../bin/normalizer,sha256=NDIdcqPIIO-reZ8k3sTEjisprBXAWcQ8QjO_lKPWxjA,265 +charset_normalizer-3.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +charset_normalizer-3.1.0.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 +charset_normalizer-3.1.0.dist-info/METADATA,sha256=8lfcrrmtfEq--eZqh8FJzEjptLCEoGXySKruxIms44I,30983 +charset_normalizer-3.1.0.dist-info/RECORD,, +charset_normalizer-3.1.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92 +charset_normalizer-3.1.0.dist-info/entry_points.txt,sha256=uYo8aIGLWv8YgWfSna5HnfY_En4pkF1w4bgawNAXzP0,76 +charset_normalizer-3.1.0.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 +charset_normalizer/__init__.py,sha256=aAb_F9Zb23pb4NO6TfIfqLXLvf1PjnLBBOuPvQwPA18,1549 +charset_normalizer/__pycache__/__init__.cpython-37.pyc,, +charset_normalizer/__pycache__/api.cpython-37.pyc,, +charset_normalizer/__pycache__/cd.cpython-37.pyc,, +charset_normalizer/__pycache__/constant.cpython-37.pyc,, +charset_normalizer/__pycache__/legacy.cpython-37.pyc,, +charset_normalizer/__pycache__/md.cpython-37.pyc,, +charset_normalizer/__pycache__/models.cpython-37.pyc,, +charset_normalizer/__pycache__/utils.cpython-37.pyc,, +charset_normalizer/__pycache__/version.cpython-37.pyc,, +charset_normalizer/api.py,sha256=Vh44rFXztkxCjW7gF2waq8TyRL3mXKX8RwNGB99bhb4,18624 +charset_normalizer/assets/__init__.py,sha256=wpRfujN7GJuEE5wHHo3wEDVoJ5ovzRIxsImyimCBfGU,20069 +charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc,, +charset_normalizer/cd.py,sha256=mZuiTSKq4XpweSDD2H4T4R3Axtaa-QS0tpEWdpMuAzQ,12554 +charset_normalizer/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc,, +charset_normalizer/cli/__pycache__/normalizer.cpython-37.pyc,, +charset_normalizer/cli/normalizer.py,sha256=2F-xURZJzo063Ye-2RLJ2wcmURpbKeAzKwpiws65dAs,9744 +charset_normalizer/constant.py,sha256=PmCeoKXqq3ZbCtCUpKHwwFBIv9DXMT_an1yd24q28mA,19101 +charset_normalizer/legacy.py,sha256=T-QuVMsMeDiQEk8WSszMrzVJg_14AMeSkmHdRYhdl1k,2071 +charset_normalizer/md.py,sha256=MXPKP_oLbsubulEL_1rxcYKSd5FeEfyEfNNm5O6ADpc,18258 +charset_normalizer/models.py,sha256=mC11wo84l00u2o03TRNX7M5ItBAbPUKKXgJSFxA35GY,11492 +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/utils.py,sha256=tKLpquPYQdaRdFRwBo5gPOi06ov8UCJy5X1Pti0Q78U,11544 +charset_normalizer/version.py,sha256=bekbdpF_D3BtF-PhbPnA9PNaZaI8kKIgl3LTCD5FmYk,79 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/WHEEL new file mode 100644 index 0000000..57e3d84 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.4) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/entry_points.txt b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/entry_points.txt new file mode 100644 index 0000000..a06d360 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +normalizer = charset_normalizer.cli.normalizer:cli_detect diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/top_level.txt new file mode 100644 index 0000000..66958f0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer-3.1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +charset_normalizer diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__init__.py b/.venv/lib/python3.7/site-packages/charset_normalizer/__init__.py new file mode 100644 index 0000000..ebb5da8 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/__init__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +""" +Charset-Normalizer +~~~~~~~~~~~~~~ +The Real First Universal Charset Detector. +A library that helps you read text from an unknown charset encoding. +Motivated by chardet, This package is trying to resolve the issue by taking a new approach. +All IANA character set names for which the Python core library provides codecs are supported. + +Basic usage: + >>> from charset_normalizer import from_bytes + >>> results = from_bytes('BÑĐµĐºĐ¸ Ñ‡Đ¾Đ²ĐµĐº Đ¸Đ¼Đ° Đ¿Ñ€Đ°Đ²Đ¾ Đ½Đ° Đ¾Đ±Ñ€Đ°Đ·Đ¾Đ²Đ°Đ½Đ¸Đµ. OĐ±Ñ€Đ°Đ·Đ¾Đ²Đ°Đ½Đ¸ĐµÑ‚Đ¾!'.encode('utf_8')) + >>> best_guess = results.best() + >>> str(best_guess) + 'BÑĐµĐºĐ¸ Ñ‡Đ¾Đ²ĐµĐº Đ¸Đ¼Đ° Đ¿Ñ€Đ°Đ²Đ¾ Đ½Đ° Đ¾Đ±Ñ€Đ°Đ·Đ¾Đ²Đ°Đ½Đ¸Đµ. OĐ±Ñ€Đ°Đ·Đ¾Đ²Đ°Đ½Đ¸ĐµÑ‚Đ¾!' + +Others methods and usages are available - see the full documentation +at . +:copyright: (c) 2021 by Ahmed TAHRI +:license: MIT, see LICENSE for more details. +""" +import logging + +from .api import from_bytes, from_fp, from_path +from .legacy import detect +from .models import CharsetMatch, CharsetMatches +from .utils import set_logging_handler +from .version import VERSION, __version__ + +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "detect", + "CharsetMatch", + "CharsetMatches", + "__version__", + "VERSION", + "set_logging_handler", +) + +# Attach a NullHandler to the top level logger by default +# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library + +logging.getLogger("charset_normalizer").addHandler(logging.NullHandler()) diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e29206cca7e239a93cb057205e1652f9130ab223 GIT binary patch literal 1535 zcmcIkOK;>v5VmI~^XNP_`#@ZaQ!--51AAJHmWX5t+K9~rC4qx4R*&5?Zl&8c-R*?g z1A@KqH#Rr81*8=bg76odtFN5)FL0vTGkKupx|Uq3s;;j3>eXAz%f!L&!-Joq<)-8O zZH23^fy}4)Yl9?md?#|Fns9wLsz(h`lXbr?8-7DB_zSLsx&_gcEx%RqP0^MezaxoH zD!C;V<&wWt@oljzSNs)u$G?Me$6sactGf|7bzj{>?*6HB>Y~1O;B*)BmvzS>Ph+Yy zGreJ|Bo+JxQ{=n}@u+OM~&$-eDzDoEpQyS&@Rrrh<7MfIfWD^7*DXOMmVrn2} zBGWKUb5M*%VA!_?#wwLS6UdXJBt1zWoW%#0glWW+iAQ!*!;h(95saqQam36+IE=Z5 zjD|;a!T?#Lrf3Z&Mc+CV#|%T-1D!K_&(I@#Od(+>K(kDxG>j3T5U{g3+^qc4&@cs< zJS0>y4dYb7NzB8za`olZ#3|xS6}!#~-5m1>O%W>#HBda$d6uOL;d+E@QO!fhHDVkP z0NB{rm?b>VGDxng3|!i4)p0PI8m6xMo%8)5;gcFO}xE%JK}A=f!Ie_Wn{5iCNTONYXHB8UlnXi% z40_n$*=&q+Y<`r6xnzl0&rFP5WPmb5Kd zw8Xw=s)NM8_jYl*56V^$V1a|6Y|X=#b(-;+zianpQ?LmQr&WZqDRGsAzKK*WU|5@l7GJF8=3Vpp7nU5 z4f^PP!}KVU!HcU-_ionnN_A^v`$51HZi2were*sH;?4!zcn@9cRU{3!U3=gzxvTcC HH&*@yju<4W literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2f42a23d5db0a67eef171637f408af83d956ed2 GIT binary patch literal 10108 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 f;;EkI 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16b1a7f2f6521c88236b3d5aad6ed3796eaf4b53 GIT binary patch literal 11407 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 O)!#DiRF^Ae(f(h0ep!zI literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62a3ebda6b8f11630c5a937cbf471e28818bb4d5 GIT binary patch literal 8975 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a45661d5d7c609b8c7583134388d87c3966574f8 GIT binary patch literal 246 zcmZ?b<>g`k0`1@xDgHqEF^B^L%s_?%5EqL9i4=w?h7`sq##F`yOestY8Kam}n1dNK zS*irMTq_Fli&GWKQj3Z+^Ygf>SdH}z^$cz?>iKE1++vT9PsvY?kH5to9}iUl CharsetMatches: + """ + Given a raw bytes sequence, return the best possibles charset usable to render str objects. + If there is no results, it is a strong indicator that the source is binary/not text. + By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. + And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. + + The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page + but never take it for granted. Can improve the performance. + + You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that + purpose. + + This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. + By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' + toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. + Custom logging format and handler can be set manually. + """ + + if not isinstance(sequences, (bytearray, bytes)): + raise TypeError( + "Expected object of type bytes or bytearray, got: {0}".format( + type(sequences) + ) + ) + + if explain: + previous_logger_level: int = logger.level + logger.addHandler(explain_handler) + logger.setLevel(TRACE) + + length: int = len(sequences) + + if length == 0: + logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level or logging.WARNING) + return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) + + if cp_isolation is not None: + logger.log( + TRACE, + "cp_isolation is set. use this flag for debugging purpose. " + "limited list of encoding allowed : %s.", + ", ".join(cp_isolation), + ) + cp_isolation = [iana_name(cp, False) for cp in cp_isolation] + else: + cp_isolation = [] + + if cp_exclusion is not None: + logger.log( + TRACE, + "cp_exclusion is set. use this flag for debugging purpose. " + "limited list of encoding excluded : %s.", + ", ".join(cp_exclusion), + ) + cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] + else: + cp_exclusion = [] + + if length <= (chunk_size * steps): + logger.log( + TRACE, + "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", + steps, + chunk_size, + length, + ) + steps = 1 + chunk_size = length + + if steps > 1 and length / steps < chunk_size: + chunk_size = int(length / steps) + + is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE + is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE + + if is_too_small_sequence: + logger.log( + TRACE, + "Trying to detect encoding from a tiny portion of ({}) byte(s).".format( + length + ), + ) + elif is_too_large_sequence: + logger.log( + TRACE, + "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format( + length + ), + ) + + prioritized_encodings: List[str] = [] + + specified_encoding: Optional[str] = ( + any_specified_encoding(sequences) if preemptive_behaviour else None + ) + + if specified_encoding is not None: + prioritized_encodings.append(specified_encoding) + logger.log( + TRACE, + "Detected declarative mark in sequence. Priority +1 given for %s.", + specified_encoding, + ) + + tested: Set[str] = set() + tested_but_hard_failure: List[str] = [] + tested_but_soft_failure: List[str] = [] + + fallback_ascii: Optional[CharsetMatch] = None + fallback_u8: Optional[CharsetMatch] = None + fallback_specified: Optional[CharsetMatch] = None + + results: CharsetMatches = CharsetMatches() + + sig_encoding, sig_payload = identify_sig_or_bom(sequences) + + if sig_encoding is not None: + prioritized_encodings.append(sig_encoding) + logger.log( + TRACE, + "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", + len(sig_payload), + sig_encoding, + ) + + prioritized_encodings.append("ascii") + + if "utf_8" not in prioritized_encodings: + prioritized_encodings.append("utf_8") + + for encoding_iana in prioritized_encodings + IANA_SUPPORTED: + if cp_isolation and encoding_iana not in cp_isolation: + continue + + if cp_exclusion and encoding_iana in cp_exclusion: + continue + + if encoding_iana in tested: + continue + + tested.add(encoding_iana) + + decoded_payload: Optional[str] = None + bom_or_sig_available: bool = sig_encoding == encoding_iana + strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) + + if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) + continue + if encoding_iana in {"utf_7"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", + encoding_iana, + ) + continue + + try: + is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) + except (ModuleNotFoundError, ImportError): + logger.log( + TRACE, + "Encoding %s does not provide an IncrementalDecoder", + encoding_iana, + ) + continue + + try: + if is_too_large_sequence and is_multi_byte_decoder is False: + str( + sequences[: int(50e4)] + if strip_sig_or_bom is False + else sequences[len(sig_payload) : int(50e4)], + encoding=encoding_iana, + ) + else: + decoded_payload = str( + sequences + if strip_sig_or_bom is False + else sequences[len(sig_payload) :], + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError) as e: + if not isinstance(e, LookupError): + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + similar_soft_failure_test: bool = False + + for encoding_soft_failed in tested_but_soft_failure: + if is_cp_similar(encoding_iana, encoding_soft_failed): + similar_soft_failure_test = True + break + + if similar_soft_failure_test: + logger.log( + TRACE, + "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", + encoding_iana, + encoding_soft_failed, + ) + continue + + r_ = range( + 0 if not bom_or_sig_available else len(sig_payload), + length, + int(length / steps), + ) + + multi_byte_bonus: bool = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) + + if multi_byte_bonus: + logger.log( + TRACE, + "Code page %s is a multi byte encoding table and it appear that at least one character " + "was encoded using n-bytes.", + encoding_iana, + ) + + max_chunk_gave_up: int = int(len(r_) / 4) + + max_chunk_gave_up = max(max_chunk_gave_up, 2) + early_stop_count: int = 0 + lazy_str_hard_failure = False + + md_chunks: List[str] = [] + md_ratios = [] + + try: + for chunk in cut_sequence_chunks( + sequences, + encoding_iana, + r_, + chunk_size, + bom_or_sig_available, + strip_sig_or_bom, + sig_payload, + is_multi_byte_decoder, + decoded_payload, + ): + md_chunks.append(chunk) + + md_ratios.append( + mess_ratio( + chunk, + threshold, + explain is True and 1 <= len(cp_isolation) <= 2, + ) + ) + + if md_ratios[-1] >= threshold: + early_stop_count += 1 + + if (early_stop_count >= max_chunk_gave_up) or ( + bom_or_sig_available and strip_sig_or_bom is False + ): + break + except ( + UnicodeDecodeError + ) as e: # Lazy str loading may have missed something there + logger.log( + TRACE, + "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + early_stop_count = max_chunk_gave_up + lazy_str_hard_failure = True + + # We might want to check the sequence again with the whole content + # Only if initial MD tests passes + if ( + not lazy_str_hard_failure + and is_too_large_sequence + and not is_multi_byte_decoder + ): + try: + sequences[int(50e3) :].decode(encoding_iana, errors="strict") + except UnicodeDecodeError as e: + logger.log( + TRACE, + "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 + if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: + tested_but_soft_failure.append(encoding_iana) + logger.log( + TRACE, + "%s was excluded because of initial chaos probing. Gave up %i time(s). " + "Computed mean chaos is %f %%.", + encoding_iana, + early_stop_count, + round(mean_mess_ratio * 100, ndigits=3), + ) + # Preparing those fallbacks in case we got nothing. + if ( + encoding_iana in ["ascii", "utf_8", specified_encoding] + and not lazy_str_hard_failure + ): + fallback_entry = CharsetMatch( + sequences, encoding_iana, threshold, False, [], decoded_payload + ) + if encoding_iana == specified_encoding: + fallback_specified = fallback_entry + elif encoding_iana == "ascii": + fallback_ascii = fallback_entry + else: + fallback_u8 = fallback_entry + continue + + logger.log( + TRACE, + "%s passed initial chaos probing. Mean measured chaos is %f %%", + encoding_iana, + round(mean_mess_ratio * 100, ndigits=3), + ) + + if not is_multi_byte_decoder: + target_languages: List[str] = encoding_languages(encoding_iana) + else: + target_languages = mb_encoding_languages(encoding_iana) + + if target_languages: + logger.log( + TRACE, + "{} should target any language(s) of {}".format( + encoding_iana, str(target_languages) + ), + ) + + cd_ratios = [] + + # We shall skip the CD when its about ASCII + # Most of the time its not relevant to run "language-detection" on it. + if encoding_iana != "ascii": + for chunk in md_chunks: + chunk_languages = coherence_ratio( + chunk, + language_threshold, + ",".join(target_languages) if target_languages else None, + ) + + cd_ratios.append(chunk_languages) + + cd_ratios_merged = merge_coherence_ratios(cd_ratios) + + if cd_ratios_merged: + logger.log( + TRACE, + "We detected language {} using {}".format( + cd_ratios_merged, encoding_iana + ), + ) + + results.append( + CharsetMatch( + sequences, + encoding_iana, + mean_mess_ratio, + bom_or_sig_available, + cd_ratios_merged, + decoded_payload, + ) + ) + + if ( + encoding_iana in [specified_encoding, "ascii", "utf_8"] + and mean_mess_ratio < 0.1 + ): + logger.debug( + "Encoding detection: %s is most likely the one.", encoding_iana + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if encoding_iana == sig_encoding: + logger.debug( + "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " + "the beginning of the sequence.", + encoding_iana, + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if len(results) == 0: + if fallback_u8 or fallback_ascii or fallback_specified: + logger.log( + TRACE, + "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", + ) + + if fallback_specified: + logger.debug( + "Encoding detection: %s will be used as a fallback match", + fallback_specified.encoding, + ) + results.append(fallback_specified) + elif ( + (fallback_u8 and fallback_ascii is None) + or ( + fallback_u8 + and fallback_ascii + and fallback_u8.fingerprint != fallback_ascii.fingerprint + ) + or (fallback_u8 is not None) + ): + logger.debug("Encoding detection: utf_8 will be used as a fallback match") + results.append(fallback_u8) + elif fallback_ascii: + logger.debug("Encoding detection: ascii will be used as a fallback match") + results.append(fallback_ascii) + + if results: + logger.debug( + "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", + results.best().encoding, # type: ignore + len(results) - 1, + ) + else: + logger.debug("Encoding detection: Unable to determine any suitable charset.") + + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + + return results + + +def from_fp( + fp: BinaryIO, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but using a file pointer that is already ready. + Will not close the file pointer. + """ + return from_bytes( + fp.read(), + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + ) + + +def from_path( + path: "PathLike[Any]", + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. + Can raise IOError. + """ + with open(path, "rb") as fp: + return from_fp( + fp, + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + ) diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py b/.venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py new file mode 100644 index 0000000..9075930 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py @@ -0,0 +1,1440 @@ +# -*- coding: utf-8 -*- +from typing import Dict, List + +# Language label that contain the em dash "—" +# character are to be considered alternative seq to origin +FREQUENCIES: Dict[str, List[str]] = { + "English": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "u", + "m", + "f", + "p", + "g", + "w", + "y", + "b", + "v", + "k", + "x", + "j", + "z", + "q", + ], + "English—": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "m", + "u", + "f", + "p", + "g", + "w", + "b", + "y", + "v", + "k", + "j", + "x", + "z", + "q", + ], + "German": [ + "e", + "n", + "i", + "r", + "s", + "t", + "a", + "d", + "h", + "u", + "l", + "g", + "o", + "c", + "m", + "b", + "f", + "k", + "w", + "z", + "p", + "v", + "Ă¼", + "ä", + "ö", + "j", + ], + "French": [ + "e", + "a", + "s", + "n", + "i", + "t", + "r", + "l", + "u", + "o", + "d", + "c", + "p", + "m", + "Ă©", + "v", + "g", + "f", + "b", + "h", + "q", + "Ă ", + "x", + "è", + "y", + "j", + ], + "Dutch": [ + "e", + "n", + "a", + "i", + "r", + "t", + "o", + "d", + "s", + "l", + "g", + "h", + "v", + "m", + "u", + "k", + "c", + "p", + "b", + "w", + "j", + "z", + "f", + "y", + "x", + "Ă«", + ], + "Italian": [ + "e", + "i", + "a", + "o", + "n", + "l", + "t", + "r", + "s", + "c", + "d", + "u", + "p", + "m", + "g", + "v", + "f", + "b", + "z", + "h", + "q", + "è", + "Ă ", + "k", + "y", + "Ă²", + ], + "Polish": [ + "a", + "i", + "o", + "e", + "n", + "r", + "z", + "w", + "s", + "c", + "t", + "k", + "y", + "d", + "p", + "m", + "u", + "l", + "j", + "Å‚", + "g", + "b", + "h", + "Ä…", + "Ä™", + "Ă³", + ], + "Spanish": [ + "e", + "a", + "o", + "n", + "s", + "r", + "i", + "l", + "d", + "t", + "c", + "u", + "m", + "p", + "b", + "g", + "v", + "f", + "y", + "Ă³", + "h", + "q", + "Ă­", + "j", + "z", + "Ă¡", + ], + "Russian": [ + "Đ¾", + "Đ°", + "е", + "и", + "Đ½", + "Ñ", + "Ñ‚", + "Ñ€", + "Đ²", + "Đ»", + "Đº", + "Đ¼", + "Đ´", + "Đ¿", + "у", + "Đ³", + "Ñ", + "Ñ‹", + "Đ·", + "б", + "Đ¹", + "ÑŒ", + "ч", + "Ñ…", + "ж", + "ц", + ], + # Jap-Kanji + "Japanese": [ + "人", + "一", + "大", + "亅", + "ä¸", + "丨", + "竹", + "笑", + "å£", + "æ—¥", + "ä»", + "二", + "å½³", + "è¡Œ", + "å", + "土", + "丶", + "寸", + "寺", + "時", + "ä¹™", + "丿", + "乂", + "æ°”", + "æ°—", + "冂", + "å·¾", + "亠", + "市", + "ç›®", + "å„¿", + "見", + "å…«", + "å°", + "凵", + "県", + "月", + "å½", + "é–€", + "é–“", + "木", + "æ±", + "å±±", + "出", + "本", + "中", + "刀", + "分", + "耳", + "åˆ", + "å–", + "最", + "言", + "ç”°", + "心", + "æ€", + "刂", + "å‰", + "京", + "å°¹", + "事", + "生", + "å¶", + "云", + "ä¼", + "未", + "æ¥", + "白", + "冫", + "楽", + "ç¬", + "馬", + "å°¸", + "å°º", + "駅", + "æ˜", + "耂", + "者", + "了", + "é˜", + "都", + "高", + "åœ", + "å ", + "å‚", + "广", + "店", + "å­", + "申", + "奄", + "亻", + "俺", + "ä¸", + "æ–¹", + "冖", + "å­¦", + "è¡£", + "艮", + "食", + "自", + ], + # Jap-Katakana + "Japanese—": [ + "ăƒ¼", + "ăƒ³", + "ă‚¹", + "ăƒ»", + "ăƒ«", + "ăƒˆ", + "ăƒª", + "イ", + "ă‚¢", + "ăƒ©", + "ăƒƒ", + "ă‚¯", + "ăƒ‰", + "ă‚·", + "ăƒ¬", + "ジ", + "ă‚¿", + "ăƒ•", + "ăƒ­", + "ă‚«", + "ăƒ†", + "ăƒ", + "ă‚£", + "ă‚°", + "ăƒ", + "ăƒ ", + "ăƒ—", + "ă‚ª", + "ă‚³", + "ăƒ‡", + "ăƒ‹", + "ウ", + "ăƒ¡", + "サ", + "ăƒ“", + "ăƒ", + "ăƒ–", + "ăƒ£", + "エ", + "ăƒ¥", + "ăƒ", + "ă‚­", + "ă‚º", + "ăƒ€", + "ăƒ‘", + "ăƒŸ", + "ェ", + "ăƒ§", + "ăƒ", + "ă‚»", + "ăƒ™", + "ガ", + "ăƒ¢", + "ăƒ„", + "ăƒ", + "ăƒœ", + "ă‚½", + "ăƒ", + "ă‚¡", + "ăƒ´", + "ăƒ¯", + "ăƒ", + "ăƒ", + "ăƒ”", + "ケ", + "ă‚´", + "ă‚®", + "ザ", + "ăƒ›", + "ă‚²", + "ă‚©", + "ăƒ¤", + "ăƒ’", + "ăƒ¦", + "ăƒ¨", + "ăƒ˜", + "ă‚¼", + "ăƒŒ", + "ă‚¥", + "ă‚¾", + "ăƒ¶", + "ăƒ‚", + "ăƒ²", + "ăƒ…", + "ăƒµ", + "ăƒ±", + "ăƒ°", + "ăƒ®", + "ăƒ½", + "ă‚ ", + "ăƒ¾", + "ăƒ·", + "ăƒ¿", + "ăƒ¸", + "ăƒ¹", + "ăƒº", + ], + # Jap-Hiragana + "Japanese——": [ + "ă®", + "ă«", + "ă‚‹", + "ăŸ", + "ă¨", + "ă¯", + "ă—", + "ă„", + "ă‚’", + "ă§", + "ă¦", + "ăŒ", + "ăª", + "ă‚Œ", + "ă‹", + "ら", + "ă•", + "ă£", + "ă‚", + "ă™", + "ă‚", + "ă‚‚", + "ă“", + "ă¾", + "ă†", + "ă", + "ă‚ˆ", + "ă", + "ă‚“", + "ă‚", + "ă", + "ă‘", + "ă", + "ă¤", + "ă ", + "ă‚„", + "ăˆ", + "ă©", + "ă‚", + "ă¡", + "ă¿", + "ă›", + "ă˜", + "ă°", + "ă¸", + "ă³", + "ă", + "ă‚", + "ă»", + "ă’", + "ă‚€", + "ă¹", + "ă²", + "ょ", + "ゆ", + "ă¶", + "ă”", + "ă‚ƒ", + "ă­", + "ăµ", + "ă", + "ă", + "ă¼", + "ă‚…", + "ă¥", + "ă–", + "ă", + "ă¬", + "ăœ", + "ă±", + "ă½", + "ă·", + "ă´", + "ăƒ", + "ă", + "ă‡", + "ăº", + "ă‚", + "ă¢", + "ă‰", + "ă…", + "ă‚", + "ă‚", + "ă‚‘", + "ă‚›", + "ă‚œ", + "ă‚", + "ă‚”", + "ă‚", + "ă‚Ÿ", + "ă‚™", + "ă‚•", + "ă‚–", + ], + "Portuguese": [ + "a", + "e", + "o", + "s", + "i", + "r", + "d", + "n", + "t", + "m", + "u", + "c", + "l", + "p", + "g", + "v", + "b", + "f", + "h", + "Ă£", + "q", + "Ă©", + "ç", + "Ă¡", + "z", + "Ă­", + ], + "Swedish": [ + "e", + "a", + "n", + "r", + "t", + "s", + "i", + "l", + "d", + "o", + "m", + "k", + "g", + "v", + "h", + "f", + "u", + "p", + "ä", + "c", + "b", + "ö", + "Ă¥", + "y", + "j", + "x", + ], + "Chinese": [ + "ç„", + "一", + "是", + "ä¸", + "了", + "在", + "人", + "有", + "我", + "ä»–", + "è¿™", + "个", + "们", + "中", + "æ¥", + "ä¸", + "大", + "为", + "å’Œ", + "国", + "地", + "到", + "以", + "说", + "æ—¶", + "è¦", + "å°±", + "出", + "ä¼", + "å¯", + "也", + "ä½ ", + "对", + "生", + "能", + "而", + "å­", + "é‚£", + "å¾—", + "äº", + "ç€", + "下", + "自", + "之", + "å¹´", + "过", + "å‘", + "å", + "作", + "里", + "用", + "é“", + "è¡Œ", + "所", + "然", + "家", + "ç§", + "事", + "æˆ", + "æ–¹", + "å¤", + "ç»", + "么", + "å»", + "法", + "å­¦", + "如", + "都", + "åŒ", + "ç°", + "当", + "没", + "å¨", + "é¢", + "èµ·", + "看", + "å®", + "天", + "分", + "还", + "è¿›", + "好", + "å°", + "部", + "å…¶", + "些", + "主", + "æ ·", + "ç†", + "心", + "她", + "本", + "å‰", + "å¼€", + "但", + "å› ", + "åª", + "ä»", + "想", + "å®", + ], + "Ukrainian": [ + "Đ¾", + "Đ°", + "Đ½", + "Ñ–", + "и", + "Ñ€", + "Đ²", + "Ñ‚", + "е", + "Ñ", + "Đº", + "Đ»", + "у", + "Đ´", + "Đ¼", + "Đ¿", + "Đ·", + "Ñ", + "ÑŒ", + "б", + "Đ³", + "Đ¹", + "ч", + "Ñ…", + "ц", + "Ñ—", + ], + "Norwegian": [ + "e", + "r", + "n", + "t", + "a", + "s", + "i", + "o", + "l", + "d", + "g", + "k", + "m", + "v", + "f", + "p", + "u", + "b", + "h", + "Ă¥", + "y", + "j", + "ø", + "c", + "æ", + "w", + ], + "Finnish": [ + "a", + "i", + "n", + "t", + "e", + "s", + "l", + "o", + "u", + "k", + "ä", + "m", + "r", + "v", + "j", + "h", + "p", + "y", + "d", + "ö", + "g", + "c", + "b", + "f", + "w", + "z", + ], + "Vietnamese": [ + "n", + "h", + "t", + "i", + "c", + "g", + "a", + "o", + "u", + "m", + "l", + "r", + "Ă ", + "Ä‘", + "s", + "e", + "v", + "p", + "b", + "y", + "Æ°", + "d", + "Ă¡", + "k", + "á»™", + "ế", + ], + "Czech": [ + "o", + "e", + "a", + "n", + "t", + "s", + "i", + "l", + "v", + "r", + "k", + "d", + "u", + "m", + "p", + "Ă­", + "c", + "h", + "z", + "Ă¡", + "y", + "j", + "b", + "Ä›", + "Ă©", + "Å™", + ], + "Hungarian": [ + "e", + "a", + "t", + "l", + "s", + "n", + "k", + "r", + "i", + "o", + "z", + "Ă¡", + "Ă©", + "g", + "m", + "b", + "y", + "v", + "d", + "h", + "u", + "p", + "j", + "ö", + "f", + "c", + ], + "Korean": [ + "́´", + "다", + "́—", + "́˜", + "ë”", + "ë¡œ", + "하", + "́„", + "ê°€", + "ê³ ", + "́§€", + "́„œ", + "í•œ", + "́€", + "기", + "́œ¼", + "ë…„", + "대", + "́‚¬", + "́‹œ", + "를", + "리", + "ë„", + "́¸", + "́¤", + "́¼", + ], + "Indonesian": [ + "a", + "n", + "e", + "i", + "r", + "t", + "u", + "s", + "d", + "k", + "m", + "l", + "g", + "p", + "b", + "o", + "h", + "y", + "j", + "c", + "w", + "f", + "v", + "z", + "x", + "q", + ], + "Turkish": [ + "a", + "e", + "i", + "n", + "r", + "l", + "ı", + "k", + "d", + "t", + "s", + "m", + "y", + "u", + "o", + "b", + "Ă¼", + "ÅŸ", + "v", + "g", + "z", + "h", + "c", + "p", + "ç", + "ÄŸ", + ], + "Romanian": [ + "e", + "i", + "a", + "r", + "n", + "t", + "u", + "l", + "o", + "c", + "s", + "d", + "p", + "m", + "ă", + "f", + "v", + "Ă®", + "g", + "b", + "È™", + "È›", + "z", + "h", + "Ă¢", + "j", + ], + "Farsi": [ + "ا", + "ÛŒ", + "ر", + "د", + "Ù†", + "Ù‡", + "Ùˆ", + "Ù…", + "ت", + "ب", + "س", + "Ù„", + "Ú©", + "Ø´", + "ز", + "Ù", + "Ú¯", + "ع", + "Ø®", + "Ù‚", + "ج", + "Ø¢", + "Ù¾", + "Ø­", + "Ø·", + "ص", + ], + "Arabic": [ + "ا", + "Ù„", + "Ù", + "Ù…", + "Ùˆ", + "Ù†", + "ر", + "ت", + "ب", + "Ø©", + "ع", + "د", + "س", + "Ù", + "Ù‡", + "Ùƒ", + "Ù‚", + "Ø£", + "Ø­", + "ج", + "Ø´", + "Ø·", + "ص", + "Ù‰", + "Ø®", + "Ø¥", + ], + "Danish": [ + "e", + "r", + "n", + "t", + "a", + "i", + "s", + "d", + "l", + "o", + "g", + "m", + "k", + "f", + "v", + "u", + "b", + "h", + "p", + "Ă¥", + "y", + "ø", + "æ", + "c", + "j", + "w", + ], + "Serbian": [ + "Đ°", + "и", + "Đ¾", + "е", + "Đ½", + "Ñ€", + "Ñ", + "у", + "Ñ‚", + "Đº", + "ј", + "Đ²", + "Đ´", + "Đ¼", + "Đ¿", + "Đ»", + "Đ³", + "Đ·", + "б", + "a", + "i", + "e", + "o", + "n", + "ц", + "ш", + ], + "Lithuanian": [ + "i", + "a", + "s", + "o", + "r", + "e", + "t", + "n", + "u", + "k", + "m", + "l", + "p", + "v", + "d", + "j", + "g", + "Ä—", + "b", + "y", + "ų", + "Å¡", + "ž", + "c", + "Ä…", + "į", + ], + "Slovene": [ + "e", + "a", + "i", + "o", + "n", + "r", + "s", + "l", + "t", + "j", + "v", + "k", + "d", + "p", + "m", + "u", + "z", + "b", + "g", + "h", + "Ä", + "c", + "Å¡", + "ž", + "f", + "y", + ], + "Slovak": [ + "o", + "a", + "e", + "n", + "i", + "r", + "v", + "t", + "s", + "l", + "k", + "d", + "m", + "p", + "u", + "c", + "h", + "j", + "b", + "z", + "Ă¡", + "y", + "Ă½", + "Ă­", + "Ä", + "Ă©", + ], + "Hebrew": [ + "×™", + "ו", + "×”", + "ל", + "ר", + "ב", + "ת", + "×", + "×", + "ש", + "× ", + "×¢", + "×", + "ד", + "ק", + "×—", + "פ", + "ס", + "×›", + "×’", + "ט", + "צ", + "ן", + "×–", + "×", + ], + "Bulgarian": [ + "Đ°", + "и", + "Đ¾", + "е", + "Đ½", + "Ñ‚", + "Ñ€", + "Ñ", + "Đ²", + "Đ»", + "Đº", + "Đ´", + "Đ¿", + "Đ¼", + "Đ·", + "Đ³", + "Ñ", + "Ñ", + "у", + "б", + "ч", + "ц", + "Đ¹", + "ж", + "щ", + "Ñ…", + ], + "Croatian": [ + "a", + "i", + "o", + "e", + "n", + "r", + "j", + "s", + "t", + "u", + "k", + "l", + "v", + "d", + "m", + "p", + "g", + "z", + "b", + "c", + "Ä", + "h", + "Å¡", + "ž", + "ć", + "f", + ], + "Hindi": [ + "क", + "र", + "स", + "न", + "त", + "म", + "ह", + "प", + "य", + "ल", + "व", + "ज", + "द", + "ग", + "ब", + "श", + "ट", + "अ", + "à¤", + "थ", + "भ", + "ड", + "à¤", + "ध", + "ष", + "इ", + ], + "Estonian": [ + "a", + "i", + "e", + "s", + "t", + "l", + "u", + "n", + "o", + "k", + "r", + "d", + "m", + "v", + "g", + "p", + "j", + "h", + "ä", + "b", + "õ", + "Ă¼", + "f", + "c", + "ö", + "y", + ], + "Thai": [ + "า", + "น", + "ร", + "อ", + "à¸", + "เ", + "ง", + "ม", + "ย", + "ล", + "ว", + "ด", + "ท", + "ส", + "ต", + "ะ", + "ป", + "à¸", + "ค", + "ห", + "à¹", + "จ", + "à¸", + "à¸", + "ข", + "ใ", + ], + "Greek": [ + "α", + "Ï„", + "ο", + "ι", + "ε", + "ν", + "Ï", + "σ", + "κ", + "η", + "Ï€", + "Ï‚", + "Ï…", + "μ", + "λ", + "ί", + "ÏŒ", + "ά", + "γ", + "έ", + "δ", + "ή", + "ω", + "χ", + "θ", + "Ï", + ], + "Tamil": [ + "க", + "த", + "ப", + "ட", + "à®°", + "à®®", + "ல", + "ன", + "வ", + "à®±", + "ய", + "ள", + "à®", + "ந", + "இ", + "ண", + "à®…", + "ஆ", + "à®´", + "à®™", + "à®", + "உ", + "à®’", + "ஸ", + ], + "Kazakh": [ + "Đ°", + "Ñ‹", + "е", + "Đ½", + "Ñ‚", + "Ñ€", + "Đ»", + "Ñ–", + "Đ´", + "Ñ", + "Đ¼", + "̉›", + "Đº", + "Đ¾", + "б", + "и", + "у", + "̉“", + "ж", + "̉£", + "Đ·", + "ш", + "Đ¹", + "Đ¿", + "Đ³", + "Ó©", + ], +} diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cb24a5bb3381abc8371f45414f1aa6f46d81629 GIT binary patch literal 11995 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 AZ~y=R literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/cd.py b/.venv/lib/python3.7/site-packages/charset_normalizer/cd.py new file mode 100644 index 0000000..6e56fe8 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/cd.py @@ -0,0 +1,390 @@ +import importlib +from codecs import IncrementalDecoder +from collections import Counter +from functools import lru_cache +from typing import Counter as TypeCounter, Dict, List, Optional, Tuple + +from .assets import FREQUENCIES +from .constant import KO_NAMES, LANGUAGE_SUPPORTED_COUNT, TOO_SMALL_SEQUENCE, ZH_NAMES +from .md import is_suspiciously_successive_range +from .models import CoherenceMatches +from .utils import ( + is_accentuated, + is_latin, + is_multi_byte_encoding, + is_unicode_range_secondary, + unicode_range, +) + + +def encoding_unicode_range(iana_name: str) -> List[str]: + """ + Return associated unicode ranges in a single byte code page. + """ + if is_multi_byte_encoding(iana_name): + raise IOError("Function not supported on multi-byte code page") + + decoder = importlib.import_module( + "encodings.{}".format(iana_name) + ).IncrementalDecoder + + p: IncrementalDecoder = decoder(errors="ignore") + seen_ranges: Dict[str, int] = {} + character_count: int = 0 + + for i in range(0x40, 0xFF): + chunk: str = p.decode(bytes([i])) + + if chunk: + character_range: Optional[str] = unicode_range(chunk) + + if character_range is None: + continue + + if is_unicode_range_secondary(character_range) is False: + if character_range not in seen_ranges: + seen_ranges[character_range] = 0 + seen_ranges[character_range] += 1 + character_count += 1 + + return sorted( + [ + character_range + for character_range in seen_ranges + if seen_ranges[character_range] / character_count >= 0.15 + ] + ) + + +def unicode_range_languages(primary_range: str) -> List[str]: + """ + Return inferred languages used with a unicode range. + """ + languages: List[str] = [] + + for language, characters in FREQUENCIES.items(): + for character in characters: + if unicode_range(character) == primary_range: + languages.append(language) + break + + return languages + + +@lru_cache() +def encoding_languages(iana_name: str) -> List[str]: + """ + Single-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + unicode_ranges: List[str] = encoding_unicode_range(iana_name) + primary_range: Optional[str] = None + + for specified_range in unicode_ranges: + if "Latin" not in specified_range: + primary_range = specified_range + break + + if primary_range is None: + return ["Latin Based"] + + return unicode_range_languages(primary_range) + + +@lru_cache() +def mb_encoding_languages(iana_name: str) -> List[str]: + """ + Multi-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + if ( + iana_name.startswith("shift_") + or iana_name.startswith("iso2022_jp") + or iana_name.startswith("euc_j") + or iana_name == "cp932" + ): + return ["Japanese"] + if iana_name.startswith("gb") or iana_name in ZH_NAMES: + return ["Chinese"] + if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: + return ["Korean"] + + return [] + + +@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) +def get_target_features(language: str) -> Tuple[bool, bool]: + """ + Determine main aspects from a supported language if it contains accents and if is pure Latin. + """ + target_have_accents: bool = False + target_pure_latin: bool = True + + for character in FREQUENCIES[language]: + if not target_have_accents and is_accentuated(character): + target_have_accents = True + if target_pure_latin and is_latin(character) is False: + target_pure_latin = False + + return target_have_accents, target_pure_latin + + +def alphabet_languages( + characters: List[str], ignore_non_latin: bool = False +) -> List[str]: + """ + Return associated languages associated to given characters. + """ + languages: List[Tuple[str, float]] = [] + + source_have_accents = any(is_accentuated(character) for character in characters) + + for language, language_characters in FREQUENCIES.items(): + target_have_accents, target_pure_latin = get_target_features(language) + + if ignore_non_latin and target_pure_latin is False: + continue + + if target_have_accents is False and source_have_accents: + continue + + character_count: int = len(language_characters) + + character_match_count: int = len( + [c for c in language_characters if c in characters] + ) + + ratio: float = character_match_count / character_count + + if ratio >= 0.2: + languages.append((language, ratio)) + + languages = sorted(languages, key=lambda x: x[1], reverse=True) + + return [compatible_language[0] for compatible_language in languages] + + +def characters_popularity_compare( + language: str, ordered_characters: List[str] +) -> float: + """ + Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. + The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). + Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) + """ + if language not in FREQUENCIES: + raise ValueError("{} not available".format(language)) + + character_approved_count: int = 0 + FREQUENCIES_language_set = set(FREQUENCIES[language]) + + ordered_characters_count: int = len(ordered_characters) + target_language_characters_count: int = len(FREQUENCIES[language]) + + large_alphabet: bool = target_language_characters_count > 26 + + for character, character_rank in zip( + ordered_characters, range(0, ordered_characters_count) + ): + if character not in FREQUENCIES_language_set: + continue + + character_rank_in_language: int = FREQUENCIES[language].index(character) + expected_projection_ratio: float = ( + target_language_characters_count / ordered_characters_count + ) + character_rank_projection: int = int(character_rank * expected_projection_ratio) + + if ( + large_alphabet is False + and abs(character_rank_projection - character_rank_in_language) > 4 + ): + continue + + if ( + large_alphabet is True + and abs(character_rank_projection - character_rank_in_language) + < target_language_characters_count / 3 + ): + character_approved_count += 1 + continue + + characters_before_source: List[str] = FREQUENCIES[language][ + 0:character_rank_in_language + ] + characters_after_source: List[str] = FREQUENCIES[language][ + character_rank_in_language: + ] + characters_before: List[str] = ordered_characters[0:character_rank] + characters_after: List[str] = ordered_characters[character_rank:] + + before_match_count: int = len( + set(characters_before) & set(characters_before_source) + ) + + after_match_count: int = len( + set(characters_after) & set(characters_after_source) + ) + + if len(characters_before_source) == 0 and before_match_count <= 4: + character_approved_count += 1 + continue + + if len(characters_after_source) == 0 and after_match_count <= 4: + character_approved_count += 1 + continue + + if ( + before_match_count / len(characters_before_source) >= 0.4 + or after_match_count / len(characters_after_source) >= 0.4 + ): + character_approved_count += 1 + continue + + return character_approved_count / len(ordered_characters) + + +def alpha_unicode_split(decoded_sequence: str) -> List[str]: + """ + Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. + Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; + One containing the latin letters and the other hebrew. + """ + layers: Dict[str, str] = {} + + for character in decoded_sequence: + if character.isalpha() is False: + continue + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + layer_target_range: Optional[str] = None + + for discovered_range in layers: + if ( + is_suspiciously_successive_range(discovered_range, character_range) + is False + ): + layer_target_range = discovered_range + break + + if layer_target_range is None: + layer_target_range = character_range + + if layer_target_range not in layers: + layers[layer_target_range] = character.lower() + continue + + layers[layer_target_range] += character.lower() + + return list(layers.values()) + + +def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: + """ + This function merge results previously given by the function coherence_ratio. + The return type is the same as coherence_ratio. + """ + per_language_ratios: Dict[str, List[float]] = {} + for result in results: + for sub_result in result: + language, ratio = sub_result + if language not in per_language_ratios: + per_language_ratios[language] = [ratio] + continue + per_language_ratios[language].append(ratio) + + merge = [ + ( + language, + round( + sum(per_language_ratios[language]) / len(per_language_ratios[language]), + 4, + ), + ) + for language in per_language_ratios + ] + + return sorted(merge, key=lambda x: x[1], reverse=True) + + +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: + """ + We shall NOT return "English—" in CoherenceMatches because it is an alternative + of "English". This function only keeps the best match and remove the em-dash in it. + """ + index_results: Dict[str, List[float]] = dict() + + for result in results: + language, ratio = result + no_em_name: str = language.replace("—", "") + + if no_em_name not in index_results: + index_results[no_em_name] = [] + + index_results[no_em_name].append(ratio) + + if any(len(index_results[e]) > 1 for e in index_results): + filtered_results: CoherenceMatches = [] + + for language in index_results: + filtered_results.append((language, max(index_results[language]))) + + return filtered_results + + return results + + +@lru_cache(maxsize=2048) +def coherence_ratio( + decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None +) -> CoherenceMatches: + """ + Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. + A layer = Character extraction by alphabets/ranges. + """ + + results: List[Tuple[str, float]] = [] + ignore_non_latin: bool = False + + sufficient_match_count: int = 0 + + lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] + if "Latin Based" in lg_inclusion_list: + ignore_non_latin = True + lg_inclusion_list.remove("Latin Based") + + for layer in alpha_unicode_split(decoded_sequence): + sequence_frequencies: TypeCounter[str] = Counter(layer) + most_common = sequence_frequencies.most_common() + + character_count: int = sum(o for c, o in most_common) + + if character_count <= TOO_SMALL_SEQUENCE: + continue + + popular_character_ordered: List[str] = [c for c, o in most_common] + + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered, ignore_non_latin + ): + ratio: float = characters_popularity_compare( + language, popular_character_ordered + ) + + if ratio < threshold: + continue + elif ratio >= 0.8: + sufficient_match_count += 1 + + results.append((language, round(ratio, 4))) + + if sufficient_match_count >= 3: + break + + return sorted( + filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True + ) diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py b/.venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..503224269ac91042655aab884382408c7849c05a GIT binary patch literal 166 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 Y5mGPWDy#@;>tAa8oil%7Z0Fej0ElJiV*mgE literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py b/.venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py new file mode 100644 index 0000000..f4bcbaa --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py @@ -0,0 +1,296 @@ +import argparse +import sys +from json import dumps +from os.path import abspath, basename, dirname, join, realpath +from platform import python_version +from typing import List, Optional +from unicodedata import unidata_version + +import charset_normalizer.md as md_module +from charset_normalizer import from_fp +from charset_normalizer.models import CliDetectionResult +from charset_normalizer.version import __version__ + + +def query_yes_no(question: str, default: str = "yes") -> bool: + """Ask a yes/no question via input() and return their answer. + + "question" is a string that is presented to the user. + "default" is the presumed answer if the user just hits . + It must be "yes" (the default), "no" or None (meaning + an answer is required of the user). + + The "answer" return value is True for "yes" or False for "no". + + Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input + """ + valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + while True: + sys.stdout.write(question + prompt) + choice = input().lower() + if default is not None and choice == "": + return valid[default] + elif choice in valid: + return valid[choice] + else: + sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") + + +def cli_detect(argv: Optional[List[str]] = None) -> int: + """ + CLI assistant using ARGV and ArgumentParser + :param argv: + :return: 0 if everything is fine, anything else equal trouble + """ + parser = argparse.ArgumentParser( + description="The Real First Universal Charset Detector. " + "Discover originating encoding used on text file. " + "Normalize text to unicode." + ) + + parser.add_argument( + "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed" + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + default=False, + dest="verbose", + help="Display complementary information about file if any. " + "Stdout will contain logs about the detection process.", + ) + parser.add_argument( + "-a", + "--with-alternative", + action="store_true", + default=False, + dest="alternatives", + help="Output complementary possibilities if any. Top-level JSON WILL be a list.", + ) + parser.add_argument( + "-n", + "--normalize", + action="store_true", + default=False, + dest="normalize", + help="Permit to normalize input file. If not set, program does not write anything.", + ) + parser.add_argument( + "-m", + "--minimal", + action="store_true", + default=False, + dest="minimal", + help="Only output the charset detected to STDOUT. Disabling JSON output.", + ) + parser.add_argument( + "-r", + "--replace", + action="store_true", + default=False, + dest="replace", + help="Replace file when trying to normalize it instead of creating a new one.", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + dest="force", + help="Replace file without asking if you are sure, use this flag with caution.", + ) + parser.add_argument( + "-t", + "--threshold", + action="store", + default=0.2, + type=float, + dest="threshold", + help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.", + ) + parser.add_argument( + "--version", + action="version", + version="Charset-Normalizer {} - Python {} - Unicode {} - SpeedUp {}".format( + __version__, + python_version(), + unidata_version, + "OFF" if md_module.__file__.lower().endswith(".py") else "ON", + ), + help="Show version information and exit.", + ) + + args = parser.parse_args(argv) + + if args.replace is True and args.normalize is False: + print("Use --replace in addition of --normalize only.", file=sys.stderr) + return 1 + + if args.force is True and args.replace is False: + print("Use --force in addition of --replace only.", file=sys.stderr) + return 1 + + if args.threshold < 0.0 or args.threshold > 1.0: + print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr) + return 1 + + x_ = [] + + for my_file in args.files: + matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose) + + best_guess = matches.best() + + if best_guess is None: + print( + 'Unable to identify originating encoding for "{}". {}'.format( + my_file.name, + "Maybe try increasing maximum amount of chaos." + if args.threshold < 1.0 + else "", + ), + file=sys.stderr, + ) + x_.append( + CliDetectionResult( + abspath(my_file.name), + None, + [], + [], + "Unknown", + [], + False, + 1.0, + 0.0, + None, + True, + ) + ) + else: + x_.append( + CliDetectionResult( + abspath(my_file.name), + best_guess.encoding, + best_guess.encoding_aliases, + [ + cp + for cp in best_guess.could_be_from_charset + if cp != best_guess.encoding + ], + best_guess.language, + best_guess.alphabets, + best_guess.bom, + best_guess.percent_chaos, + best_guess.percent_coherence, + None, + True, + ) + ) + + if len(matches) > 1 and args.alternatives: + for el in matches: + if el != best_guess: + x_.append( + CliDetectionResult( + abspath(my_file.name), + el.encoding, + el.encoding_aliases, + [ + cp + for cp in el.could_be_from_charset + if cp != el.encoding + ], + el.language, + el.alphabets, + el.bom, + el.percent_chaos, + el.percent_coherence, + None, + False, + ) + ) + + if args.normalize is True: + if best_guess.encoding.startswith("utf") is True: + print( + '"{}" file does not need to be normalized, as it already came from unicode.'.format( + my_file.name + ), + file=sys.stderr, + ) + if my_file.closed is False: + my_file.close() + continue + + dir_path = dirname(realpath(my_file.name)) + file_name = basename(realpath(my_file.name)) + + o_: List[str] = file_name.split(".") + + if args.replace is False: + o_.insert(-1, best_guess.encoding) + if my_file.closed is False: + my_file.close() + elif ( + args.force is False + and query_yes_no( + 'Are you sure to normalize "{}" by replacing it ?'.format( + my_file.name + ), + "no", + ) + is False + ): + if my_file.closed is False: + my_file.close() + continue + + try: + x_[0].unicode_path = join(dir_path, ".".join(o_)) + + with open(x_[0].unicode_path, "w", encoding="utf-8") as fp: + fp.write(str(best_guess)) + except IOError as e: + print(str(e), file=sys.stderr) + if my_file.closed is False: + my_file.close() + return 2 + + if my_file.closed is False: + my_file.close() + + if args.minimal is False: + print( + dumps( + [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__, + ensure_ascii=True, + indent=4, + ) + ) + else: + for my_file in args.files: + print( + ", ".join( + [ + el.encoding or "undefined" + for el in x_ + if el.path == abspath(my_file.name) + ] + ) + ) + + return 0 + + +if __name__ == "__main__": + cli_detect() diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/constant.py b/.venv/lib/python3.7/site-packages/charset_normalizer/constant.py new file mode 100644 index 0000000..3188108 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/constant.py @@ -0,0 +1,495 @@ +from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE +from encodings.aliases import aliases +from re import IGNORECASE, compile as re_compile +from typing import Dict, List, Set, Union + +from .assets import FREQUENCIES + +# Contain for each eligible encoding a list of/item bytes SIG/BOM +ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = { + "utf_8": BOM_UTF8, + "utf_7": [ + b"\x2b\x2f\x76\x38", + b"\x2b\x2f\x76\x39", + b"\x2b\x2f\x76\x2b", + b"\x2b\x2f\x76\x2f", + b"\x2b\x2f\x76\x38\x2d", + ], + "gb18030": b"\x84\x31\x95\x33", + "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE], + "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE], +} + +TOO_SMALL_SEQUENCE: int = 32 +TOO_BIG_SEQUENCE: int = int(10e6) + +UTF8_MAXIMAL_ALLOCATION: int = 1112064 + +UNICODE_RANGES_COMBINED: Dict[str, range] = { + "Control character": range(31 + 1), + "Basic Latin": range(32, 127 + 1), + "Latin-1 Supplement": range(128, 255 + 1), + "Latin Extended-A": range(256, 383 + 1), + "Latin Extended-B": range(384, 591 + 1), + "IPA Extensions": range(592, 687 + 1), + "Spacing Modifier Letters": range(688, 767 + 1), + "Combining Diacritical Marks": range(768, 879 + 1), + "Greek and Coptic": range(880, 1023 + 1), + "Cyrillic": range(1024, 1279 + 1), + "Cyrillic Supplement": range(1280, 1327 + 1), + "Armenian": range(1328, 1423 + 1), + "Hebrew": range(1424, 1535 + 1), + "Arabic": range(1536, 1791 + 1), + "Syriac": range(1792, 1871 + 1), + "Arabic Supplement": range(1872, 1919 + 1), + "Thaana": range(1920, 1983 + 1), + "NKo": range(1984, 2047 + 1), + "Samaritan": range(2048, 2111 + 1), + "Mandaic": range(2112, 2143 + 1), + "Syriac Supplement": range(2144, 2159 + 1), + "Arabic Extended-A": range(2208, 2303 + 1), + "Devanagari": range(2304, 2431 + 1), + "Bengali": range(2432, 2559 + 1), + "Gurmukhi": range(2560, 2687 + 1), + "Gujarati": range(2688, 2815 + 1), + "Oriya": range(2816, 2943 + 1), + "Tamil": range(2944, 3071 + 1), + "Telugu": range(3072, 3199 + 1), + "Kannada": range(3200, 3327 + 1), + "Malayalam": range(3328, 3455 + 1), + "Sinhala": range(3456, 3583 + 1), + "Thai": range(3584, 3711 + 1), + "Lao": range(3712, 3839 + 1), + "Tibetan": range(3840, 4095 + 1), + "Myanmar": range(4096, 4255 + 1), + "Georgian": range(4256, 4351 + 1), + "Hangul Jamo": range(4352, 4607 + 1), + "Ethiopic": range(4608, 4991 + 1), + "Ethiopic Supplement": range(4992, 5023 + 1), + "Cherokee": range(5024, 5119 + 1), + "Unified Canadian Aboriginal Syllabics": range(5120, 5759 + 1), + "Ogham": range(5760, 5791 + 1), + "Runic": range(5792, 5887 + 1), + "Tagalog": range(5888, 5919 + 1), + "Hanunoo": range(5920, 5951 + 1), + "Buhid": range(5952, 5983 + 1), + "Tagbanwa": range(5984, 6015 + 1), + "Khmer": range(6016, 6143 + 1), + "Mongolian": range(6144, 6319 + 1), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6399 + 1), + "Limbu": range(6400, 6479 + 1), + "Tai Le": range(6480, 6527 + 1), + "New Tai Lue": range(6528, 6623 + 1), + "Khmer Symbols": range(6624, 6655 + 1), + "Buginese": range(6656, 6687 + 1), + "Tai Tham": range(6688, 6831 + 1), + "Combining Diacritical Marks Extended": range(6832, 6911 + 1), + "Balinese": range(6912, 7039 + 1), + "Sundanese": range(7040, 7103 + 1), + "Batak": range(7104, 7167 + 1), + "Lepcha": range(7168, 7247 + 1), + "Ol Chiki": range(7248, 7295 + 1), + "Cyrillic Extended C": range(7296, 7311 + 1), + "Sundanese Supplement": range(7360, 7375 + 1), + "Vedic Extensions": range(7376, 7423 + 1), + "Phonetic Extensions": range(7424, 7551 + 1), + "Phonetic Extensions Supplement": range(7552, 7615 + 1), + "Combining Diacritical Marks Supplement": range(7616, 7679 + 1), + "Latin Extended Additional": range(7680, 7935 + 1), + "Greek Extended": range(7936, 8191 + 1), + "General Punctuation": range(8192, 8303 + 1), + "Superscripts and Subscripts": range(8304, 8351 + 1), + "Currency Symbols": range(8352, 8399 + 1), + "Combining Diacritical Marks for Symbols": range(8400, 8447 + 1), + "Letterlike Symbols": range(8448, 8527 + 1), + "Number Forms": range(8528, 8591 + 1), + "Arrows": range(8592, 8703 + 1), + "Mathematical Operators": range(8704, 8959 + 1), + "Miscellaneous Technical": range(8960, 9215 + 1), + "Control Pictures": range(9216, 9279 + 1), + "Optical Character Recognition": range(9280, 9311 + 1), + "Enclosed Alphanumerics": range(9312, 9471 + 1), + "Box Drawing": range(9472, 9599 + 1), + "Block Elements": range(9600, 9631 + 1), + "Geometric Shapes": range(9632, 9727 + 1), + "Miscellaneous Symbols": range(9728, 9983 + 1), + "Dingbats": range(9984, 10175 + 1), + "Miscellaneous Mathematical Symbols-A": range(10176, 10223 + 1), + "Supplemental Arrows-A": range(10224, 10239 + 1), + "Braille Patterns": range(10240, 10495 + 1), + "Supplemental Arrows-B": range(10496, 10623 + 1), + "Miscellaneous Mathematical Symbols-B": range(10624, 10751 + 1), + "Supplemental Mathematical Operators": range(10752, 11007 + 1), + "Miscellaneous Symbols and Arrows": range(11008, 11263 + 1), + "Glagolitic": range(11264, 11359 + 1), + "Latin Extended-C": range(11360, 11391 + 1), + "Coptic": range(11392, 11519 + 1), + "Georgian Supplement": range(11520, 11567 + 1), + "Tifinagh": range(11568, 11647 + 1), + "Ethiopic Extended": range(11648, 11743 + 1), + "Cyrillic Extended-A": range(11744, 11775 + 1), + "Supplemental Punctuation": range(11776, 11903 + 1), + "CJK Radicals Supplement": range(11904, 12031 + 1), + "Kangxi Radicals": range(12032, 12255 + 1), + "Ideographic Description Characters": range(12272, 12287 + 1), + "CJK Symbols and Punctuation": range(12288, 12351 + 1), + "Hiragana": range(12352, 12447 + 1), + "Katakana": range(12448, 12543 + 1), + "Bopomofo": range(12544, 12591 + 1), + "Hangul Compatibility Jamo": range(12592, 12687 + 1), + "Kanbun": range(12688, 12703 + 1), + "Bopomofo Extended": range(12704, 12735 + 1), + "CJK Strokes": range(12736, 12783 + 1), + "Katakana Phonetic Extensions": range(12784, 12799 + 1), + "Enclosed CJK Letters and Months": range(12800, 13055 + 1), + "CJK Compatibility": range(13056, 13311 + 1), + "CJK Unified Ideographs Extension A": range(13312, 19903 + 1), + "Yijing Hexagram Symbols": range(19904, 19967 + 1), + "CJK Unified Ideographs": range(19968, 40959 + 1), + "Yi Syllables": range(40960, 42127 + 1), + "Yi Radicals": range(42128, 42191 + 1), + "Lisu": range(42192, 42239 + 1), + "Vai": range(42240, 42559 + 1), + "Cyrillic Extended-B": range(42560, 42655 + 1), + "Bamum": range(42656, 42751 + 1), + "Modifier Tone Letters": range(42752, 42783 + 1), + "Latin Extended-D": range(42784, 43007 + 1), + "Syloti Nagri": range(43008, 43055 + 1), + "Common Indic Number Forms": range(43056, 43071 + 1), + "Phags-pa": range(43072, 43135 + 1), + "Saurashtra": range(43136, 43231 + 1), + "Devanagari Extended": range(43232, 43263 + 1), + "Kayah Li": range(43264, 43311 + 1), + "Rejang": range(43312, 43359 + 1), + "Hangul Jamo Extended-A": range(43360, 43391 + 1), + "Javanese": range(43392, 43487 + 1), + "Myanmar Extended-B": range(43488, 43519 + 1), + "Cham": range(43520, 43615 + 1), + "Myanmar Extended-A": range(43616, 43647 + 1), + "Tai Viet": range(43648, 43743 + 1), + "Meetei Mayek Extensions": range(43744, 43775 + 1), + "Ethiopic Extended-A": range(43776, 43823 + 1), + "Latin Extended-E": range(43824, 43887 + 1), + "Cherokee Supplement": range(43888, 43967 + 1), + "Meetei Mayek": range(43968, 44031 + 1), + "Hangul Syllables": range(44032, 55215 + 1), + "Hangul Jamo Extended-B": range(55216, 55295 + 1), + "High Surrogates": range(55296, 56191 + 1), + "High Private Use Surrogates": range(56192, 56319 + 1), + "Low Surrogates": range(56320, 57343 + 1), + "Private Use Area": range(57344, 63743 + 1), + "CJK Compatibility Ideographs": range(63744, 64255 + 1), + "Alphabetic Presentation Forms": range(64256, 64335 + 1), + "Arabic Presentation Forms-A": range(64336, 65023 + 1), + "Variation Selectors": range(65024, 65039 + 1), + "Vertical Forms": range(65040, 65055 + 1), + "Combining Half Marks": range(65056, 65071 + 1), + "CJK Compatibility Forms": range(65072, 65103 + 1), + "Small Form Variants": range(65104, 65135 + 1), + "Arabic Presentation Forms-B": range(65136, 65279 + 1), + "Halfwidth and Fullwidth Forms": range(65280, 65519 + 1), + "Specials": range(65520, 65535 + 1), + "Linear B Syllabary": range(65536, 65663 + 1), + "Linear B Ideograms": range(65664, 65791 + 1), + "Aegean Numbers": range(65792, 65855 + 1), + "Ancient Greek Numbers": range(65856, 65935 + 1), + "Ancient Symbols": range(65936, 65999 + 1), + "Phaistos Disc": range(66000, 66047 + 1), + "Lycian": range(66176, 66207 + 1), + "Carian": range(66208, 66271 + 1), + "Coptic Epact Numbers": range(66272, 66303 + 1), + "Old Italic": range(66304, 66351 + 1), + "Gothic": range(66352, 66383 + 1), + "Old Permic": range(66384, 66431 + 1), + "Ugaritic": range(66432, 66463 + 1), + "Old Persian": range(66464, 66527 + 1), + "Deseret": range(66560, 66639 + 1), + "Shavian": range(66640, 66687 + 1), + "Osmanya": range(66688, 66735 + 1), + "Osage": range(66736, 66815 + 1), + "Elbasan": range(66816, 66863 + 1), + "Caucasian Albanian": range(66864, 66927 + 1), + "Linear A": range(67072, 67455 + 1), + "Cypriot Syllabary": range(67584, 67647 + 1), + "Imperial Aramaic": range(67648, 67679 + 1), + "Palmyrene": range(67680, 67711 + 1), + "Nabataean": range(67712, 67759 + 1), + "Hatran": range(67808, 67839 + 1), + "Phoenician": range(67840, 67871 + 1), + "Lydian": range(67872, 67903 + 1), + "Meroitic Hieroglyphs": range(67968, 67999 + 1), + "Meroitic Cursive": range(68000, 68095 + 1), + "Kharoshthi": range(68096, 68191 + 1), + "Old South Arabian": range(68192, 68223 + 1), + "Old North Arabian": range(68224, 68255 + 1), + "Manichaean": range(68288, 68351 + 1), + "Avestan": range(68352, 68415 + 1), + "Inscriptional Parthian": range(68416, 68447 + 1), + "Inscriptional Pahlavi": range(68448, 68479 + 1), + "Psalter Pahlavi": range(68480, 68527 + 1), + "Old Turkic": range(68608, 68687 + 1), + "Old Hungarian": range(68736, 68863 + 1), + "Rumi Numeral Symbols": range(69216, 69247 + 1), + "Brahmi": range(69632, 69759 + 1), + "Kaithi": range(69760, 69839 + 1), + "Sora Sompeng": range(69840, 69887 + 1), + "Chakma": range(69888, 69967 + 1), + "Mahajani": range(69968, 70015 + 1), + "Sharada": range(70016, 70111 + 1), + "Sinhala Archaic Numbers": range(70112, 70143 + 1), + "Khojki": range(70144, 70223 + 1), + "Multani": range(70272, 70319 + 1), + "Khudawadi": range(70320, 70399 + 1), + "Grantha": range(70400, 70527 + 1), + "Newa": range(70656, 70783 + 1), + "Tirhuta": range(70784, 70879 + 1), + "Siddham": range(71040, 71167 + 1), + "Modi": range(71168, 71263 + 1), + "Mongolian Supplement": range(71264, 71295 + 1), + "Takri": range(71296, 71375 + 1), + "Ahom": range(71424, 71487 + 1), + "Warang Citi": range(71840, 71935 + 1), + "Zanabazar Square": range(72192, 72271 + 1), + "Soyombo": range(72272, 72367 + 1), + "Pau Cin Hau": range(72384, 72447 + 1), + "Bhaiksuki": range(72704, 72815 + 1), + "Marchen": range(72816, 72895 + 1), + "Masaram Gondi": range(72960, 73055 + 1), + "Cuneiform": range(73728, 74751 + 1), + "Cuneiform Numbers and Punctuation": range(74752, 74879 + 1), + "Early Dynastic Cuneiform": range(74880, 75087 + 1), + "Egyptian Hieroglyphs": range(77824, 78895 + 1), + "Anatolian Hieroglyphs": range(82944, 83583 + 1), + "Bamum Supplement": range(92160, 92735 + 1), + "Mro": range(92736, 92783 + 1), + "Bassa Vah": range(92880, 92927 + 1), + "Pahawh Hmong": range(92928, 93071 + 1), + "Miao": range(93952, 94111 + 1), + "Ideographic Symbols and Punctuation": range(94176, 94207 + 1), + "Tangut": range(94208, 100351 + 1), + "Tangut Components": range(100352, 101119 + 1), + "Kana Supplement": range(110592, 110847 + 1), + "Kana Extended-A": range(110848, 110895 + 1), + "Nushu": range(110960, 111359 + 1), + "Duployan": range(113664, 113823 + 1), + "Shorthand Format Controls": range(113824, 113839 + 1), + "Byzantine Musical Symbols": range(118784, 119039 + 1), + "Musical Symbols": range(119040, 119295 + 1), + "Ancient Greek Musical Notation": range(119296, 119375 + 1), + "Tai Xuan Jing Symbols": range(119552, 119647 + 1), + "Counting Rod Numerals": range(119648, 119679 + 1), + "Mathematical Alphanumeric Symbols": range(119808, 120831 + 1), + "Sutton SignWriting": range(120832, 121519 + 1), + "Glagolitic Supplement": range(122880, 122927 + 1), + "Mende Kikakui": range(124928, 125151 + 1), + "Adlam": range(125184, 125279 + 1), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126719 + 1), + "Mahjong Tiles": range(126976, 127023 + 1), + "Domino Tiles": range(127024, 127135 + 1), + "Playing Cards": range(127136, 127231 + 1), + "Enclosed Alphanumeric Supplement": range(127232, 127487 + 1), + "Enclosed Ideographic Supplement": range(127488, 127743 + 1), + "Miscellaneous Symbols and Pictographs": range(127744, 128511 + 1), + "Emoticons range(Emoji)": range(128512, 128591 + 1), + "Ornamental Dingbats": range(128592, 128639 + 1), + "Transport and Map Symbols": range(128640, 128767 + 1), + "Alchemical Symbols": range(128768, 128895 + 1), + "Geometric Shapes Extended": range(128896, 129023 + 1), + "Supplemental Arrows-C": range(129024, 129279 + 1), + "Supplemental Symbols and Pictographs": range(129280, 129535 + 1), + "CJK Unified Ideographs Extension B": range(131072, 173791 + 1), + "CJK Unified Ideographs Extension C": range(173824, 177983 + 1), + "CJK Unified Ideographs Extension D": range(177984, 178207 + 1), + "CJK Unified Ideographs Extension E": range(178208, 183983 + 1), + "CJK Unified Ideographs Extension F": range(183984, 191471 + 1), + "CJK Compatibility Ideographs Supplement": range(194560, 195103 + 1), + "Tags": range(917504, 917631 + 1), + "Variation Selectors Supplement": range(917760, 917999 + 1), +} + + +UNICODE_SECONDARY_RANGE_KEYWORD: List[str] = [ + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", +] + +RE_POSSIBLE_ENCODING_INDICATION = re_compile( + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + IGNORECASE, +) + +IANA_SUPPORTED: List[str] = sorted( + filter( + lambda x: x.endswith("_codec") is False + and x not in {"rot_13", "tactis", "mbcs"}, + list(set(aliases.values())), + ) +) + +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) + +# pre-computed code page that are similar using the function cp_similarity. +IANA_SUPPORTED_SIMILAR: Dict[str, List[str]] = { + "cp037": ["cp1026", "cp1140", "cp273", "cp500"], + "cp1026": ["cp037", "cp1140", "cp273", "cp500"], + "cp1125": ["cp866"], + "cp1140": ["cp037", "cp1026", "cp273", "cp500"], + "cp1250": ["iso8859_2"], + "cp1251": ["kz1048", "ptcp154"], + "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1253": ["iso8859_7"], + "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1257": ["iso8859_13"], + "cp273": ["cp037", "cp1026", "cp1140", "cp500"], + "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], + "cp500": ["cp037", "cp1026", "cp1140", "cp273"], + "cp850": ["cp437", "cp857", "cp858", "cp865"], + "cp857": ["cp850", "cp858", "cp865"], + "cp858": ["cp437", "cp850", "cp857", "cp865"], + "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], + "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], + "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], + "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], + "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], + "cp866": ["cp1125"], + "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], + "iso8859_11": ["tis_620"], + "iso8859_13": ["cp1257"], + "iso8859_14": [ + "iso8859_10", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_15": [ + "cp1252", + "cp1254", + "iso8859_10", + "iso8859_14", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_16": [ + "iso8859_14", + "iso8859_15", + "iso8859_2", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], + "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], + "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], + "iso8859_7": ["cp1253"], + "iso8859_9": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "latin_1", + ], + "kz1048": ["cp1251", "ptcp154"], + "latin_1": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "iso8859_9", + ], + "mac_iceland": ["mac_roman", "mac_turkish"], + "mac_roman": ["mac_iceland", "mac_turkish"], + "mac_turkish": ["mac_iceland", "mac_roman"], + "ptcp154": ["cp1251", "kz1048"], + "tis_620": ["iso8859_11"], +} + + +CHARDET_CORRESPONDENCE: Dict[str, str] = { + "iso2022_kr": "ISO-2022-KR", + "iso2022_jp": "ISO-2022-JP", + "euc_kr": "EUC-KR", + "tis_620": "TIS-620", + "utf_32": "UTF-32", + "euc_jp": "EUC-JP", + "koi8_r": "KOI8-R", + "iso8859_1": "ISO-8859-1", + "iso8859_2": "ISO-8859-2", + "iso8859_5": "ISO-8859-5", + "iso8859_6": "ISO-8859-6", + "iso8859_7": "ISO-8859-7", + "iso8859_8": "ISO-8859-8", + "utf_16": "UTF-16", + "cp855": "IBM855", + "mac_cyrillic": "MacCyrillic", + "gb2312": "GB2312", + "gb18030": "GB18030", + "cp932": "CP932", + "cp866": "IBM866", + "utf_8": "utf-8", + "utf_8_sig": "UTF-8-SIG", + "shift_jis": "SHIFT_JIS", + "big5": "Big5", + "cp1250": "windows-1250", + "cp1251": "windows-1251", + "cp1252": "Windows-1252", + "cp1253": "windows-1253", + "cp1255": "windows-1255", + "cp1256": "windows-1256", + "cp1254": "Windows-1254", + "cp949": "CP949", +} + + +COMMON_SAFE_ASCII_CHARACTERS: Set[str] = { + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", +} + + +KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"} +ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"} + +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) + +# Logging LEVEL below DEBUG +TRACE: int = 5 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/legacy.py b/.venv/lib/python3.7/site-packages/charset_normalizer/legacy.py new file mode 100644 index 0000000..43aad21 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/legacy.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Optional, Union +from warnings import warn + +from .api import from_bytes +from .constant import CHARDET_CORRESPONDENCE + + +def detect( + byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any +) -> Dict[str, Optional[Union[str, float]]]: + """ + chardet legacy method + Detect the encoding of the given byte string. It should be mostly backward-compatible. + Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) + This function is deprecated and should be used to migrate your project easily, consult the documentation for + further information. Not planned for removal. + + :param byte_str: The byte sequence to examine. + :param should_rename_legacy: Should we rename legacy encodings + to their more modern equivalents? + """ + if len(kwargs): + warn( + f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" + ) + + if not isinstance(byte_str, (bytearray, bytes)): + raise TypeError( # pragma: nocover + "Expected object of type bytes or bytearray, got: " + "{0}".format(type(byte_str)) + ) + + if isinstance(byte_str, bytearray): + byte_str = bytes(byte_str) + + r = from_bytes(byte_str).best() + + encoding = r.encoding if r is not None else None + language = r.language if r is not None and r.language != "Unknown" else "" + confidence = 1.0 - r.chaos if r is not None else None + + # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process + # but chardet does return 'utf-8-sig' and it is a valid codec name. + if r is not None and encoding == "utf_8" and r.bom: + encoding += "_sig" + + if should_rename_legacy is False and encoding in CHARDET_CORRESPONDENCE: + encoding = CHARDET_CORRESPONDENCE[encoding] + + return { + "encoding": encoding, + "language": language, + "confidence": confidence, + } diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/md.py b/.venv/lib/python3.7/site-packages/charset_normalizer/md.py new file mode 100644 index 0000000..56e9321 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/md.py @@ -0,0 +1,571 @@ +from functools import lru_cache +from logging import getLogger +from typing import List, Optional + +from .constant import ( + COMMON_SAFE_ASCII_CHARACTERS, + TRACE, + UNICODE_SECONDARY_RANGE_KEYWORD, +) +from .utils import ( + is_accentuated, + is_ascii, + is_case_variable, + is_cjk, + is_emoticon, + is_hangul, + is_hiragana, + is_katakana, + is_latin, + is_punctuation, + is_separator, + is_symbol, + is_thai, + is_unprintable, + remove_accent, + unicode_range, +) + + +class MessDetectorPlugin: + """ + Base abstract class used for mess detection plugins. + All detectors MUST extend and implement given methods. + """ + + def eligible(self, character: str) -> bool: + """ + Determine if given character should be fed in. + """ + raise NotImplementedError # pragma: nocover + + def feed(self, character: str) -> None: + """ + The main routine to be executed upon character. + Insert the logic in witch the text would be considered chaotic. + """ + raise NotImplementedError # pragma: nocover + + def reset(self) -> None: # pragma: no cover + """ + Permit to reset the plugin to the initial state. + """ + raise NotImplementedError + + @property + def ratio(self) -> float: + """ + Compute the chaos ratio based on what your feed() has seen. + Must NOT be lower than 0.; No restriction gt 0. + """ + raise NotImplementedError # pragma: nocover + + +class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._punctuation_count: int = 0 + self._symbol_count: int = 0 + self._character_count: int = 0 + + self._last_printable_char: Optional[str] = None + self._frenzy_symbol_in_word: bool = False + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character != self._last_printable_char + and character not in COMMON_SAFE_ASCII_CHARACTERS + ): + if is_punctuation(character): + self._punctuation_count += 1 + elif ( + character.isdigit() is False + and is_symbol(character) + and is_emoticon(character) is False + ): + self._symbol_count += 2 + + self._last_printable_char = character + + def reset(self) -> None: # pragma: no cover + self._punctuation_count = 0 + self._character_count = 0 + self._symbol_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + ratio_of_punctuation: float = ( + self._punctuation_count + self._symbol_count + ) / self._character_count + + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 + + +class TooManyAccentuatedPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._accentuated_count: int = 0 + + def eligible(self, character: str) -> bool: + return character.isalpha() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if is_accentuated(character): + self._accentuated_count += 1 + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._accentuated_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0 or self._character_count < 8: + return 0.0 + ratio_of_accentuation: float = self._accentuated_count / self._character_count + return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 + + +class UnprintablePlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._unprintable_count: int = 0 + self._character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if is_unprintable(character): + self._unprintable_count += 1 + self._character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._unprintable_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._unprintable_count * 8) / self._character_count + + +class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._successive_count: int = 0 + self._character_count: int = 0 + + self._last_latin_character: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isalpha() and is_latin(character) + + def feed(self, character: str) -> None: + self._character_count += 1 + if ( + self._last_latin_character is not None + and is_accentuated(character) + and is_accentuated(self._last_latin_character) + ): + if character.isupper() and self._last_latin_character.isupper(): + self._successive_count += 1 + # Worse if its the same char duplicated with different accent. + if remove_accent(character) == remove_accent(self._last_latin_character): + self._successive_count += 1 + self._last_latin_character = character + + def reset(self) -> None: # pragma: no cover + self._successive_count = 0 + self._character_count = 0 + self._last_latin_character = None + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._successive_count * 2) / self._character_count + + +class SuspiciousRange(MessDetectorPlugin): + def __init__(self) -> None: + self._suspicious_successive_range_count: int = 0 + self._character_count: int = 0 + self._last_printable_seen: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character.isspace() + or is_punctuation(character) + or character in COMMON_SAFE_ASCII_CHARACTERS + ): + self._last_printable_seen = None + return + + if self._last_printable_seen is None: + self._last_printable_seen = character + return + + unicode_range_a: Optional[str] = unicode_range(self._last_printable_seen) + unicode_range_b: Optional[str] = unicode_range(character) + + if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): + self._suspicious_successive_range_count += 1 + + self._last_printable_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._suspicious_successive_range_count = 0 + self._last_printable_seen = None + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + ratio_of_suspicious_range_usage: float = ( + self._suspicious_successive_range_count * 2 + ) / self._character_count + + if ratio_of_suspicious_range_usage < 0.1: + return 0.0 + + return ratio_of_suspicious_range_usage + + +class SuperWeirdWordPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._word_count: int = 0 + self._bad_word_count: int = 0 + self._foreign_long_count: int = 0 + + self._is_current_word_bad: bool = False + self._foreign_long_watch: bool = False + + self._character_count: int = 0 + self._bad_character_count: int = 0 + + self._buffer: str = "" + self._buffer_accent_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character.isalpha(): + self._buffer += character + if is_accentuated(character): + self._buffer_accent_count += 1 + if ( + self._foreign_long_watch is False + and (is_latin(character) is False or is_accentuated(character)) + and is_cjk(character) is False + and is_hangul(character) is False + and is_katakana(character) is False + and is_hiragana(character) is False + and is_thai(character) is False + ): + self._foreign_long_watch = True + return + if not self._buffer: + return + if ( + character.isspace() or is_punctuation(character) or is_separator(character) + ) and self._buffer: + self._word_count += 1 + buffer_length: int = len(self._buffer) + + self._character_count += buffer_length + + if buffer_length >= 4: + if self._buffer_accent_count / buffer_length > 0.34: + self._is_current_word_bad = True + # Word/Buffer ending with a upper case accentuated letter are so rare, + # that we will consider them all as suspicious. Same weight as foreign_long suspicious. + if is_accentuated(self._buffer[-1]) and self._buffer[-1].isupper(): + self._foreign_long_count += 1 + self._is_current_word_bad = True + if buffer_length >= 24 and self._foreign_long_watch: + self._foreign_long_count += 1 + self._is_current_word_bad = True + + if self._is_current_word_bad: + self._bad_word_count += 1 + self._bad_character_count += len(self._buffer) + self._is_current_word_bad = False + + self._foreign_long_watch = False + self._buffer = "" + self._buffer_accent_count = 0 + elif ( + character not in {"<", ">", "-", "=", "~", "|", "_"} + and character.isdigit() is False + and is_symbol(character) + ): + self._is_current_word_bad = True + self._buffer += character + + def reset(self) -> None: # pragma: no cover + self._buffer = "" + self._is_current_word_bad = False + self._foreign_long_watch = False + self._bad_word_count = 0 + self._word_count = 0 + self._character_count = 0 + self._bad_character_count = 0 + self._foreign_long_count = 0 + + @property + def ratio(self) -> float: + if self._word_count <= 10 and self._foreign_long_count == 0: + return 0.0 + + return self._bad_character_count / self._character_count + + +class CjkInvalidStopPlugin(MessDetectorPlugin): + """ + GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and + can be easily detected. Searching for the overuse of '丅' and '丄'. + """ + + def __init__(self) -> None: + self._wrong_stop_count: int = 0 + self._cjk_character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character in {"丅", "丄"}: + self._wrong_stop_count += 1 + return + if is_cjk(character): + self._cjk_character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._wrong_stop_count = 0 + self._cjk_character_count = 0 + + @property + def ratio(self) -> float: + if self._cjk_character_count < 16: + return 0.0 + return self._wrong_stop_count / self._cjk_character_count + + +class ArchaicUpperLowerPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._buf: bool = False + + self._character_count_since_last_sep: int = 0 + + self._successive_upper_lower_count: int = 0 + self._successive_upper_lower_count_final: int = 0 + + self._character_count: int = 0 + + self._last_alpha_seen: Optional[str] = None + self._current_ascii_only: bool = True + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + is_concerned = character.isalpha() and is_case_variable(character) + chunk_sep = is_concerned is False + + if chunk_sep and self._character_count_since_last_sep > 0: + if ( + self._character_count_since_last_sep <= 64 + and character.isdigit() is False + and self._current_ascii_only is False + ): + self._successive_upper_lower_count_final += ( + self._successive_upper_lower_count + ) + + self._successive_upper_lower_count = 0 + self._character_count_since_last_sep = 0 + self._last_alpha_seen = None + self._buf = False + self._character_count += 1 + self._current_ascii_only = True + + return + + if self._current_ascii_only is True and is_ascii(character) is False: + self._current_ascii_only = False + + if self._last_alpha_seen is not None: + if (character.isupper() and self._last_alpha_seen.islower()) or ( + character.islower() and self._last_alpha_seen.isupper() + ): + if self._buf is True: + self._successive_upper_lower_count += 2 + self._buf = False + else: + self._buf = True + else: + self._buf = False + + self._character_count += 1 + self._character_count_since_last_sep += 1 + self._last_alpha_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._character_count_since_last_sep = 0 + self._successive_upper_lower_count = 0 + self._successive_upper_lower_count_final = 0 + self._last_alpha_seen = None + self._buf = False + self._current_ascii_only = True + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return self._successive_upper_lower_count_final / self._character_count + + +@lru_cache(maxsize=1024) +def is_suspiciously_successive_range( + unicode_range_a: Optional[str], unicode_range_b: Optional[str] +) -> bool: + """ + Determine if two Unicode range seen next to each other can be considered as suspicious. + """ + if unicode_range_a is None or unicode_range_b is None: + return True + + if unicode_range_a == unicode_range_b: + return False + + if "Latin" in unicode_range_a and "Latin" in unicode_range_b: + return False + + if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b: + return False + + # Latin characters can be accompanied with a combining diacritical mark + # eg. Vietnamese. + if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and ( + "Combining" in unicode_range_a or "Combining" in unicode_range_b + ): + return False + + keywords_range_a, keywords_range_b = unicode_range_a.split( + " " + ), unicode_range_b.split(" ") + + for el in keywords_range_a: + if el in UNICODE_SECONDARY_RANGE_KEYWORD: + continue + if el in keywords_range_b: + return False + + # Japanese Exception + range_a_jp_chars, range_b_jp_chars = ( + unicode_range_a + in ( + "Hiragana", + "Katakana", + ), + unicode_range_b in ("Hiragana", "Katakana"), + ) + if (range_a_jp_chars or range_b_jp_chars) and ( + "CJK" in unicode_range_a or "CJK" in unicode_range_b + ): + return False + if range_a_jp_chars and range_b_jp_chars: + return False + + if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b: + if "CJK" in unicode_range_a or "CJK" in unicode_range_b: + return False + if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": + return False + + # Chinese/Japanese use dedicated range for punctuation and/or separators. + if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or ( + unicode_range_a in ["Katakana", "Hiragana"] + and unicode_range_b in ["Katakana", "Hiragana"] + ): + if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b: + return False + if "Forms" in unicode_range_a or "Forms" in unicode_range_b: + return False + + return True + + +@lru_cache(maxsize=2048) +def mess_ratio( + decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False +) -> float: + """ + Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. + """ + + detectors: List[MessDetectorPlugin] = [ + md_class() for md_class in MessDetectorPlugin.__subclasses__() + ] + + length: int = len(decoded_sequence) + 1 + + mean_mess_ratio: float = 0.0 + + if length < 512: + intermediary_mean_mess_ratio_calc: int = 32 + elif length <= 1024: + intermediary_mean_mess_ratio_calc = 64 + else: + intermediary_mean_mess_ratio_calc = 128 + + for character, index in zip(decoded_sequence + "\n", range(length)): + for detector in detectors: + if detector.eligible(character): + detector.feed(character) + + if ( + index > 0 and index % intermediary_mean_mess_ratio_calc == 0 + ) or index == length - 1: + mean_mess_ratio = sum(dt.ratio for dt in detectors) + + if mean_mess_ratio >= maximum_threshold: + break + + if debug: + logger = getLogger("charset_normalizer") + + logger.log( + TRACE, + "Mess-detector extended-analysis start. " + f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} " + f"maximum_threshold={maximum_threshold}", + ) + + if len(decoded_sequence) > 16: + logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") + logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") + + for dt in detectors: # pragma: nocover + logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") + + return round(mean_mess_ratio, 3) diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/models.py b/.venv/lib/python3.7/site-packages/charset_normalizer/models.py new file mode 100644 index 0000000..7f8ca38 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/models.py @@ -0,0 +1,337 @@ +from encodings.aliases import aliases +from hashlib import sha256 +from json import dumps +from typing import Any, Dict, Iterator, List, Optional, Tuple, Union + +from .constant import TOO_BIG_SEQUENCE +from .utils import iana_name, is_multi_byte_encoding, unicode_range + + +class CharsetMatch: + def __init__( + self, + payload: bytes, + guessed_encoding: str, + mean_mess_ratio: float, + has_sig_or_bom: bool, + languages: "CoherenceMatches", + decoded_payload: Optional[str] = None, + ): + self._payload: bytes = payload + + self._encoding: str = guessed_encoding + self._mean_mess_ratio: float = mean_mess_ratio + self._languages: CoherenceMatches = languages + self._has_sig_or_bom: bool = has_sig_or_bom + self._unicode_ranges: Optional[List[str]] = None + + self._leaves: List[CharsetMatch] = [] + self._mean_coherence_ratio: float = 0.0 + + self._output_payload: Optional[bytes] = None + self._output_encoding: Optional[str] = None + + self._string: Optional[str] = decoded_payload + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CharsetMatch): + raise TypeError( + "__eq__ cannot be invoked on {} and {}.".format( + str(other.__class__), str(self.__class__) + ) + ) + return self.encoding == other.encoding and self.fingerprint == other.fingerprint + + def __lt__(self, other: object) -> bool: + """ + Implemented to make sorted available upon CharsetMatches items. + """ + if not isinstance(other, CharsetMatch): + raise ValueError + + chaos_difference: float = abs(self.chaos - other.chaos) + coherence_difference: float = abs(self.coherence - other.coherence) + + # Below 1% difference --> Use Coherence + if chaos_difference < 0.01 and coherence_difference > 0.02: + # When having a tough decision, use the result that decoded as many multi-byte as possible. + if chaos_difference == 0.0 and self.coherence == other.coherence: + return self.multi_byte_usage > other.multi_byte_usage + return self.coherence > other.coherence + + return self.chaos < other.chaos + + @property + def multi_byte_usage(self) -> float: + return 1.0 - len(str(self)) / len(self.raw) + + def __str__(self) -> str: + # Lazy Str Loading + if self._string is None: + self._string = str(self._payload, self._encoding, "strict") + return self._string + + def __repr__(self) -> str: + return "".format(self.encoding, self.fingerprint) + + def add_submatch(self, other: "CharsetMatch") -> None: + if not isinstance(other, CharsetMatch) or other == self: + raise ValueError( + "Unable to add instance <{}> as a submatch of a CharsetMatch".format( + other.__class__ + ) + ) + + other._string = None # Unload RAM usage; dirty trick. + self._leaves.append(other) + + @property + def encoding(self) -> str: + return self._encoding + + @property + def encoding_aliases(self) -> List[str]: + """ + Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. + """ + also_known_as: List[str] = [] + for u, p in aliases.items(): + if self.encoding == u: + also_known_as.append(p) + elif self.encoding == p: + also_known_as.append(u) + return also_known_as + + @property + def bom(self) -> bool: + return self._has_sig_or_bom + + @property + def byte_order_mark(self) -> bool: + return self._has_sig_or_bom + + @property + def languages(self) -> List[str]: + """ + Return the complete list of possible languages found in decoded sequence. + Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. + """ + return [e[0] for e in self._languages] + + @property + def language(self) -> str: + """ + Most probable language found in decoded sequence. If none were detected or inferred, the property will return + "Unknown". + """ + if not self._languages: + # Trying to infer the language based on the given encoding + # Its either English or we should not pronounce ourselves in certain cases. + if "ascii" in self.could_be_from_charset: + return "English" + + # doing it there to avoid circular import + from charset_normalizer.cd import encoding_languages, mb_encoding_languages + + languages = ( + mb_encoding_languages(self.encoding) + if is_multi_byte_encoding(self.encoding) + else encoding_languages(self.encoding) + ) + + if len(languages) == 0 or "Latin Based" in languages: + return "Unknown" + + return languages[0] + + return self._languages[0][0] + + @property + def chaos(self) -> float: + return self._mean_mess_ratio + + @property + def coherence(self) -> float: + if not self._languages: + return 0.0 + return self._languages[0][1] + + @property + def percent_chaos(self) -> float: + return round(self.chaos * 100, ndigits=3) + + @property + def percent_coherence(self) -> float: + return round(self.coherence * 100, ndigits=3) + + @property + def raw(self) -> bytes: + """ + Original untouched bytes. + """ + return self._payload + + @property + def submatch(self) -> List["CharsetMatch"]: + return self._leaves + + @property + def has_submatch(self) -> bool: + return len(self._leaves) > 0 + + @property + def alphabets(self) -> List[str]: + if self._unicode_ranges is not None: + return self._unicode_ranges + # list detected ranges + detected_ranges: List[Optional[str]] = [ + unicode_range(char) for char in str(self) + ] + # filter and sort + self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) + return self._unicode_ranges + + @property + def could_be_from_charset(self) -> List[str]: + """ + The complete list of encoding that output the exact SAME str result and therefore could be the originating + encoding. + This list does include the encoding available in property 'encoding'. + """ + return [self._encoding] + [m.encoding for m in self._leaves] + + def output(self, encoding: str = "utf_8") -> bytes: + """ + Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. + Any errors will be simply ignored by the encoder NOT replaced. + """ + if self._output_encoding is None or self._output_encoding != encoding: + self._output_encoding = encoding + self._output_payload = str(self).encode(encoding, "replace") + + return self._output_payload # type: ignore + + @property + def fingerprint(self) -> str: + """ + Retrieve the unique SHA256 computed using the transformed (re-encoded) payload. Not the original one. + """ + return sha256(self.output()).hexdigest() + + +class CharsetMatches: + """ + Container with every CharsetMatch items ordered by default from most probable to the less one. + Act like a list(iterable) but does not implements all related methods. + """ + + def __init__(self, results: Optional[List[CharsetMatch]] = None): + self._results: List[CharsetMatch] = sorted(results) if results else [] + + def __iter__(self) -> Iterator[CharsetMatch]: + yield from self._results + + def __getitem__(self, item: Union[int, str]) -> CharsetMatch: + """ + Retrieve a single item either by its position or encoding name (alias may be used here). + Raise KeyError upon invalid index or encoding not present in results. + """ + if isinstance(item, int): + return self._results[item] + if isinstance(item, str): + item = iana_name(item, False) + for result in self._results: + if item in result.could_be_from_charset: + return result + raise KeyError + + def __len__(self) -> int: + return len(self._results) + + def __bool__(self) -> bool: + return len(self._results) > 0 + + def append(self, item: CharsetMatch) -> None: + """ + Insert a single match. Will be inserted accordingly to preserve sort. + Can be inserted as a submatch. + """ + if not isinstance(item, CharsetMatch): + raise ValueError( + "Cannot append instance '{}' to CharsetMatches".format( + str(item.__class__) + ) + ) + # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) + if len(item.raw) <= TOO_BIG_SEQUENCE: + for match in self._results: + if match.fingerprint == item.fingerprint and match.chaos == item.chaos: + match.add_submatch(item) + return + self._results.append(item) + self._results = sorted(self._results) + + def best(self) -> Optional["CharsetMatch"]: + """ + Simply return the first match. Strict equivalent to matches[0]. + """ + if not self._results: + return None + return self._results[0] + + def first(self) -> Optional["CharsetMatch"]: + """ + Redundant method, call the method best(). Kept for BC reasons. + """ + return self.best() + + +CoherenceMatch = Tuple[str, float] +CoherenceMatches = List[CoherenceMatch] + + +class CliDetectionResult: + def __init__( + self, + path: str, + encoding: Optional[str], + encoding_aliases: List[str], + alternative_encodings: List[str], + language: str, + alphabets: List[str], + has_sig_or_bom: bool, + chaos: float, + coherence: float, + unicode_path: Optional[str], + is_preferred: bool, + ): + self.path: str = path + self.unicode_path: Optional[str] = unicode_path + self.encoding: Optional[str] = encoding + self.encoding_aliases: List[str] = encoding_aliases + self.alternative_encodings: List[str] = alternative_encodings + self.language: str = language + self.alphabets: List[str] = alphabets + self.has_sig_or_bom: bool = has_sig_or_bom + self.chaos: float = chaos + self.coherence: float = coherence + self.is_preferred: bool = is_preferred + + @property + def __dict__(self) -> Dict[str, Any]: # type: ignore + return { + "path": self.path, + "encoding": self.encoding, + "encoding_aliases": self.encoding_aliases, + "alternative_encodings": self.alternative_encodings, + "language": self.language, + "alphabets": self.alphabets, + "has_sig_or_bom": self.has_sig_or_bom, + "chaos": self.chaos, + "coherence": self.coherence, + "unicode_path": self.unicode_path, + "is_preferred": self.is_preferred, + } + + def to_json(self) -> str: + return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/py.typed b/.venv/lib/python3.7/site-packages/charset_normalizer/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/utils.py b/.venv/lib/python3.7/site-packages/charset_normalizer/utils.py new file mode 100644 index 0000000..76eafc6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/utils.py @@ -0,0 +1,414 @@ +import importlib +import logging +import unicodedata +from codecs import IncrementalDecoder +from encodings.aliases import aliases +from functools import lru_cache +from re import findall +from typing import Generator, List, Optional, Set, Tuple, Union + +from _multibytecodec import MultibyteIncrementalDecoder + +from .constant import ( + ENCODING_MARKS, + IANA_SUPPORTED_SIMILAR, + RE_POSSIBLE_ENCODING_INDICATION, + UNICODE_RANGES_COMBINED, + UNICODE_SECONDARY_RANGE_KEYWORD, + UTF8_MAXIMAL_ALLOCATION, +) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_accentuated(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return ( + "WITH GRAVE" in description + or "WITH ACUTE" in description + or "WITH CEDILLA" in description + or "WITH DIAERESIS" in description + or "WITH CIRCUMFLEX" in description + or "WITH TILDE" in description + ) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def remove_accent(character: str) -> str: + decomposed: str = unicodedata.decomposition(character) + if not decomposed: + return character + + codes: List[str] = decomposed.split(" ") + + return chr(int(codes[0], 16)) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def unicode_range(character: str) -> Optional[str]: + """ + Retrieve the Unicode range official name from a single character. + """ + character_ord: int = ord(character) + + for range_name, ord_range in UNICODE_RANGES_COMBINED.items(): + if character_ord in ord_range: + return range_name + + return None + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_latin(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return "LATIN" in description + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_ascii(character: str) -> bool: + try: + character.encode("ascii") + except UnicodeEncodeError: + return False + return True + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_punctuation(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "P" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Punctuation" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_symbol(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "S" in character_category or "N" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Forms" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_emoticon(character: str) -> bool: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Emoticons" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_separator(character: str) -> bool: + if character.isspace() or character in {"|", "+", ",", ";", "<", ">"}: + return True + + character_category: str = unicodedata.category(character) + + return "Z" in character_category + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_case_variable(character: str) -> bool: + return character.islower() != character.isupper() + + +def is_private_use_only(character: str) -> bool: + character_category: str = unicodedata.category(character) + + return character_category == "Co" + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_cjk(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "CJK" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hiragana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HIRAGANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_katakana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "KATAKANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hangul(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HANGUL" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_thai(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "THAI" in character_name + + +@lru_cache(maxsize=len(UNICODE_RANGES_COMBINED)) +def is_unicode_range_secondary(range_name: str) -> bool: + return any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_unprintable(character: str) -> bool: + return ( + character.isspace() is False # includes \n \t \r \v + and character.isprintable() is False + and character != "\x1A" # Why? Its the ASCII substitute character. + and character != "\ufeff" # bug discovered in Python, + # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. + ) + + +def any_specified_encoding(sequence: bytes, search_zone: int = 4096) -> Optional[str]: + """ + Extract using ASCII-only decoder any specified encoding in the first n-bytes. + """ + if not isinstance(sequence, bytes): + raise TypeError + + seq_len: int = len(sequence) + + results: List[str] = findall( + RE_POSSIBLE_ENCODING_INDICATION, + sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"), + ) + + if len(results) == 0: + return None + + for specified_encoding in results: + specified_encoding = specified_encoding.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if encoding_alias == specified_encoding: + return encoding_iana + if encoding_iana == specified_encoding: + return encoding_iana + + return None + + +@lru_cache(maxsize=128) +def is_multi_byte_encoding(name: str) -> bool: + """ + Verify is a specific encoding is a multi byte one based on it IANA name + """ + return name in { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_le", + "utf_32_be", + "utf_7", + } or issubclass( + importlib.import_module("encodings.{}".format(name)).IncrementalDecoder, + MultibyteIncrementalDecoder, + ) + + +def identify_sig_or_bom(sequence: bytes) -> Tuple[Optional[str], bytes]: + """ + Identify and extract SIG/BOM in given sequence. + """ + + for iana_encoding in ENCODING_MARKS: + marks: Union[bytes, List[bytes]] = ENCODING_MARKS[iana_encoding] + + if isinstance(marks, bytes): + marks = [marks] + + for mark in marks: + if sequence.startswith(mark): + return iana_encoding, mark + + return None, b"" + + +def should_strip_sig_or_bom(iana_encoding: str) -> bool: + return iana_encoding not in {"utf_16", "utf_32"} + + +def iana_name(cp_name: str, strict: bool = True) -> str: + cp_name = cp_name.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if cp_name in [encoding_alias, encoding_iana]: + return encoding_iana + + if strict: + raise ValueError("Unable to retrieve IANA for '{}'".format(cp_name)) + + return cp_name + + +def range_scan(decoded_sequence: str) -> List[str]: + ranges: Set[str] = set() + + for character in decoded_sequence: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + ranges.add(character_range) + + return list(ranges) + + +def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: + if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): + return 0.0 + + decoder_a = importlib.import_module( + "encodings.{}".format(iana_name_a) + ).IncrementalDecoder + decoder_b = importlib.import_module( + "encodings.{}".format(iana_name_b) + ).IncrementalDecoder + + id_a: IncrementalDecoder = decoder_a(errors="ignore") + id_b: IncrementalDecoder = decoder_b(errors="ignore") + + character_match_count: int = 0 + + for i in range(255): + to_be_decoded: bytes = bytes([i]) + if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): + character_match_count += 1 + + return character_match_count / 254 + + +def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: + """ + Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using + the function cp_similarity. + """ + return ( + iana_name_a in IANA_SUPPORTED_SIMILAR + and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + ) + + +def set_logging_handler( + name: str = "charset_normalizer", + level: int = logging.INFO, + format_string: str = "%(asctime)s | %(levelname)s | %(message)s", +) -> None: + logger = logging.getLogger(name) + logger.setLevel(level) + + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(format_string)) + logger.addHandler(handler) + + +def cut_sequence_chunks( + sequences: bytes, + encoding_iana: str, + offsets: range, + chunk_size: int, + bom_or_sig_available: bool, + strip_sig_or_bom: bool, + sig_payload: bytes, + is_multi_byte_decoder: bool, + decoded_payload: Optional[str] = None, +) -> Generator[str, None, None]: + if decoded_payload and is_multi_byte_decoder is False: + for i in offsets: + chunk = decoded_payload[i : i + chunk_size] + if not chunk: + break + yield chunk + else: + for i in offsets: + chunk_end = i + chunk_size + if chunk_end > len(sequences) + 8: + continue + + cut_sequence = sequences[i : i + chunk_size] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode( + encoding_iana, + errors="ignore" if is_multi_byte_decoder else "strict", + ) + + # multi-byte bad cutting detector and adjustment + # not the cleanest way to perform that fix but clever enough for now. + if is_multi_byte_decoder and i > 0: + chunk_partial_size_chk: int = min(chunk_size, 16) + + if ( + decoded_payload + and chunk[:chunk_partial_size_chk] not in decoded_payload + ): + for j in range(i, i - 4, -1): + cut_sequence = sequences[j:chunk_end] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode(encoding_iana, errors="ignore") + + if chunk[:chunk_partial_size_chk] in decoded_payload: + break + + yield chunk diff --git a/.venv/lib/python3.7/site-packages/charset_normalizer/version.py b/.venv/lib/python3.7/site-packages/charset_normalizer/version.py new file mode 100644 index 0000000..b74c264 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/charset_normalizer/version.py @@ -0,0 +1,6 @@ +""" +Expose version +""" + +__version__ = "3.1.0" +VERSION = __version__.split(".") diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/LICENSE.txt b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..27c7def --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/LICENSE.txt @@ -0,0 +1,25 @@ +SPDX-License-Identifier: BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/METADATA b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/METADATA new file mode 100644 index 0000000..cff3151 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/METADATA @@ -0,0 +1,100 @@ +Metadata-Version: 2.1 +Name: colorzero +Version: 2.0 +Summary: Yet another Python color library +Home-page: UNKNOWN +Author: Dave Jones +Author-email: dave@waveform.org.uk +License: BSD-3-Clause +Project-URL: Documentation, https://colorzero.readthedocs.io/ +Project-URL: Source Code, https://github.com/waveform80/colorzero/ +Project-URL: Issue Tracker, https://github.com/waveform80/colorzero/issues +Keywords: color +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: Developers +Classifier: Topic :: Education +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Dist: setuptools +Provides-Extra: doc +Requires-Dist: pkginfo ; extra == 'doc' +Requires-Dist: sphinx ; extra == 'doc' +Requires-Dist: sphinx-rtd-theme ; extra == 'doc' +Provides-Extra: test +Requires-Dist: pytest ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' + +.. -*- rst -*- + +========= +colorzero +========= + +colorzero is a color manipulation library for Python (yes, *another* one) which +aims to be reasonably simple to use and "pythonic" in nature. + +It does *not* aim to be as comprehensive, powerful, or that matter as *correct* +as, say, `colormath`_. colorzero originally grew out of work on my `picamera`_ +project, hence it's intended to be sufficiently simple that school children can +use it without having to explain color spaces and illuminants. However, it does +aim to be useful to a wide range of skills, hence it does include basic +facilities for `CIE Lab`_ representations, and `Delta-E`_ calculations should +you need them. + +The major difference between colorzero and other libraries (`grapefruit`_, +`colormath`_, etc.) is that its ``Color`` class is a ``namedtuple`` descendent. +This means it is immutable; you cannot *directly* change the attributes of a +``Color`` instance. The major advantage of this is that instances can be used +as keys in dictionaries (for simple `LUTs`_), or placed in sets. + +Manipulation of ``Color`` instances is done by typical operations with other +classes the result of which is a new ``Color`` instance. For example:: + + >>> Color('red') + Color('blue') + + >>> Color('magenta') - Color('red') + + >>> Color('red') - Red(0.5) + + >>> Color('green') + Color('grey').red + + >>> Color.from_hls(0.5, 0.5, 1.0) + + >>> Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8) + + >>> (Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8)).hls + HLS(h=0.5, l=0.4, s=1.0) + +Links +===== + +* The code is licensed under the `BSD license`_ +* The `source code`_ can be obtained from GitHub, which also hosts the `bug + tracker`_ +* The `documentation`_ (which includes installation, quick-start examples, and + lots of code recipes) can be read on ReadTheDocs +* Packages can be downloaded from `PyPI`_, but reading the installation + instructions is more likely to be useful + + +.. _picamera: https://picamera.readthedocs.io/ +.. _colormath: https://python-colormath.readthedocs.io/ +.. _grapefruit: https://grapefruit.readthedocs.io/ +.. _CIE Lab: https://en.wikipedia.org/wiki/Lab_color_space +.. _Delta-E: https://en.wikipedia.org/wiki/Color_difference +.. _PyPI: http://pypi.python.org/pypi/colorzero/ +.. _documentation: http://colorzero.readthedocs.io/ +.. _source code: https://github.com/waveform80/colorzero +.. _bug tracker: https://github.com/waveform80/colorzero/issues +.. _BSD license: http://opensource.org/licenses/BSD-3-Clause +.. _LUTs: https://en.wikipedia.org/wiki/Lookup_table#Lookup_tables_in_image_processing + + diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/RECORD b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/RECORD new file mode 100644 index 0000000..bc58d17 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/RECORD @@ -0,0 +1,22 @@ +colorzero-2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +colorzero-2.0.dist-info/LICENSE.txt,sha256=7hx29GVBDDSALd-B1w4ep6RULPWEWUJQOEmNj042u0U,1504 +colorzero-2.0.dist-info/METADATA,sha256=wZsiK6mA8-hSbDs_vV4VAj0EKdl7Rdm23AMCKWW8BkI,4142 +colorzero-2.0.dist-info/RECORD,, +colorzero-2.0.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 +colorzero-2.0.dist-info/top_level.txt,sha256=JcyzC5NTo41c0MjR6cmoUbb7saKEuWOc_oD2K-pKbcU,10 +colorzero/__init__.py,sha256=JIp-Pw9y_-saKTBjDvrUSihMRDjrRdARvdQm0lmave8,878 +colorzero/__pycache__/__init__.cpython-37.pyc,, +colorzero/__pycache__/attr.cpython-37.pyc,, +colorzero/__pycache__/color.cpython-37.pyc,, +colorzero/__pycache__/conversions.cpython-37.pyc,, +colorzero/__pycache__/deltae.cpython-37.pyc,, +colorzero/__pycache__/easings.cpython-37.pyc,, +colorzero/__pycache__/tables.cpython-37.pyc,, +colorzero/__pycache__/types.cpython-37.pyc,, +colorzero/attr.py,sha256=RQLpFz1HH5IalpVmiezHXrjIKg9RGgn2e2qP5Dqc8Qk,6653 +colorzero/color.py,sha256=e6_Y0Fi8vhI81tCuwl9BDnJf4hgB2NpxQ8FP_KdXmXA,38856 +colorzero/conversions.py,sha256=uNNDUL1vshPvRaZnu0z6izGgQ2FGByzQJerFRKD-qSc,11343 +colorzero/deltae.py,sha256=uUESZMfOY6kXXqxdSHAXeOXMV_EX757i1v8eBic1Qn0,5673 +colorzero/easings.py,sha256=FLf3wfYbRJObE85bXPCMJBCQnqRlvvg_LrBTArcTLX0,885 +colorzero/tables.py,sha256=K31J-X7ojqJLk-Y0wwVlqIVswJ0tp7XiLbnD2161k70,13892 +colorzero/types.py,sha256=TyKgk5c6buctDYuxTF94Q7INM5rYEHTPGBliaDtOklo,9210 diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/WHEEL new file mode 100644 index 0000000..ef99c6c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/top_level.txt new file mode 100644 index 0000000..595fe52 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero-2.0.dist-info/top_level.txt @@ -0,0 +1 @@ +colorzero diff --git a/.venv/lib/python3.7/site-packages/colorzero/__init__.py b/.venv/lib/python3.7/site-packages/colorzero/__init__.py new file mode 100644 index 0000000..90a8536 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/__init__.py @@ -0,0 +1,29 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2018 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +The colorzero package defines a number of classes for representation and +manipulation of colors. The primary class of interest to users is +:class:`Color`. The other classes are used for manipulation of the attributes +on this class and are: + +* :class:`Red` +* :class:`Green` +* :class:`Blue` +* :class:`Hue` +* :class:`Lightness` +* :class:`Saturation` +* :class:`Luma` +""" + +from .color import Color +from .easings import linear, ease_in, ease_out, ease_in_out +from .deltae import euclid, cie1976, cie1994g, cie1994t, ciede2000 +from .attr import Red, Green, Blue, Hue, Lightness, Saturation, Luma +from .types import RGB, HLS, HSV, CMY, CMYK, YUV, YIQ, XYZ, Luv, Lab +from .tables import NAMED_COLORS diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90ba113551cffc5077077c3a8d2aafe7cbf50274 GIT binary patch literal 1110 zcmZ9L+iuh_5QdXYvWIk+p6MCP;bxI&3qqh)2tf-1!~%i^M17NbH*Oo@NrLSll_!E% z@-0`q0$0og3Ja0)Y3BEgXU2*5dcD}g=i2Z~ng^cujhwTmfyRA&%@;)KaWD1LhVr4o z8$Q{A3LxYmL_C5fZ$gW=YCTkK=Ur>49xObnB#LW z&*x!*FTf&StYez$JS_1gSmw*H!dGCGufiH%gLS?R8+-#U@C$H}Uj)Wk9p6%y;4;6A zc6;dcI|6*qi{G3`HZD}5KTBP(Qj9-{W64r^l;zSe!SV`5QnTWSjg>G4wWC5aElVwp z%&o9lku#B}F^D`XEA>mDaN5*tGAdB&41_-YwFT{!DtAAdvzgo*pD&m@g4>ahKS)i7wkVja3SKE3l83*fAI8`3*H}a z7YwRT2rr&hdibJ$#kGgg-AK=`qo5E3{#Ae5{|OJLK6d~B literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/attr.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/attr.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a5dbac4d550fa7b8006d9d15ea6b5230c98efe2 GIT binary patch literal 7932 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/conversions.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/conversions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f0dee95c73671d21b45e73c84ad5b88d5ff5cc3 GIT binary patch literal 12902 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/deltae.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/deltae.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cc4809b39ca6c49d9fdd5b8c4ceb89a8f7b69fc GIT binary patch literal 4805 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/easings.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/easings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e121895874f4fecbc11931ee86a8f39af26b8c5 GIT binary patch literal 1133 zcmbW0U279T6ozLu*(8m&7qJ&Xp)BHs31l1ZBo?h&1wjf@P$XjJ_yT!}vF{Z8Y920jv75U% z06S#B!TZb(Ih3G`vj;v@a4ta=YB-l+?SQrFlbt=$mr9u6eXM1cn?S@yszK1tRbpkP zOwiAC&>ISS(mQ&ZrI`)~ItD3}JqiydkcTEFp~;&zvUOzD1t1BBKIpz7Hc{iP5YP1 af^LO&wNcv{W{{`iA-!wJhH|M^q30(PT>bq3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/tables.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/tables.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2e896ac8517c4a80fec120f1587bead456ec489 GIT binary patch literal 11104 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 G>%RfJ?=$EC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/__pycache__/types.cpython-37.pyc b/.venv/lib/python3.7/site-packages/colorzero/__pycache__/types.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..155bb19eb20734c00fd7d88b2b7a696ee5b6eff3 GIT binary patch literal 10732 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 LkIWv=s`T&w&$_~s literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/colorzero/attr.py b/.venv/lib/python3.7/site-packages/colorzero/attr.py new file mode 100644 index 0000000..bb8ed6a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/attr.py @@ -0,0 +1,191 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +Defines the classes for manipulating the attributes of the :class:`Color` +class through the standard binary operators. +""" + +from math import pi + + +class Red(float): + """ + Represents the red component of a :class:`Color` for use in + transformations. Instances of this class can be constructed directly with a + float value, or by querying the :attr:`Color.red` attribute. Addition, + subtraction, and multiplication are supported with :class:`Color` + instances. For example:: + + >>> Color.from_rgb(0, 0, 0) + Red(0.5) + + >>> Color('#f00') - Color('#900').red + + >>> (Red(0.1) * Color('red')).red + Red(0.1) + """ + + def __repr__(self): + return "Red({:g})".format(self) + + +class Green(float): + """ + Represents the green component of a :class:`Color` for use in + transformations. Instances of this class can be constructed directly with + a float value, or by querying the :attr:`Color.green` attribute. Addition, + subtraction, and multiplication are supported with :class:`Color` + instances. For example:: + + >>> Color(0, 0, 0) + Green(0.1) + + >>> Color.from_yuv(1, -0.4, -0.6) - Green(1) + + >>> (Green(0.5) * Color('white')).rgb + RGB(r=1.0, g=0.5, b=1.0) + """ + + def __repr__(self): + return "Green({:g})".format(self) + + +class Blue(float): + """ + Represents the blue component of a :class:`Color` for use in + transformations. Instances of this class can be constructed directly with + a float value, or by querying the :attr:`Color.blue` attribute. Addition, + subtraction, and multiplication are supported with :class:`Color` + instances. For example:: + + >>> Color(0, 0, 0) + Blue(0.2) + + >>> Color.from_hls(0.5, 0.5, 1.0) - Blue(1) + + >>> Blue(0.9) * Color('white') + + """ + + def __repr__(self): + return "Blue({:g})".format(self) + + +class Hue(float): + """ + Represents the hue of a :class:`Color` for use in transformations. + Instances of this class can be constructed directly with a float value in + the range [0.0, 1.0) representing an angle around the `HSL hue wheel`_. As + this is a circular mapping, 0.0 and 1.0 effectively mean the same thing, + i.e. out of range values will be normalized into the range [0.0, 1.0). + + The class can also be constructed with the keyword arguments ``deg`` or + ``rad`` if you wish to specify the hue value in degrees or radians instead, + respectively. Instances can also be constructed by querying the + :attr:`Color.hue` attribute. + + Addition, subtraction, and multiplication are supported with :class:`Color` + instances. For example:: + + >>> Color(1, 0, 0).hls + HLS(h=0.0, l=0.5, s=1.0) + >>> (Color(1, 0, 0) + Hue(deg=180)).hls + HLS(h=0.5, l=0.5, s=1.0) + + Note that whilst multiplication by a :class:`Hue` doesn't make much sense, + it is still supported. However, the circular nature of a hue value can lead + to suprising effects. In particular, since 1.0 is equivalent to 0.0 the + following may be observed:: + + >>> (Hue(1.0) * Color.from_hls(0.5, 0.5, 1.0)).hls + HLS(h=0.0, l=0.5, s=1.0) + + .. _HSL hue wheel: https://en.wikipedia.org/wiki/Hue + """ + + def __new__(cls, n=None, deg=None, rad=None): + if n is not None: + return super().__new__(cls, n % 1.0) + elif deg is not None: + return super().__new__(cls, (deg / 360.0) % 1.0) + elif rad is not None: + return super().__new__(cls, (rad / (2 * pi)) % 1.0) + else: + raise ValueError('You must specify a value, or deg or rad') + + def __repr__(self): + return "Hue(deg={self.deg:g})".format(self=self) + + @property + def deg(self): + """ + Returns the hue as a value in degrees with the range 0.0 <= n < 360.0. + """ + return self * 360.0 + + @property + def rad(self): + """ + Returns the hue as a value in radians with the range 0.0 <= n < 2Ï€. + """ + return self * 2 * pi + + +class Lightness(float): + """ + Represents the lightness of a :class:`Color` for use in transformations. + Instances of this class can be constructed directly with a float value, or + by querying the :attr:`Color.lightness` attribute. Addition, subtraction, + and multiplication are supported with :class:`Color` instances. For + example:: + + >>> Color(0, 0, 0) + Lightness(0.1) + + >>> Color.from_rgb_bytes(0x80, 0x80, 0) - Lightness(0.2) + + >>> Lightness(0.9) * Color('wheat') + + """ + + def __repr__(self): + return "Lightness({:g})".format(self) + + +class Saturation(float): + """ + Represents the saturation of a :class:`Color` for use in transformations. + Instances of this class can be constructed directly with a float value, or + by querying the :attr:`Color.saturation` attribute. Addition, subtraction, + and multiplication are supported with :class:`Color` instances. For + example:: + + >>> Color(0.9, 0.9, 0.6) + Saturation(0.1) + + >>> Color('red') - Saturation(1) + + >>> Saturation(0.5) * Color('wheat') + + """ + + def __repr__(self): + return "Saturation({:g})".format(self) + + +class Luma(float): + """ + Represents the luma of a :class:`Color` for use in transformations. + Instances of this class can be constructed directly with a float value, or + by querying the :attr:`Color.yuv.y` attribute. Addition, subtraction, and + multiplication are supported with :class:`Color` instances. For example:: + + >>> Color(0, 0, 0) + Luma(0.1) + + >>> Color('red') * Luma(0.5) + + """ + + def __repr__(self): + return "Luma({:g})".format(self) diff --git a/.venv/lib/python3.7/site-packages/colorzero/color.py b/.venv/lib/python3.7/site-packages/colorzero/color.py new file mode 100644 index 0000000..ebe2432 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/color.py @@ -0,0 +1,964 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +"Defines the main :class:`Color` class of the package." + +import re + +from . import conversions as cv, types, attr, deltae, tables, easings + +# Lots of the methods below use single character parameter names (r for red, y +# for luma, etc.); this is is normal and in keeping with most of the referenced +# sources +# pylint: disable=invalid-name + + +class Color(types.RGB): + """ + The Color class is a tuple which represents a color as linear red, green, + and blue components. + + The class has a flexible constructor which allows you to create an instance + from any built-in color system. There are also explicit constructors for + every known system that can convert (directly or indirectly) to linear RGB. + For example, an instance of :class:`Color` can be constructed in any of the + following ways:: + + >>> Color('#f00') + + >>> Color('green') + + >>> Color(0, 0, 1) + + >>> Color(h=0, s=1, v=0.5) + + >>> Color(y=0.4, u=-0.05, v=0.615) + + + The specific forms that the default constructor will accept are enumerated + below: + + .. tabularcolumns:: |p{60mm}|p{70mm}| + + +------------------------------+------------------------------------------+ + | Style | Description | + +==============================+==========================================+ + | Single scalar parameter | Equivalent to calling | + | | :meth:`Color.from_string`, or | + | | :meth:`Color.from_rgb24`. | + +------------------------------+------------------------------------------+ + | Three positional parameters | Equivalent to calling | + | or a 3-tuple with no field | :meth:`Color.from_rgb` if all three | + | names | parameters are between 0.0 and 1.0, or | + | | :meth:`Color.from_rgb_bytes` otherwise. | + +------------------------------+ | + | Three named parameters, or a | | + | 3-tuple with fields | | + | "r", "g", "b" | | + +------------------------------+ | + | Three named parameters, or a | | + | 3-tuple with fields | | + | "red", "green", "blue" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_yuv` if "y" is between | + | "y", "u", "v" | 0.0 and 1.0, "u" is between -0.436 and | + | | 0.436, and "v" is between -0.615 and | + | | 0.615, or :meth:`Color.from_yuv_bytes` | + | | otherwise. | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_yiq`. | + | "y", "i", "q" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_hls`. | + | "h", "l", "s" | | + +------------------------------+ | + | Three named parameters, or a | | + | 3-tuple with fields | | + | "hue", "lightness", | | + | "saturation" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_hsv` | + | "h", "s", "v" | | + +------------------------------+ | + | Three named parameters, or a | | + | 3-tuple with fields | | + | "hue", "saturation", "value" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_xyz` | + | "x", "y", "z" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_lab` | + | "l", "a", "b" | | + +------------------------------+------------------------------------------+ + | Three named parameters, or a | Equivalent to calling | + | 3-tuple with fields | :meth:`Color.from_luv` | + | "l", "u", "v" | | + +------------------------------+------------------------------------------+ + + If the constructor parameters do not conform to any of the variants in the + table above, a :exc:`ValueError` will be raised. + + Internally, the color is *always* represented as 3 :class:`float` values + corresponding to the red, green, and blue components of the color. These + values take a value from 0.0 to 1.0 (least to full intensity). The class + provides several attributes which can be used to convert one color system + into another:: + + >>> Color('#f00').hls + HLS(h=0.0, l=0.5, s=1.0) + >>> Color.from_string('green').hue + Hue(deg=120.0) + >>> Color.from_rgb_bytes(0, 0, 255).yuv + YUV(y=0.114, u=0.436, v=-0.10001426533523537) + + As :class:`Color` derives from tuple, instances are immutable. While this + provides the advantage that they can be used in a :class:`set` or as keys + of a :class:`dict`, it does mean that colors themselves cannot be + *directly* manipulated (e.g. by setting the red component). + + However, several auxilliary classes in the module provide the ability to + perform simple transformations of colors via operators which produce a new + :class:`Color` instance. For example, you can add, subtract, and multiply + colors directly:: + + >>> Color('red') + Color('blue') + + >>> Color('magenta') - Color('red') + + + Values are clipped to ensure the resulting color is still valid:: + + >>> Color('#ff00ff') + Color('#ff0000') + + + You can wrap numbers in constructors like :class:`Red` (or obtain elements + of existing colors), then add, subtract, or multiply them with a + :class:`Color`:: + + >>> Color('red') - Red(0.5) + + >>> Color('green') + Color('grey').red + + + You can even manipulate non-primary attributes like hue, saturation, and + lightness with standard addition, subtraction or multiplication operators:: + + >>> Color.from_hls(0.5, 0.5, 1.0) + + >>> Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8) + + >>> (Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8)).hls + HLS(h=0.5, l=0.4, s=1.0) + + In the last example above, a :class:`Color` instance is constructed from + HLS (hue, lightness, saturation) values with a lightness of 0.5. This is + multiplied by a :class:`Lightness` a value of 0.8 which constructs a new + :class:`Color` with the same hue and saturation, but a lightness of 0.4 + (0.8 Ă— 0.5). + + If an instance is converted to a string (with :func:`str`) it will return a + string containing the 7-character HTML code for the color (e.g. "#ff0000" + for red). As can be seen in the examples above, a similar representation is + included for the output of :func:`repr`. The output of :func:`repr` can + be customized by assigning values to :attr:`Color.repr_style`. + + .. _RGB: https://en.wikipedia.org/wiki/RGB_color_space + .. _Y'UV: https://en.wikipedia.org/wiki/YUV + .. _Y'IQ: https://en.wikipedia.org/wiki/YIQ + .. _HLS: https://en.wikipedia.org/wiki/HSL_and_HSV + .. _HSV: https://en.wikipedia.org/wiki/HSL_and_HSV + + .. attribute:: red + + Return the red value as a :class:`Red` instance + + .. attribute:: green + + Return the green value as a :class:`Green` instance + + .. attribute:: blue + + Return the blue value as a :class:`Blue` instance + + .. attribute:: repr_style + + Specifies the style of output returned when using :func:`repr` against + a :class:`Color` instance. This is an attribute of the class, not of + instances. For example:: + + >>> Color('#f00') + + >>> Color.repr_style = 'html' + >>> Color('#f00') + Color('#ff0000') + + The following values are valid: + + * 'default' - The style shown above + * 'term16m' - Similar to the default style, but instead of the HTML + style being included, a swatch previewing the color is output. Note + that the terminal must support `24-bit color ANSI codes`_ for this to + work. + * 'term256' - Similar to 'termtrue', but uses the closest color that + can be found in the standard 256-color xterm palette. Note that the + terminal must support `8-bit color ANSI codes`_ for this to work. + * 'html' - Outputs a valid :class:`Color` constructor using the HTML + style, e.g. ``Color('#ff99bb')`` + * 'rgb' - Outputs a valid :class:`Color` constructor using the floating + point RGB values, e.g. ``Color(1, 0.25, 0)`` + """ + # pylint: disable=too-many-public-methods + + __slots__ = () + + repr_style = 'default' + + def __new__(cls, *args, **kwargs): + def from_rgb(r, g, b): + "Determine whether bytes or floats are being passed for RGB" + if 0.0 <= r <= 1.0 and 0.0 <= g <= 1.0 and 0.0 <= b <= 1.0: + return cls.from_rgb(r, g, b) + else: + return cls.from_rgb_bytes(r, g, b) + + def from_yuv(y, u, v): + "Determine whether bytes or floats are being passed for YUV" + if ( + 0.0 <= y <= 1.0 and + abs(u) <= cv.BT601.Umax and + abs(v) <= cv.BT601.Vmax): + return cls.from_yuv(y, u, v) + else: + return cls.from_yuv_bytes(y, u, v) + + if kwargs: + try: + # Yes, lambdas are fine here + # pylint: disable=unnecessary-lambda + return { + frozenset('rgb'): from_rgb, + frozenset('yuv'): from_yuv, + frozenset('yiq'): cls.from_yiq, + frozenset('hls'): cls.from_hls, + frozenset('hsv'): cls.from_hsv, + frozenset('xyz'): cls.from_xyz, + frozenset('lab'): cls.from_lab, + frozenset('luv'): cls.from_luv, + frozenset('cmy'): cls.from_cmy, + frozenset('cmyk'): cls.from_cmyk, + frozenset(('red', 'green', 'blue')): + lambda red, green, blue: + from_rgb(red, green, blue), + frozenset(('cyan', 'magenta', 'yellow')): + lambda cyan, magenta, yellow: + cls.from_cmy(cyan, magenta, yellow), + frozenset(('cyan', 'magenta', 'yellow', 'black')): + lambda cyan, magenta, yellow, black: + cls.from_cmyk(cyan, magenta, yellow, black), + frozenset(('hue', 'lightness', 'saturation')): + lambda hue, lightness, saturation: + cls.from_hls(hue, lightness, saturation), + frozenset(('hue', 'saturation', 'value')): + lambda hue, saturation, value: + cls.from_hsv(hue, saturation, value), + }[frozenset(kwargs.keys())](**kwargs) + except KeyError: + pass + else: + if len(args) == 1: + if isinstance(args[0], bytes): + spec = args[0].decode('ascii') + else: + spec = args[0] + if isinstance(spec, str): + return cls.from_string(spec) + elif isinstance(spec, tuple): + try: + return cls(**spec._asdict()) + except AttributeError: + if len(spec) == 3: + return from_rgb(*spec) + elif isinstance(spec, int): + return cls.from_rgb24(spec) + elif len(args) == 3: + r, g, b = args + return from_rgb(r, g, b) + raise ValueError('Unable to construct Color from provided arguments') + + @classmethod + def from_string(cls, s): + """ + Construct a :class:`Color` from a 4 or 7 character CSS-like + representation (e.g. "#f00" or "#ff0000" for red), or from one of the + named colors (e.g. "green" or "wheat") from the `CSS standard`_. Any + other string format will result in a :exc:`ValueError`. + + .. _CSS standard: http://www.w3.org/TR/css3-color/#svg-color + """ + if s[:1] != '#': + s = cv.name_to_html(s) + return cls.from_rgb_bytes(*cv.html_to_rgb_bytes(s)) + + @classmethod + def from_rgb(cls, r, g, b): + """ + Construct a :class:`Color` from three linear `RGB`_ float values + between 0.0 and 1.0. + """ + return super().__new__(cls, + cv.clamp_float(r), + cv.clamp_float(g), + cv.clamp_float(b)) + + @classmethod + def from_rgb24(cls, n): + """ + Construct a :class:`Color` from an unsigned 24-bit integer number + of the form 0x00BBGGRR. + """ + return cls.from_rgb_bytes(*cv.rgb24_to_rgb_bytes(n)) + + @classmethod + def from_rgb565(cls, n): + """ + Construct a :class:`Color` from an unsigned 16-bit integer number + in RGB565 format. + """ + return cls.from_rgb(*cv.rgb565_to_rgb(n)) + + @classmethod + def from_rgb_bytes(cls, r, g, b): + """ + Construct a :class:`Color` from three `RGB`_ byte values between 0 and + 255. + + .. _RGB: https://en.wikipedia.org/wiki/RGB_color_space + """ + return cls.from_rgb(*cv.rgb_bytes_to_rgb(r, g, b)) + + @classmethod + def from_yuv(cls, y, u, v): + """ + Construct a :class:`Color` from three `Y'UV`_ float values. The Y value + may be between 0.0 and 1.0. U may be between -0.436 and 0.436, while + V may be between -0.615 and 0.615. + + .. _Y'UV: https://en.wikipedia.org/wiki/YUV + """ + return cls.from_rgb(*cv.yuv_to_rgb(y, u, v)) + + @classmethod + def from_yuv_bytes(cls, y, u, v): + """ + Construct a :class:`Color` from three `Y'UV`_ byte values between 0 and + 255. The U and V values are biased by 128 to prevent negative values as + is typical in video applications. The Y value is biased by 16 for the + same purpose. + + .. _Y'UV: https://en.wikipedia.org/wiki/YUV + """ + return cls.from_rgb_bytes(*cv.yuv_bytes_to_rgb_bytes(y, u, v)) + + @classmethod + def from_yiq(cls, y, i, q): + """ + Construct a :class:`Color` from three `Y'IQ`_ float values. Y' can be + between 0.0 and 1.0, while I and Q can be between -1.0 and 1.0. + + .. _Y'IQ: https://en.wikipedia.org/wiki/YIQ + """ + return cls.from_rgb(*cv.yiq_to_rgb(y, i, q)) + + @classmethod + def from_hls(cls, h, l, s): + """ + Construct a :class:`Color` from `HLS`_ (hue, lightness, saturation) + floats between 0.0 and 1.0. + + .. _HLS: https://en.wikipedia.org/wiki/HSL_and_HSV + """ + return cls.from_rgb(*cv.hls_to_rgb(h, l, s)) + + @classmethod + def from_hsv(cls, h, s, v): + """ + Construct a :class:`Color` from `HSV`_ (hue, saturation, value) floats + between 0.0 and 1.0. + + .. _HSV: https://en.wikipedia.org/wiki/HSL_and_HSV + """ + return cls.from_rgb(*cv.hsv_to_rgb(h, s, v)) + + @classmethod + def from_cmy(cls, c, m, y): + """ + Construct a :class:`Color` from `CMY`_ (cyan, magenta, yellow) floats + between 0.0 and 1.0. + + .. note:: + + This conversion uses the basic subtractive method which is not + accurate for color reproduction on print devices. See the `Color + FAQ`_ for more information. + + .. _Color FAQ: http://poynton.ca/notes/colour_and_gamma/ColorFAQ.html#RTFToC24 + .. _CMY: https://en.wikipedia.org/wiki/CMYK_color_model + """ + return cls.from_rgb(*cv.cmy_to_rgb(c, m, y)) + + @classmethod + def from_cmyk(cls, c, m, y, k): + """ + Construct a :class:`Color` from `CMYK`_ (cyan, magenta, yellow, black) + floats between 0.0 and 1.0. + + .. note:: + + This conversion uses the basic subtractive method which is not + accurate for color reproduction on print devices. See the `Color + FAQ`_ for more information. + + .. _Color FAQ: http://poynton.ca/notes/colour_and_gamma/ColorFAQ.html#RTFToC24 + .. _CMYK: https://en.wikipedia.org/wiki/CMYK_color_model + """ + return cls.from_cmy(*cv.cmyk_to_cmy(c, m, y, k)) + + @classmethod + def from_xyz(cls, x, y, z): + """ + Construct a :class:`Color` from (X, Y, Z) float values representing + a color in the `CIE 1931 color space`_. The conversion assumes the + sRGB working space with reference white D65. + + .. _CIE 1931 color space: https://en.wikipedia.org/wiki/CIE_1931_color_space + """ + return cls.from_rgb(*cv.xyz_to_rgb(x, y, z)) + + @classmethod + def from_lab(cls, l, a, b): + """ + Construct a :class:`Color` from (L*, a*, b*) float values representing + a color in the `CIE Lab color space`_. The conversion assumes the + sRGB working space with reference white D65. + + .. _CIE Lab color space: https://en.wikipedia.org/wiki/Lab_color_space + """ + return cls.from_xyz(*cv.lab_to_xyz(l, a, b)) + + @classmethod + def from_luv(cls, l, u, v): + """ + Construct a :class:`Color` from (L*, u*, v*) float values representing + a color in the `CIE Luv color space`_. The conversion assumes the sRGB + working space with reference white D65. + + .. _CIE Luv color space: https://en.wikipedia.org/wiki/CIELUV + """ + return cls.from_xyz(*cv.luv_to_xyz(l, u, v)) + + def __add__(self, other): + if isinstance(other, types.RGB): + return Color.from_rgb(self.r + other.r, + self.g + other.g, + self.b + other.b) + elif isinstance(other, (attr.Red, attr.Green, attr.Blue)): + r, g, b = self + return Color.from_rgb( + r + other if isinstance(other, attr.Red) else r, + g + other if isinstance(other, attr.Green) else g, + b + other if isinstance(other, attr.Blue) else b, + ) + elif isinstance(other, (attr.Hue, attr.Lightness, attr.Saturation)): + h, l, s = self.hls + return Color.from_hls( + h + other if isinstance(other, attr.Hue) else h, + l + other if isinstance(other, attr.Lightness) else l, + s + other if isinstance(other, attr.Saturation) else s, + ) + elif isinstance(other, attr.Luma): + y, u, v = self.yuv + return Color.from_yuv(y + other, u, v) + return NotImplemented + + def __radd__(self, other): + # Addition is commutative + if isinstance(other, (types.RGB, + attr.Red, attr.Green, attr.Blue, + attr.Hue, attr.Lightness, attr.Saturation, + attr.Luma)): + return self.__add__(other) + return NotImplemented + + def __sub__(self, other): + if isinstance(other, types.RGB): + return Color.from_rgb(self.r - other.r, + self.g - other.g, + self.b - other.b) + elif isinstance(other, (attr.Red, attr.Green, attr.Blue)): + r, g, b = self.rgb + return Color.from_rgb( + r - other if isinstance(other, attr.Red) else r, + g - other if isinstance(other, attr.Green) else g, + b - other if isinstance(other, attr.Blue) else b, + ) + elif isinstance(other, (attr.Hue, attr.Lightness, attr.Saturation)): + h, l, s = self.hls + return Color.from_hls( + h - other if isinstance(other, attr.Hue) else h, + l - other if isinstance(other, attr.Lightness) else l, + s - other if isinstance(other, attr.Saturation) else s, + ) + elif isinstance(other, attr.Luma): + y, u, v = self.yuv + return Color.from_yuv(y - other, u, v) + return NotImplemented + + def __rsub__(self, other): + if isinstance(other, (attr.Red, attr.Green, attr.Blue)): + r, g, b = self.rgb + return Color.from_rgb( + other - r if isinstance(other, attr.Red) else 0.0, + other - g if isinstance(other, attr.Green) else 0.0, + other - b if isinstance(other, attr.Blue) else 0.0, + ) + return NotImplemented + + def __mul__(self, other): + if isinstance(other, types.RGB): + return Color.from_rgb(self.r * other.r, + self.g * other.g, + self.b * other.b) + elif isinstance(other, (attr.Red, attr.Green, attr.Blue)): + r, g, b = self + return Color.from_rgb( + r * other if isinstance(other, attr.Red) else r, + g * other if isinstance(other, attr.Green) else g, + b * other if isinstance(other, attr.Blue) else b, + ) + elif isinstance(other, (attr.Hue, attr.Lightness, attr.Saturation)): + h, l, s = self.hls + return Color.from_hls( + h * other if isinstance(other, attr.Hue) else h, + l * other if isinstance(other, attr.Lightness) else l, + s * other if isinstance(other, attr.Saturation) else s, + ) + elif isinstance(other, attr.Luma): + y, u, v = self.yuv + return Color.from_yuv(y * other, u, v) + return NotImplemented + + def __rmul__(self, other): + # Multiplication is commutative + if isinstance(other, (types.RGB, + attr.Red, attr.Green, attr.Blue, + attr.Hue, attr.Lightness, attr.Saturation, + attr.Luma)): + return self.__mul__(other) + return NotImplemented + + _format_re = re.compile( + r'^(' + r'(?Phtml)|' + r'(?Pcss(?Prgb|hsl)?)|' + r'(?P[fb])?(?P0|8|256|16[mM])?' + r')$') + def __format__(self, format_spec): + m = Color._format_re.match(format_spec) + if not m: + raise ValueError( + 'Invalid format {:r} for Color'.format(format_spec)) + if m.group('html'): + return self.html + elif m.group('css'): + return self._format_css(m.group('cssfmt')) + else: + return self._format_term(m.group('back'), m.group('term')) + + def _format_css(self, cssfmt): + return { + None: lambda self: 'rgb({0:d}, {1:d}, {2:d})'.format( + *self.rgb_bytes), + 'rgb': lambda self: 'rgb({0:d}, {1:d}, {2:d})'.format( + *self.rgb_bytes), + 'hsl': lambda self: 'hsl({0:g}deg, {1:g}%, {2:g}%)'.format( + self.hls.hue.deg, self.hls.saturation * 100, + self.hls.lightness * 100), + }[cssfmt](self) + + def _format_term(self, back, term): + if term == '0': + args = ({ + None: 0, + 'f': 39, + 'b': 49, + }[back],) + elif term in (None, '8'): + table = tables.DOS_COLORS + if back == 'b': + code = 40 + table = { + k: (bold, index) + for k, (bold, index) in table.items() + if not bold + } + else: + code = 30 + try: + bold, index = table[self.rgb_bytes] + except KeyError: + bold, index = sorted( + (self.difference(Color.from_rgb_bytes(*color)), bold, index) + for color, (bold, index) in table.items() + )[0][1:] + args = (1,) if bold else () + args += (code + index,) + elif term == '256': + code = 48 if back == 'b' else 38 + try: + index = tables.XTERM_COLORS[self.rgb_bytes] + except KeyError: + index = sorted( + (self.difference(Color.from_rgb_bytes(*color)), index) + for color, index in tables.XTERM_COLORS.items() + )[0][1] + args = (48 if back == 'b' else 38, 5, index) + elif term.lower() == '16m': + args = (48 if back == 'b' else 38, 2) + self.rgb_bytes + else: + assert False # pragma: no cover + return '\x1b[' + ';'.join(str(i) for i in args) + 'm' + + def __str__(self): + return self.html + + def __repr__(self): + try: + return { + 'default': '', + 'term16m': '', + 'term256': '', + 'html': 'Color({self.html!r})', + 'rgb': 'Color({self.r:g}, {self.g:g}, {self.b:g})', + }[Color.repr_style].format(self=self) + except KeyError: + raise ValueError( + 'invalid repr_style value: {}'.format(Color.repr_style)) + + @property + def html(self): + """ + Returns the color as a string in HTML #RRGGBB format. + """ + return cv.rgb_bytes_to_html(*self.rgb_bytes) + + @property + def rgb(self): + """ + Return a simple 3-tuple of (r, g, b) float values in the range 0.0 <= n + <= 1.0. + + .. note:: + + The :class:`Color` class can already be treated as such a 3-tuple + but for the cases where you want a straight + :func:`~collections.namedtuple` this property is available. + """ + return types.RGB(*self) + + @property + def rgb565(self): + """ + Returns an unsigned 16-bit integer number representing the color in + the RGB565 encoding. + """ + return cv.rgb_to_rgb565(*self) + + @property + def rgb_bytes(self): + """ + Returns a 3-tuple of (red, green, blue) byte values. + """ + return cv.rgb_to_rgb_bytes(*self) + + @property + def yuv(self): + """ + Returns a 3-tuple of (y, u, v) float values; Y values can be between + 0.0 and 1.0, U values are between -0.436 and 0.436, and V values are + between -0.615 and 0.615. + """ + return cv.rgb_to_yuv(*self) + + @property + def yuv_bytes(self): + """ + Returns a 3-tuple of (y, u, v) byte values. Y values are biased by 16 + in the result to prevent negatives. U and V values are biased by 128 + for the same purpose. + """ + return cv.rgb_bytes_to_yuv_bytes(*self.rgb_bytes) + + @property + def yiq(self): + """ + Returns a 3-tuple of (y, i, q) float values; y values can be between + 0.0 and 1.0, whilst i and q values can be between -1.0 and 1.0. + """ + return cv.rgb_to_yiq(*self) + + @property + def xyz(self): + """ + Returns a 3-tuple of (X, Y, Z) float values representing the color in + the `CIE 1931 color space`_. The conversion assumes the sRGB working + space, with reference white D65. + + .. _CIE 1931 color space: https://en.wikipedia.org/wiki/CIE_1931_color_space + """ + return cv.rgb_to_xyz(*self) + + @property + def lab(self): + """ + Returns a 3-tuple of (L*, a*, b*) float values representing the color + in the `CIE Lab color space`_ with the `D65 standard illuminant`_. + + .. _CIE Lab color space: https://en.wikipedia.org/wiki/Lab_color_space + .. _D65 standard illuminant: https://en.wikipedia.org/wiki/Illuminant_D65 + """ + return cv.xyz_to_lab(*self.xyz) + + @property + def luv(self): + """ + Returns a 3-tuple of (L*, u*, v*) float values representing the color + in the `CIE Luv color space`_ with the `D65 standard illuminant`_. + + .. _CIE Luv color space: https://en.wikipedia.org/wiki/CIELUV + """ + return cv.xyz_to_luv(*self.xyz) + + @property + def hls(self): + """ + Returns a 3-tuple of (hue, lightness, saturation) float values (between + 0.0 and 1.0). + """ + return cv.rgb_to_hls(*self) + + @property + def hsv(self): + """ + Returns a 3-tuple of (hue, saturation, value) float values (between 0.0 + and 1.0). + """ + return cv.rgb_to_hsv(*self) + + @property + def cmy(self): + """ + Returns a 3-tuple of (cyan, magenta, yellow) float values (between 0.0 + and 1.0). + + .. note:: + + This conversion uses the basic subtractive method which is not + accurate for color reproduction on print devices. See the `Color + FAQ`_ for more information. + + .. _Color FAQ: http://poynton.ca/notes/colour_and_gamma/ColorFAQ.html#RTFToC24 + """ + return cv.rgb_to_cmy(*self) + + @property + def cmyk(self): + """ + Returns a 4-tuple of (cyan, magenta, yellow, black) float values + (between 0.0 and 1.0). + + .. note:: + + This conversion uses the basic subtractive method which is not + accurate for color reproduction on print devices. See the `Color + FAQ`_ for more information. + + .. _Color FAQ: http://poynton.ca/notes/colour_and_gamma/ColorFAQ.html#RTFToC24 + """ + return cv.cmy_to_cmyk(*self.cmy) + + @property + def hue(self): + """ + Returns the hue of the color as a :class:`Hue` instance which can be + used in operations with other :class:`Color` instances. + """ + return attr.Hue(self.hls[0]) + + @property + def lightness(self): + """ + Returns the lightness of the color as a :class:`Lightness` instance + which can be used in operations with other :class:`Color` instances. + """ + return attr.Lightness(self.hls[1]) + + @property + def saturation(self): + """ + Returns the saturation of the color as a :class:`Saturation` instance + which can be used in operations with other :class:`Color` instances. + """ + return attr.Saturation(self.hls[2]) + + @property + def luma(self): + """ + Returns the `luma`_ of the color as a :class:`Luma` instance which can + be used in operations with other :class:`Color` instances. + + .. _luma: https://en.wikipedia.org/wiki/Luma_(video) + """ + return attr.Luma(self.yuv[0]) + + def difference(self, other, method='euclid'): + """ + Determines the difference between this color and *other* using the + specified *method*. + + :param Color other: + The color to compare this color to. + + :param str method: + The algorithm to use in the comparison. Valid values are: + + * 'euclid' - This is the default method. Calculate the `Euclidian + distance`_. This is by far the fastest method, but also the least + accurate in terms of human perception. + * 'cie1976' - Use the `CIE 1976`_ formula for calculating the + difference between two colors in CIE Lab space. + * 'cie1994g' - Use the `CIE 1994`_ formula with the "graphic arts" + bias for calculating the difference. + * 'cie1994t' - Use the `CIE 1994`_ forumula with the "textiles" + bias for calculating the difference. + * 'ciede2000' - Use the `CIEDE 2000`_ formula for calculating the + difference. + + :returns: + A :class:`float` indicating how different the two colors are. Note + that the Euclidian distance will be significantly different to the + other calculations; effectively this just measures the distance + between the two colors by treating them as coordinates in a three + dimensional Euclidian space. All other methods are means of + calculating a `Delta E`_ value in which 2.3 is considered a + `just-noticeable difference`_ (JND). + + For example:: + + >>> Color('red').difference(Color('red')) + 0.0 + >>> Color('red').difference(Color('red'), method='cie1976') + 0.0 + >>> Color('red').difference(Color('#900')) + 0.4 + >>> Color('red').difference(Color('#900'), method='cie1976') + 40.17063087142142 + >>> Color('red').difference(Color('#900'), method='ciede2000') + 21.078146289272155 + >>> Color('red').difference(Color('blue')) + 1.4142135623730951 + >>> Color('red').difference(Color('blue'), method='cie1976') + 176.31403908880046 + + .. note:: + + Instead of using this method, you may wish to simply use the + various difference functions (:func:`euclid`, :func:`cie1976`, + etc.) directly. + + .. _Delta E: https://en.wikipedia.org/wiki/Color_difference + .. _just-noticeable difference: https://en.wikipedia.org/wiki/Just-noticeable_difference + .. _Euclidian distance: https://en.wikipedia.org/wiki/Euclidean_distance + .. _CIE 1976: https://en.wikipedia.org/wiki/Color_difference#CIE76 + .. _CIE 1994: https://en.wikipedia.org/wiki/Color_difference#CIE94 + .. _CIEDE 2000: https://en.wikipedia.org/wiki/Color_difference#CIEDE2000 + """ + if isinstance(method, bytes): + method = method.decode('ascii') + try: + fn = getattr(deltae, method) + except AttributeError: + raise ValueError('invalid method: {}'.format(method)) + else: + if method.startswith('cie'): + return fn(self.lab, other.lab) + else: + return fn(self, other) + + def gradient(self, other, steps=10, easing=easings.linear): + """ + Returns a generator which fades between this color and *other* in the + specified number of *steps*. + + :param Color other: + The color that will end the gradient (with the color the method is + called upon starting the gradient) + + :param int steps: + The unqiue number of colors to include in the generated gradient. + Defaults to 10 if unspecified. + + :param callable easing: + A function which controls the speed of the progression. If + specified, if must be a function which takes a single parameter, + the number of *steps*, and yields a sequence of values between 0.0 + (representing the start of the gradient) and 1.0 (representing the + end). The default is :func:`linear`. + + :return: + A generator yielding *steps* :class:`Color` instances which fade + from this color to *other*. + + For example:: + + >>> Color.repr_style = 'html' + >>> print('\\n'.join( + ... repr(c) for c in + ... Color('red').gradient(Color('green')) + ... )) + Color('#ff0000') + Color('#e30e00') + Color('#c61c00') + Color('#aa2b00') + Color('#8e3900') + Color('#714700') + Color('#555500') + Color('#396400') + Color('#1c7200') + Color('#008000') + + .. versionadded:: 1.1 + """ + if steps < 2: + raise ValueError('steps must be >= 2') + # NOTE: Can't simply subtract self from other here, as the result will + # be clamped and we want the actual result. + delta = types.RGB(*( + other_i - self_i + for self_i, other_i in zip(self, other) + )) + for t in easing(steps): + yield self + types.RGB(*(delta_i * t for delta_i in delta)) diff --git a/.venv/lib/python3.7/site-packages/colorzero/conversions.py b/.venv/lib/python3.7/site-packages/colorzero/conversions.py new file mode 100644 index 0000000..0aeacf1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/conversions.py @@ -0,0 +1,385 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +Defines all conversion functions used by colorzero to convert between the +various color systems implemented. References used in the development of these +routines are as follows: + +* `Charles Poynton's Color FAQ`_ +* `Bruce Lindbloom's Color Equations`_ +* `RGB color space`_ article from Wikipedia +* `SRGB`_ article from Wikipedia +* `YUV`_ article from Wikipedia +* `YIQ`_ article from Wikipedia +* `HSL and HSV`_ article from Wikipedia +* `CIE 1931 color space`_ article from Wikipedia + +.. _RGB color space: https://en.wikipedia.org/wiki/RGB_color_space +.. _SRGB: https://en.wikipedia.org/wiki/SRGB +.. _YUV: https://en.wikipedia.org/wiki/YUV +.. _YIQ: https://en.wikipedia.org/wiki/YIQ +.. _HSL and HSV: https://en.wikipedia.org/wiki/HSL_and_HSV +.. _CIE 1931 color space: https://en.wikipedia.org/wiki/CIE_1931_color_space +.. _Charles Poynton's Color FAQ: http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html +.. _Bruce Lindbloom's Color Equations: https://www.brucelindbloom.com/ +""" + +import colorsys +from collections import namedtuple +from fractions import Fraction + +from .tables import NAMED_COLORS +from .types import RGB, YIQ, YUV, CMY, CMYK, HLS, HSV, XYZ, Luv, Lab + +# Lots of the conversion functions use single character parameter names and +# variables internally; this is is normal and in keeping with most of the +# referenced sources +# pylint: disable=invalid-name + + +# Utility functions and constants ############################################ + +def clamp_float(v): + "Clamp *v* to the range 0.0 to 1.0 inclusive" + return max(0.0, min(1.0, v)) + + +def clamp_bytes(v): + "Clamp *v* to the range 0 to 255 inclusive" + return max(0, min(255, v)) + + +def to_srgb(c): + "Convert a linear RGB value (0..1) to the sRGB color space" + return 12.92 * c if c <= 0.0031308 else (1.055 * c ** (1 / 2.4) - 0.055) + + +def from_srgb(c): + "Convert an RGB value from the sRGB color space to linear RGB" + return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4 + + +def xyz_to_uv(x, y, z): + "Calculate the U, V values from an XYZ color" + d = x + 15 * y + 3 * z + return (0, 0) if d == 0 else (4 * x / d, 9 * y / d) + + +def matrix_mult(m, n): + "Generator function that multiplies matrices *m* and *n*" + return ( + sum(mval * nval for mval, nval in zip(mrow, n)) + for mrow in m + ) + + +class YUVCoefficients(namedtuple('YUVCoefficients', ( + 'Wr', 'Wg', 'Wb', + 'Umax', 'Vmax', 'U', 'V', + 'Rv', 'Gu', 'Gv', 'Bu'))): + "Represents coefficients for the BT.601 and BT.709 standards." + def __new__(cls, Umax=0.436, Vmax=0.615, **kwargs): + try: + Wr = kwargs['Wr'] + Wb = kwargs['Wb'] + except KeyError as e: + raise TypeError('YUVCoefficients() missing required keyword ' + 'argument: {e:s}'.format(e=e)) + Wg = (1 - Wr - Wb) + U = Umax / (1 - Wb) + V = Vmax / (1 - Wr) + Rv = (1 - Wr) / Vmax + Bu = (1 - Wb) / Umax + Gu = (Wb * (1 - Wb)) / (Umax * Wg) + Gv = (Wr * (1 - Wr)) / (Vmax * Wg) + return super(YUVCoefficients, cls).__new__(cls, + Wr, Wg, Wb, + Umax, Vmax, U, V, + Rv, Gu, Gv, Bu) + + +BT601 = YUVCoefficients(Wr=0.299, Wb=0.114) +BT709 = YUVCoefficients(Wr=0.2126, Wb=0.0722) +SMPTE240M = YUVCoefficients(Wr=0.212, Wb=0.087) +# TODO define some API to use these in Color + + +# The standard illuminants in the CIE XYZ space +D50 = XYZ(0.966797, 1.0, 0.825188) +D65 = XYZ(0.95047, 1.0, 1.08883) +# TODO define some more of these and figure out some API to use them in Color +# TODO what about standard observers? color temperature? + + +# Conversion functions ####################################################### + +def rgb_to_yiq(r, g, b): + "Convert a linear RGB color to YIQ" + # Coefficients from Python 3.4+ + y = 0.30 * r + 0.59 * g + 0.11 * b + i = 0.74 * (r - y) - 0.27 * (b - y) + q = 0.48 * (r - y) + 0.41 * (b - y) + return YIQ(y, i, q) + + +def yiq_to_rgb(y, i, q): + "Convert a YIQ color to linear RGB" + # Coefficients from Python 3.4+ + return RGB( + clamp_float(y + 0.9468822170900693 * i + 0.6235565819861433 * q), + clamp_float(y - 0.27478764629897834 * i - 0.6356910791873801 * q), + clamp_float(y - 1.1085450346420322 * i + 1.7090069284064666 * q), + ) + + +def rgb_to_hls(r, g, b): + "Convert a linear RGB color to HLS" + return HLS(*colorsys.rgb_to_hls(r, g, b)) + + +def hls_to_rgb(h, l, s): + "Convert an HLS color to linear RGB" + return RGB(*colorsys.hls_to_rgb(h, l, s)) + + +def rgb_to_hsv(r, g, b): + "Convert a linear RGB color to HSV" + return HSV(*colorsys.rgb_to_hsv(r, g, b)) + + +def hsv_to_rgb(h, s, v): + "Convert an HSV color to linear RGB" + return RGB(*colorsys.hsv_to_rgb(h, s, v)) + + +def rgb_to_rgb_bytes(r, g, b): + "Convert a linear RGB color to RGB888" + return RGB(int(round(r * 255)), int(round(g * 255)), int(round(b * 255))) + + +def rgb_bytes_to_rgb(r, g, b): + "Convert an RGB888 color to linear RGB" + return RGB(r / 255, g / 255, b / 255) + + +def rgb_bytes_to_html(r, g, b): + "Convert RGB888 to the HTML representation" + return '#{0:02x}{1:02x}{2:02x}'.format(r, g, b) + + +def rgb_bytes_to_rgb24(r, g, b): + "Convert RGB888 to RGB24" + return (b << 16) | (g << 8) | r + + +def rgb24_to_rgb_bytes(n): + "Convert RGB24 to RGB888" + return RGB(n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF) + + +def html_to_rgb_bytes(html): + "Convert the HTML color representation to RGB888" + if html.startswith('#'): + try: + if len(html) == 7: + return RGB( + int(html[1:3], base=16), + int(html[3:5], base=16), + int(html[5:7], base=16) + ) + elif len(html) == 4: + return RGB( + int(html[1:2], base=16) * 0x11, + int(html[2:3], base=16) * 0x11, + int(html[3:4], base=16) * 0x11 + ) + except ValueError: + pass + raise ValueError( + '{:s} is not a valid HTML color specification'.format(html)) + + +def name_to_html(name): + "Convert a named color to the HTML representation" + try: + return NAMED_COLORS[name] + except KeyError: + raise ValueError('invalid color name {:s}'.format(name)) + + +def rgb_to_rgb565(r, g, b): + "Convert linear RGB to RGB565" + return ( + (int(r * 0xF800) & 0xF800) | + (int(g * 0x07E0) & 0x07E0) | + (int(b * 0x001F) & 0x001F) + ) + + +def rgb565_to_rgb(rgb565): + "Convert RGB565 to linear RGB" + r = (rgb565 & 0xF800) / 0xF800 + g = (rgb565 & 0x07E0) / 0x07E0 + b = (rgb565 & 0x001F) / 0x001F + return RGB(r, g, b) + + +def rgb_to_yuv(r, g, b, std=BT601): + """ + Convert linear RGB to Y'CbCr using the specified coefficients (the default + coefficients are from BT.601) + """ + y = std.Wr * r + std.Wg * g + std.Wb * b + return YUV(y, std.U * (b - y), std.V * (r - y)) + + +def yuv_to_rgb(y, u, v, std=BT601): + """ + Convert Y'CbCr to linear RGB using the specified coefficients (the default + coefficients are from BT.601) + """ + return RGB( + clamp_float(y + std.Rv * v), + clamp_float(y - std.Gu * u - std.Gv * v), + clamp_float(y + std.Bu * u), + ) + + +def rgb_bytes_to_yuv_bytes(r, g, b): + "Convert RGB888 to YUV444 bytes using studio swing from BT.601" + # pylint: disable=bad-whitespace + return YUV( + (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16, + ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128, + ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128, + ) + + +def yuv_bytes_to_rgb_bytes(y, u, v): + "Convert YUV444 bytes to RGB888 using studio swing from BT.601" + c = y - 16 + d = u - 128 + e = v - 128 + return RGB( + clamp_bytes((298 * c + 409 * e + 128) >> 8), + clamp_bytes((298 * c - 100 * d - 208 * e + 128) >> 8), + clamp_bytes((298 * c + 516 * d + 128) >> 8), + ) + + +def rgb_to_cmy(r, g, b): + "Convert linear RGB to CMY using the subtractive method" + return CMY(1 - r, 1 - g, 1 - b) + + +def cmy_to_rgb(c, m, y): + "Convert CMY to linear RGB using the subtractive method" + return RGB(1 - c, 1 - m, 1 - y) + + +def cmy_to_cmyk(c, m, y): + "Calculate the black component of CMY to convert to CMYK" + k = min(c, m, y) + if k == 1.0: + return CMYK(0.0, 0.0, 0.0, 1.0) + else: + d = 1.0 - k + return CMYK((c - k) / d, (m - k) / d, (y - k) / d, k) + + +def cmyk_to_cmy(c, m, y, k): + "Remove the black component from CMYK to yield CMY" + n = 1 - k + return CMY(c * n + k, m * n + k, y * n + k) + + +def rgb_to_xyz(r, g, b): + """ + Convert linear RGB to CIE XYZ representation. RGB is assumed to be sRGB and + conversion uses D65 as reference white. + """ + return XYZ(*matrix_mult( + ((0.4124564, 0.3575761, 0.1804375), + (0.2126729, 0.7151522, 0.0721750), + (0.0193339, 0.1191920, 0.9503041)), + (from_srgb(r), from_srgb(g), from_srgb(b)) + )) + + +def xyz_to_rgb(x, y, z): + """ + Convert CIE XYZ representation to linear RGB. sRGB is used as the output + color space, and D65 as reference white. + """ + # pylint: disable=bad-whitespace + m = matrix_mult( + (( 3.2404542, -1.5371385, -0.4985314), + (-0.9692660, 1.8760108, 0.0415560), + ( 0.0556434, -0.2040259, 1.0572252)), + (x, y, z) + ) + return RGB(*(to_srgb(c) for c in m)) + + +def luv_to_xyz(l, u, v, white=D65): + "Convert CIE L*u*v* to CIE XYZ representation" + if l == 0: + return XYZ(0, 0, 0) + uw, vw = xyz_to_uv(*white) + u_prime = u / (13 * l) + uw + v_prime = v / (13 * l) + vw + y = white.y * ( + l * Fraction(3, 29) ** 3 if l <= 8 else + ((l + 16) / 116) ** 3 + ) + return XYZ( + y * (9 * u_prime) / (4 * v_prime), + y, + y * (12 - 3 * u_prime - 20 * v_prime) / (4 * v_prime), + ) + + +def xyz_to_luv(x, y, z, white=D65): + "Convert CIE XYZ to CIE L*u*v* representation" + uw, vw = xyz_to_uv(*white) + u, v = xyz_to_uv(x, y, z) + K = Fraction(29, 3) ** 3 + e = Fraction(6, 29) ** 3 + y_prime = y / white.y + L = 116 * y_prime ** Fraction(1, 3) - 16 if y_prime > e else K * y_prime + return Luv( + L, + 13 * L * (u - uw), + 13 * L * (v - vw), + ) + + +def lab_to_xyz(l, a, b, white=D65): + "Convert CIE L*a*b* to CIE XYZ representation" + theta = Fraction(6, 29) + fy = (l + 16) / 116 + fx = fy + a / 500 + fz = fy - b / 200 + xyz = ( + n ** 3 if n > theta else 3 * theta ** 2 * (n - Fraction(4, 29)) + for n in (fx, fy, fz) + ) + return XYZ(*(n * m for n, m in zip(xyz, white))) + + +def xyz_to_lab(x, y, z, white=D65): + "Convert CIE XYZ to CIE L*a*b* representation" + theta = Fraction(6, 29) + x, y, z = (n / m for n, m in zip((x, y, z), white)) + fx, fy, fz = ( + t ** Fraction(1, 3) if t > theta ** 3 else + t / (3 * theta ** 2) + Fraction(4, 29) + for t in (x, y, z) + ) + return Lab(116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)) diff --git a/.venv/lib/python3.7/site-packages/colorzero/deltae.py b/.venv/lib/python3.7/site-packages/colorzero/deltae.py new file mode 100644 index 0000000..e5e980a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/deltae.py @@ -0,0 +1,178 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2018 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +"Defines the various algorithms for :meth:`Color.difference`." + +from math import sqrt, atan2, degrees, radians, sin, cos, exp + +# Lots of the delta-e functions use single character parameter names and +# variables internally; this is is normal and in keeping with most of the +# referenced sources +# pylint: disable=invalid-name + + +def euclid(color1, color2): + """ + Calculates color difference as a simple `Euclidean distance`_ by treating + the three components as spatial dimensions. + + .. note:: + + This function will return considerably different values to the other + difference functions. In particular, the maximum "difference" will be + :math:`\\sqrt{3}` which is much smaller than the output of the CIE + functions. + + .. _Euclidean distance: https://en.wikipedia.org/wiki/Euclidean_distance + """ + return sqrt(sum((e1 - e2) ** 2 for e1, e2 in zip(color1, color2))) + + +def cie1976(color1, color2): + """ + Calculates color difference according to the `CIE 1976`_ formula. + Effectively this is the Euclidean formula, but with CIE L*a*b* components + instead of RGB. + + .. _CIE 1976: https://en.wikipedia.org/wiki/Color_difference#CIE76 + """ + return sqrt(sum((e1 - e2) ** 2 for e1, e2 in zip(color1, color2))) + + +def cie1994(color1, color2, method): + """ + Calculates color difference according to the `CIE 1994`_ formula. The + *method* can be either "cie1994g" for the "graphical" biases, or "cie1994t" + for the "textile" biases. The CIE1994 is also basically the Euclidean + formula (with biases) but in CIE L*C*H* space. + + .. _CIE 1994: https://en.wikipedia.org/wiki/Color_difference#CIE94 + """ + C1 = sqrt(color1.a ** 2 + color1.b ** 2) + C2 = sqrt(color2.a ** 2 + color2.b ** 2) + + dL = color1.l - color2.l + dC = C1 - C2 + # Don't bother with the sqrt here as due to limited float precision + # we can wind up with a domain error (because the value is ever so + # slightly negative - try it with black'n'white for an example), and we're + # just going to square the result in the final equation anyway + dH2 = (color1.a - color2.a) ** 2 + (color1.b - color2.b) ** 2 - dC ** 2 + + kL, K1, K2 = { + 'cie1994g': (1, 0.045, 0.015), + 'cie1994t': (2, 0.048, 0.014), + }[method] + SC = 1 + K1 * C1 + SH = 1 + K2 * C1 + return sqrt( + (dL / kL) ** 2 + + (dC / SC) ** 2 + + (dH2 / SH ** 2) + ) + + +def cie1994g(color1, color2): + """ + Calculates color difference according to the `CIE 1994`_ formula with the + "textile" bias. See :func:`cie1994` for further information. + + .. _CIE 1994: https://en.wikipedia.org/wiki/Color_difference#CIE94 + """ + return cie1994(color1, color2, 'cie1994g') + + +def cie1994t(color1, color2): + """ + Calculates color difference according to the `CIE 1994`_ formula with the + "graphics" bias. See :func:`cie1994` for further information. + + .. _CIE 1994: https://en.wikipedia.org/wiki/Color_difference#CIE94 + """ + return cie1994(color1, color2, 'cie1994t') + + +def ciede2000(color1, color2): + """ + Calculates color difference according to the `CIEDE 2000`_ formula. This is + the most accurate algorithm currently implemented but also the most complex + and slowest. Like CIE1994 it is largely based in CIE L*C*h* space, but with + several modifications to account for perceptual uniformity flaws. + + .. _CIEDE 2000: https://en.wikipedia.org/wiki/Color_difference#CIEDE2000 + """ + # See WP article and Sharma 2005 for important implementation notes: + # http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf + # + # Yes, there's lots of locals; but this is easiest to understand as it's a + # near straight translation of the math + # pylint: disable=too-many-locals + + C_ = ( + sqrt(color1.a ** 2 + color1.b ** 2) + + sqrt(color2.a ** 2 + color2.b ** 2) + ) / 2 + + G = (1 - sqrt(C_ ** 7 / (C_ ** 7 + 25 ** 7))) / 2 + a1_prime = (1 + G) * color1.a + a2_prime = (1 + G) * color2.a + + C1_prime = sqrt(a1_prime ** 2 + color1.b ** 2) + C2_prime = sqrt(a2_prime ** 2 + color2.b ** 2) + L_ = (color1.l + color2.l) / 2 + C_ = (C1_prime + C2_prime) / 2 + + h1 = ( + 0.0 if color1.b == a1_prime == 0 else + degrees(atan2(color1.b, a1_prime)) % 360 + ) + h2 = ( + 0.0 if color2.b == a2_prime == 0 else + degrees(atan2(color2.b, a2_prime)) % 360 + ) + if C1_prime * C2_prime == 0.0: + dh = 0.0 + h_ = h1 + h2 + elif abs(h1 - h2) <= 180: + dh = h2 - h1 + h_ = (h1 + h2) / 2 + else: + if h2 > h1: + dh = h2 - h1 - 360 + else: + dh = h2 - h1 + 360 + if h1 + h2 >= 360: + h_ = (h1 + h2 - 360) / 2 + else: + h_ = (h1 + h2 + 360) / 2 + + dL = color2.l - color1.l + dC = C2_prime - C1_prime + dH = 2 * sqrt(C1_prime * C2_prime) * sin(radians(dh / 2)) + + T = ( + 1 - + 0.17 * cos(radians(h_ - 30)) + + 0.24 * cos(radians(2 * h_)) + + 0.32 * cos(radians(3 * h_ + 6)) - + 0.20 * cos(radians(4 * h_ - 63)) + ) + SL = 1 + (0.015 * (L_ - 50) ** 2) / sqrt(20 + (L_ - 50) ** 2) + SC = 1 + 0.045 * C_ + SH = 1 + 0.015 * C_ * T + RT = ( + -2 * sqrt(C_ ** 7 / (C_ ** 7 + 25 ** 7)) * + sin(radians(60 * exp(-(((h_ - 275) / 25) ** 2)))) + ) + + return sqrt( + (dL / SL) ** 2 + + (dC / SC) ** 2 + + (dH / SH) ** 2 + + RT * (dC / SC) * (dH / SH) + ) diff --git a/.venv/lib/python3.7/site-packages/colorzero/easings.py b/.venv/lib/python3.7/site-packages/colorzero/easings.py new file mode 100644 index 0000000..efb5f68 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/easings.py @@ -0,0 +1,33 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2018 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +"Defines various easing functions for :meth:`Color.gradient`." + + +def linear(steps): + "Linear easing function; yields *steps* values between 0.0 and 1.0" + for t in range(steps): + yield t / (steps - 1) + + +def ease_in(steps): + "Quadratic ease-in function; yields *steps* values between 0.0 and 1.0" + for t in linear(steps): + yield t ** 2 + + +def ease_out(steps): + "Quadratic ease-out function; yields *steps* values between 0.0 and 1.0" + for t in linear(steps): + yield t * (2 - t) + + +def ease_in_out(steps): + "Quadratic ease-in-out function; yields *steps* values between 0.0 and 1.0" + for t in linear(steps): + yield 2 * t * t if t < 0.5 else (4 - 2 * t) * t - 1 diff --git a/.venv/lib/python3.7/site-packages/colorzero/tables.py b/.venv/lib/python3.7/site-packages/colorzero/tables.py new file mode 100644 index 0000000..1debcfe --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/tables.py @@ -0,0 +1,460 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2018 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +Defines the available color names, derived from the `CSS Color Module`_ Level 3 +Specification, section 4.3, along with tables for the original DOS colors, and +XTerm colors (for :func:`format` output). + +.. _CSS Color Module: http://www.w3.org/TR/css3-color/#svg-color +""" + +# I like my spacing, dammit! +# pylint: disable=bad-whitespace,bad-continuation + + +def _transpose(table): + # Swap keys and values in a dict, but in the case of duplicated keys, use + # the first encountered instead of the last + result = {} + for k, v in table.items(): + result.setdefault(v, k) + return result + + +DOS_COLORS = _transpose({ +# Bold, Index: (R, G, B), + (False, 0): (0, 0, 0), + (False, 1): (128, 0, 0), + (False, 2): (0, 128, 0), + (False, 3): (128, 128, 0), + (False, 4): (0, 0, 128), + (False, 5): (128, 0, 128), + (False, 6): (0, 128, 128), + (False, 7): (192, 192, 192), + (True, 0): (128, 128, 128), + (True, 1): (255, 0, 0), + (True, 2): (0, 255, 0), + (True, 3): (255, 255, 0), + (True, 4): (0, 0, 255), + (True, 5): (255, 0, 255), + (True, 6): (0, 255, 255), + (True, 7): (255, 255, 255), +}) + + +XTERM_COLORS = _transpose({ +# Index: (R, G, B) + 0: (0, 0, 0), + 1: (128, 0, 0), + 2: (0, 128, 0), + 3: (128, 128, 0), + 4: (0, 0, 128), + 5: (128, 0, 128), + 6: (0, 128, 128), + 7: (192, 192, 192), + 8: (128, 128, 128), + 9: (255, 0, 0), + 10: (0, 255, 0), + 11: (255, 255, 0), + 12: (0, 0, 255), + 13: (255, 0, 255), + 14: (0, 255, 255), + 15: (255, 255, 255), + 16: (0, 0, 0), + 17: (0, 0, 95), + 18: (0, 0, 135), + 19: (0, 0, 175), + 20: (0, 0, 215), + 21: (0, 0, 255), + 22: (0, 95, 0), + 23: (0, 95, 95), + 24: (0, 95, 135), + 25: (0, 95, 175), + 26: (0, 95, 215), + 27: (0, 95, 255), + 28: (0, 135, 0), + 29: (0, 135, 95), + 30: (0, 135, 135), + 31: (0, 135, 175), + 32: (0, 135, 215), + 33: (0, 135, 255), + 34: (0, 175, 0), + 35: (0, 175, 95), + 36: (0, 175, 135), + 37: (0, 175, 175), + 38: (0, 175, 215), + 39: (0, 175, 255), + 40: (0, 215, 0), + 41: (0, 215, 95), + 42: (0, 215, 135), + 43: (0, 215, 175), + 44: (0, 215, 215), + 45: (0, 215, 255), + 46: (0, 255, 0), + 47: (0, 255, 95), + 48: (0, 255, 135), + 49: (0, 255, 175), + 50: (0, 255, 215), + 51: (0, 255, 255), + 52: (95, 0, 0), + 53: (95, 0, 95), + 54: (95, 0, 135), + 55: (95, 0, 175), + 56: (95, 0, 215), + 57: (95, 0, 255), + 58: (95, 95, 0), + 59: (95, 95, 95), + 60: (95, 95, 135), + 61: (95, 95, 175), + 62: (95, 95, 215), + 63: (95, 95, 255), + 64: (95, 135, 0), + 65: (95, 135, 95), + 66: (95, 135, 135), + 67: (95, 135, 175), + 68: (95, 135, 215), + 69: (95, 135, 255), + 70: (95, 175, 0), + 71: (95, 175, 95), + 72: (95, 175, 135), + 73: (95, 175, 175), + 74: (95, 175, 215), + 75: (95, 175, 255), + 76: (95, 215, 0), + 77: (95, 215, 95), + 78: (95, 215, 135), + 79: (95, 215, 175), + 80: (95, 215, 215), + 81: (95, 215, 255), + 82: (95, 255, 0), + 83: (95, 255, 95), + 84: (95, 255, 135), + 85: (95, 255, 175), + 86: (95, 255, 215), + 87: (95, 255, 255), + 88: (135, 0, 0), + 89: (135, 0, 95), + 90: (135, 0, 135), + 91: (135, 0, 175), + 92: (135, 0, 215), + 93: (135, 0, 255), + 94: (135, 95, 0), + 95: (135, 95, 95), + 96: (135, 95, 135), + 97: (135, 95, 175), + 98: (135, 95, 215), + 99: (135, 95, 255), + 100: (135, 135, 0), + 101: (135, 135, 95), + 102: (135, 135, 135), + 103: (135, 135, 175), + 104: (135, 135, 215), + 105: (135, 135, 255), + 106: (135, 175, 0), + 107: (135, 175, 95), + 108: (135, 175, 135), + 109: (135, 175, 175), + 110: (135, 175, 215), + 111: (135, 175, 255), + 112: (135, 215, 0), + 113: (135, 215, 95), + 114: (135, 215, 135), + 115: (135, 215, 175), + 116: (135, 215, 215), + 117: (135, 215, 255), + 118: (135, 255, 0), + 119: (135, 255, 95), + 120: (135, 255, 135), + 121: (135, 255, 175), + 122: (135, 255, 215), + 123: (135, 255, 255), + 124: (175, 0, 0), + 125: (175, 0, 95), + 126: (175, 0, 135), + 127: (175, 0, 175), + 128: (175, 0, 215), + 129: (175, 0, 255), + 130: (175, 95, 0), + 131: (175, 95, 95), + 132: (175, 95, 135), + 133: (175, 95, 175), + 134: (175, 95, 215), + 135: (175, 95, 255), + 136: (175, 135, 0), + 137: (175, 135, 95), + 138: (175, 135, 135), + 139: (175, 135, 175), + 140: (175, 135, 215), + 141: (175, 135, 255), + 142: (175, 175, 0), + 143: (175, 175, 95), + 144: (175, 175, 135), + 145: (175, 175, 175), + 146: (175, 175, 215), + 147: (175, 175, 255), + 148: (175, 215, 0), + 149: (175, 215, 95), + 150: (175, 215, 135), + 151: (175, 215, 175), + 152: (175, 215, 215), + 153: (175, 215, 255), + 154: (175, 255, 0), + 155: (175, 255, 95), + 156: (175, 255, 135), + 157: (175, 255, 175), + 158: (175, 255, 215), + 159: (175, 255, 255), + 160: (215, 0, 0), + 161: (215, 0, 95), + 162: (215, 0, 135), + 163: (215, 0, 175), + 164: (215, 0, 215), + 165: (215, 0, 255), + 166: (215, 95, 0), + 167: (215, 95, 95), + 168: (215, 95, 135), + 169: (215, 95, 175), + 170: (215, 95, 215), + 171: (215, 95, 255), + 172: (215, 135, 0), + 173: (215, 135, 95), + 174: (215, 135, 135), + 175: (215, 135, 175), + 176: (215, 135, 215), + 177: (215, 135, 255), + 178: (215, 175, 0), + 179: (215, 175, 95), + 180: (215, 175, 135), + 181: (215, 175, 175), + 182: (215, 175, 215), + 183: (215, 175, 255), + 184: (215, 215, 0), + 185: (215, 215, 95), + 186: (215, 215, 135), + 187: (215, 215, 175), + 188: (215, 215, 215), + 189: (215, 215, 255), + 190: (215, 255, 0), + 191: (215, 255, 95), + 192: (215, 255, 135), + 193: (215, 255, 175), + 194: (215, 255, 215), + 195: (215, 255, 255), + 196: (255, 0, 0), + 197: (255, 0, 95), + 198: (255, 0, 135), + 199: (255, 0, 175), + 200: (255, 0, 215), + 201: (255, 0, 255), + 202: (255, 95, 0), + 203: (255, 95, 95), + 204: (255, 95, 135), + 205: (255, 95, 175), + 206: (255, 95, 215), + 207: (255, 95, 255), + 208: (255, 135, 0), + 209: (255, 135, 95), + 210: (255, 135, 135), + 211: (255, 135, 175), + 212: (255, 135, 215), + 213: (255, 135, 255), + 214: (255, 175, 0), + 215: (255, 175, 95), + 216: (255, 175, 135), + 217: (255, 175, 175), + 218: (255, 175, 215), + 219: (255, 175, 255), + 220: (255, 215, 0), + 221: (255, 215, 95), + 222: (255, 215, 135), + 223: (255, 215, 175), + 224: (255, 215, 215), + 225: (255, 215, 255), + 226: (255, 255, 0), + 227: (255, 255, 95), + 228: (255, 255, 135), + 229: (255, 255, 175), + 230: (255, 255, 215), + 231: (255, 255, 255), + 232: (8, 8, 8), + 233: (18, 18, 18), + 234: (28, 28, 28), + 235: (38, 38, 38), + 236: (48, 48, 48), + 237: (58, 58, 58), + 238: (68, 68, 68), + 239: (78, 78, 78), + 240: (88, 88, 88), + 241: (98, 98, 98), + 242: (108, 108, 108), + 243: (118, 118, 118), + 244: (128, 128, 128), + 245: (138, 138, 138), + 246: (148, 148, 148), + 247: (158, 158, 158), + 248: (168, 168, 168), + 249: (178, 178, 178), + 250: (188, 188, 188), + 251: (198, 198, 198), + 252: (208, 208, 208), + 253: (218, 218, 218), + 254: (228, 228, 228), + 255: (238, 238, 238), +}) + + +NAMED_COLORS = { + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgreen': '#006400', + 'darkgrey': '#a9a9a9', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'grey': '#808080', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightgrey': '#d3d3d3', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370db', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#db7093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32', +} diff --git a/.venv/lib/python3.7/site-packages/colorzero/types.py b/.venv/lib/python3.7/site-packages/colorzero/types.py new file mode 100644 index 0000000..0f57152 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/colorzero/types.py @@ -0,0 +1,322 @@ +# vim: set et sw=4 sts=4 fileencoding=utf-8: +# +# The colorzero color library +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +"Define the tuples used to represent various color systems." + +from collections import namedtuple, OrderedDict + +from .attr import Red, Green, Blue, Hue, Lightness, Saturation, Luma + + +class RGB(tuple): + "Named tuple representing red, green, and blue." + # NOTE: This source mostly generated by namedtuple(..., verbose=True) + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + __slots__ = () + + _fields = ('r', 'g', 'b') + + def __new__(cls, r, g, b): + return tuple.__new__(cls, (r, g, b)) + + def _replace(self, **kw): + "Return a new RGB object replacing specified fields with new values" + result = tuple.__new__(RGB, map(kw.pop, 'rgb', self)) + if kw: + raise ValueError( + 'Got unexpected field names: {!r}'.format(list(kw))) + return result + + def __repr__(self): + "Return a nicely formatted representation string" + return ( + self.__class__.__name__ + + '(r={self.r:g}, g={self.g:g}, b={self.b:g})'.format(self=self)) + + def _asdict(self): + "Return a new OrderedDict which maps field names to their values." + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + "Return self as a plain tuple. Used by copy and pickle." + return tuple(self) + + @property + def r(self): + "Return the red value as a :class:`Red` instance" + # pylint: disable=invalid-name + return Red(self[0]) + + @property + def red(self): + "Return the red value as a :class:`Red` instance" + return Red(self[0]) + + @property + def g(self): + "Return the green value as a :class:`Green` instance" + # pylint: disable=invalid-name + return Green(self[1]) + + @property + def green(self): + "Return the green value as a :class:`Green` instance" + return Green(self[1]) + + @property + def b(self): + "Return the blue value as a :class:`Blue` instance" + # pylint: disable=invalid-name + return Blue(self[2]) + + @property + def blue(self): + "Return the blue value as a :class:`Blue` instance" + return Blue(self[2]) + + +class HLS(tuple): + "Named tuple representing hue, lightness, and saturation." + # NOTE: This source mostly generated by namedtuple(..., verbose=True) + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + __slots__ = () + + _fields = ('h', 'l', 's') + + def __new__(cls, h, l, s): + return tuple.__new__(cls, (h, l, s)) + + def _replace(self, **kw): + "Return a new HLS object replacing specified fields with new values" + result = tuple.__new__(HLS, map(kw.pop, 'hls', self)) + if kw: + raise ValueError('Got unexpected field names: {!r}'.format(list(kw))) + return result + + def __repr__(self): + "Return a nicely formatted representation string" + return ( + self.__class__.__name__ + + '(h={self.h:g}, l={self.l:g}, s={self.s:g})'.format(self=self)) + + def _asdict(self): + "Return a new OrderedDict which maps field names to their values." + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + "Return self as a plain tuple. Used by copy and pickle." + return tuple(self) + + @property + def h(self): + "Return the hue value as a :class:`Hue` instance" + # pylint: disable=invalid-name + return Hue(self[0]) + + @property + def hue(self): + "Return the hue value as a :class:`Hue` instance" + return Hue(self[0]) + + @property + def l(self): + "Return the lightness value as a :class:`Lightness` instance" + # pylint: disable=invalid-name + return Lightness(self[1]) + + @property + def lightness(self): + "Return the lightness value as a :class:`Lightness` instance" + return Lightness(self[1]) + + @property + def s(self): + "Return the saturation value as a :class:`Saturation` instance" + # pylint: disable=invalid-name + return Saturation(self[2]) + + @property + def saturation(self): + "Return the saturation value as a :class:`Saturation` instance" + return Saturation(self[2]) + + +class HSV(tuple): + 'Named tuple representing hue, saturation, and value ("brightness").' + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + __slots__ = () + + _fields = ('h', 's', 'v') + + def __new__(cls, h, s, v): + return tuple.__new__(cls, (h, s, v)) + + def _replace(self, **kw): + "Return a new HSV object replacing specified fields with new values" + result = tuple.__new__(HSV, map(kw.pop, 'hsv', self)) + if kw: + raise ValueError( + 'Got unexpected field names: {!r}'.format(list(kw))) + return result + + def __repr__(self): + "Return a nicely formatted representation string" + return ( + self.__class__.__name__ + + '(h={self.h:g}, s={self.s:g}, v={self.v:g})'.format(self=self)) + + def _asdict(self): + "Return a new OrderedDict which maps field names to their values." + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + "Return self as a plain tuple. Used by copy and pickle." + return tuple(self) + + @property + def h(self): + "Return the hue value as a :class:`Hue` instance" + # pylint: disable=invalid-name + return Hue(self[0]) + + @property + def hue(self): + "Return the hue value as a :class:`Hue` instance" + return Hue(self[0]) + + @property + def s(self): + "Return the saturation value as a :class:`Saturation` instance" + # pylint: disable=invalid-name + return Saturation(self[1]) + + @property + def saturation(self): + "Return the saturation value as a :class:`Saturation` instance" + return Saturation(self[1]) + + @property + def v(self): + "Return the brightness value" + return self[2] + + @property + def value(self): + "Return the brightness value" + return self[2] + + +class YUV(tuple): + "Named tuple representing luma and two chroma offsets" + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + __slots__ = () + + _fields = ('y', 'u', 'v') + + def __new__(cls, y, u, v): + return tuple.__new__(cls, (y, u, v)) + + def _replace(self, **kw): + "Return a new YUV object replacing specified fields with new values" + result = tuple.__new__(YUV, map(kw.pop, 'yuv', self)) + if kw: + raise ValueError( + 'Got unexpected field names: {!r}'.format(list(kw))) + return result + + def __repr__(self): + "Return a nicely formatted representation string" + return ( + self.__class__.__name__ + + '(y={self.y:g}, u={self.u:g}, v={self.v:g})'.format(self=self)) + + def _asdict(self): + "Return a new OrderedDict which maps field names to their values." + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + "Return self as a plain tuple. Used by copy and pickle." + return tuple(self) + + @property + def y(self): + "Return the luma value as a :class:`Luma` instance" + # pylint: disable=invalid-name + return Luma(self[0]) + + @property + def luma(self): + "Return the luma value as a :class:`Luma` instance" + return Luma(self[0]) + + @property + def u(self): + "Return the first chroma offset" + # pylint: disable=invalid-name + return self[1] + + @property + def v(self): + "Return the second chroma offset" + # pylint: disable=invalid-name + return self[2] + + +class CMY(namedtuple('CMY', ('c', 'm', 'y'))): + "Named tuple representing cyan, magenta, and yellow." + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + @property + def cyan(self): + # pylint: disable=missing-docstring + return self.c + + @property + def magenta(self): + # pylint: disable=missing-docstring + return self.m + + @property + def yellow(self): + # pylint: disable=missing-docstring + return self.y + + +class CMYK(namedtuple('CMYK', ('c', 'm', 'y', 'k'))): + "Named tuple representing cyan, magenta, yellow, and black." + # XXX When py3.6+ required, replace with derivative of typing.NamedTuple + + @property + def cyan(self): + # pylint: disable=missing-docstring + return self.c + + @property + def magenta(self): + # pylint: disable=missing-docstring + return self.m + + @property + def yellow(self): + # pylint: disable=missing-docstring + return self.y + + @property + def black(self): + # pylint: disable=missing-docstring + return self.k + + +YIQ = namedtuple('YIQ', ('y', 'i', 'q')) +XYZ = namedtuple('XYZ', ('x', 'y', 'z')) +Luv = namedtuple('Luv', ('l', 'u', 'v')) +Lab = namedtuple('Lab', ('l', 'a', 'b')) diff --git a/.venv/lib/python3.7/site-packages/dateutil/__init__.py b/.venv/lib/python3.7/site-packages/dateutil/__init__.py new file mode 100644 index 0000000..0defb82 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +try: + from ._version import version as __version__ +except ImportError: + __version__ = 'unknown' + +__all__ = ['easter', 'parser', 'relativedelta', 'rrule', 'tz', + 'utils', 'zoneinfo'] diff --git a/.venv/lib/python3.7/site-packages/dateutil/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aeebd6dff9eea02fa6d052d80459f6afba90c615 GIT binary patch literal 350 zcmX|7u}%Xq3{BEr@3>PDBm4m!%KZSU5E26mO9vo}b;tpt=91u~MeP^CFJ)k1;uo06 zA4CHXXn^OHORLA1VCFI0nYq3Rp-6K TeBNRZ55qGBKjMeH7B&9?feK?y literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/__pycache__/_common.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/__pycache__/_common.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be4ae382ad498c8d6a68ceaf06d0c1915c11502c GIT binary patch literal 1374 zcmZuxO>fgc5Zzrnj^n1G5*2DeLP6pyLTxUb5Fkp`!i6A_Rz<$7QqPvSaqM*05lUoE z?GFKo1N zuYOf(0KG}h<4!$~x?&CBYXfmEL$ufZ!uf-R6rzJGU9Zh*HE4Ph`&X!MpGfiat zebr8fqxL8q?S!#Odr`D=q0A`^<+MGTr2Qn`fnKV{X&AK^feZ?Ac1M%kl`@RORLUA2 zX6Qu59X{Qdf!>{O2ZVwKc}gpgH!&dO=WHN!BSYL7`%Y_-@gG?Jyb`M@BCkmqL_K4q zEb71liHBmZD5f+Od`7qeEJn(8Tp0%q;~uxgb!2723Njb-3S=)Zm^2Al#u1%m?qbX_ z<^xOL2i|2TEZ($PDh8f@&Kdpa>1R|DvTt<`k6PA}?Yyyi+r#a-SYY8y*xDJh^H(;!cD6!1wBDUykhk<2r3iO@(AD1&~_ z^q0U|yyTEtvPvK2NqG;S&*&4}UTJKZutMKLlJo^;NZmlxOEDH_&l^U&|EW1vQa+&j z3azYEN?VIcX?s!WV_ZNXp>6h!JU5#eRtqR0TAhhIh@cRX)oE3I@!_K{j*fkCa)AE5 zFAhKXqPvIlcv^jAo<4d8t(7mQ6j{#AO~fcMtwvhPhlH7wLlSdth^$N@?mZG^+#6yk zxhG}$AA)gR%8PL?n(d&*O_ZdhaZ;_ObM+b-QnGH4q3&KoQ}m8hU$m9pGL+_WS9rGT oxGv68izI-ml#m2?ualgfs~|14ug`k0?FVNDSbftF^B^Lj6jA15Et_Ri4=w?h7`sq#uTPt22JKFRwF$NJtIx# zmrOvpmmEN%2&CLklj#K$hcn`##_1JQ-r}&y%}*)KNwou+ KRt$0j3nKtH=QI`o literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/__pycache__/easter.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/__pycache__/easter.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e78185f1be081903999b68f91fb4c8bc618183e GIT binary patch literal 2161 zcmZ`)Uvm>T5I^0W|HMfkEg=bkQVqic={Pnap;H*3xR63=AuUNu$1k>GDYo#P?$GJt zm^r_cKJl3nckgTyhUs~QY~rUcl*5pea*B+Lgyb(V<|v zO5+FwDlY_Ts4CslC>fkk5PcGRk}1l(ZlI;<`BAMh2A{2GX;EYr(#74z{=x3^){`H< z`=;?MJv&+MJwJH7_i*p$^vs0uVi(1pjR|OvZ6pqm4$kmffKh_+07mo@gg8lvYdKb* z=w)vANpxA+#4;9l-jH8NVvX#?=I)9$a(H3nCJ?~BrGMvc;w)RdxN7kd>=hD}Dz96s zR#E`o9Po-DTj|^SEuRNHn=kZT{WihbBFgbIYgRtT8S1WCBUk;F^G2lvemR$)O-f*E z33NU}soXZKrq;^|{P@S~c$WPC9Q>12Yuy69<-`G<^EhA2#s}V3!0Qrtli8bjUr36; zb62g=9N^CJ6_A?atFXV8`F~*rPBE%*8@TJhEg^R_Z^$3EaT5Ct0Xm=2${X^h1Icue z6(J)l6uvyC@>ChHh=zeS0t()~%iE8&x{d zdld)h8z^4cJqbOgmnt9_D}C z#y;~tAY39H2+x~FSVUqPCd#y+T7(*S3U3%v2vY)%5gDe;G>)IqcKf~N1M#^_x7zK@ z*;BjIUIe>0KHQx&Ce+=A-Awra%yDtVV$Vz)C-&OBF19CW@iYKG*@~J{!_Q z0j)MxoH8@H_V%P)Zclr2W7bsZot`n_?RtGM7}UBxltEMrbhj>{VoqvdFZ{9_+}+u_ zd9U5d{bP#flQw$#U=nxwb>oK_dIlLyFwL~~YP?_XU^&*|vg&yYM*}ltU4#a#%RpYA zkt$EW{M_SnxRbT-voIT9MuIQd82h$HGR7xQ-Uo;=$K?_d#2POmxq##nl24GFM>3D( zA`&z_zJ}yeB7HUpV~wN@Njzd z*<>25p~g20j~1b~*3}hKUT{g7z_6FdGEiJyamu7hu9K_o0=Yz%$VMqGwOTyrv|1WN rhbu4)D|`nv22vN0AbRHIDN+MoTE3G%_V-XM!Uxl}%k~0TgP-#sg5pK7 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/__pycache__/relativedelta.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/__pycache__/relativedelta.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d28b1895cfe80396707da5f8842b25949f0c536 GIT binary patch literal 15121 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 + + and + + `The Calendar FAQ: Easter `_ + + """ + + if not (1 <= method <= 3): + raise ValueError("invalid method") + + # g - Golden year - 1 + # c - Century + # h - (23 - Epact) mod 30 + # i - Number of days from March 21 to Paschal Full Moon + # j - Weekday for PFM (0=Sunday, etc) + # p - Number of days from March 21 to Sunday on or before PFM + # (-6 to 28 methods 1 & 3, to 56 for method 2) + # e - Extra days to add for method 2 (converting Julian + # date to Gregorian date) + + y = year + g = y % 19 + e = 0 + if method < 3: + # Old method + i = (19*g + 15) % 30 + j = (y + y//4 + i) % 7 + if method == 2: + # Extra dates to convert Julian to Gregorian date + e = 10 + if y > 1600: + e = e + y//100 - 16 - (y//100 - 16)//4 + else: + # New method + c = y//100 + h = (c - c//4 - (8*c + 13)//25 + 19*g + 15) % 30 + i = h - (h//28)*(1 - (h//28)*(29//(h + 1))*((21 - g)//11)) + j = (y + y//4 + i + 2 - c + c//4) % 7 + + # p can be from -6 to 56 corresponding to dates 22 March to 23 May + # (later dates apply to method 2, although 23 May never actually occurs) + p = i - j + e + d = 1 + (p + 27 + (p + 6)//40) % 31 + m = 3 + (p + 26)//30 + return datetime.date(int(y), int(m), int(d)) diff --git a/.venv/lib/python3.7/site-packages/dateutil/parser/__init__.py b/.venv/lib/python3.7/site-packages/dateutil/parser/__init__.py new file mode 100644 index 0000000..d174b0e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/parser/__init__.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +from ._parser import parse, parser, parserinfo, ParserError +from ._parser import DEFAULTPARSER, DEFAULTTZPARSER +from ._parser import UnknownTimezoneWarning + +from ._parser import __doc__ + +from .isoparser import isoparser, isoparse + +__all__ = ['parse', 'parser', 'parserinfo', + 'isoparse', 'isoparser', + 'ParserError', + 'UnknownTimezoneWarning'] + + +### +# Deprecate portions of the private interface so that downstream code that +# is improperly relying on it is given *some* notice. + + +def __deprecated_private_func(f): + from functools import wraps + import warnings + + msg = ('{name} is a private function and may break without warning, ' + 'it will be moved and or renamed in future versions.') + msg = msg.format(name=f.__name__) + + @wraps(f) + def deprecated_func(*args, **kwargs): + warnings.warn(msg, DeprecationWarning) + return f(*args, **kwargs) + + return deprecated_func + +def __deprecate_private_class(c): + import warnings + + msg = ('{name} is a private class and may break without warning, ' + 'it will be moved and or renamed in future versions.') + msg = msg.format(name=c.__name__) + + class private_class(c): + __doc__ = c.__doc__ + + def __init__(self, *args, **kwargs): + warnings.warn(msg, DeprecationWarning) + super(private_class, self).__init__(*args, **kwargs) + + private_class.__name__ = c.__name__ + + return private_class + + +from ._parser import _timelex, _resultbase +from ._parser import _tzparser, _parsetz + +_timelex = __deprecate_private_class(_timelex) +_tzparser = __deprecate_private_class(_tzparser) +_resultbase = __deprecate_private_class(_resultbase) +_parsetz = __deprecated_private_func(_parsetz) diff --git a/.venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..815c686efe3453df62583522c00db0d4b4e1e6be GIT binary patch literal 2055 zcmcIlOK%%D5GJ_~tz8N2!bSt+e={tv4aA<5NnZg*WQOhuIyTs zPc|U=(46`M+FSbv`eXK5pg{gYPo3e~a?;14hwfsBLvnWJ zf-dNRvmghqbibz;bVe8CjLylN&e_P3p7hUyGkVHq46;$%eh!WZ0QHV_G&a-xyDUo8 zX&9R@3dcG=iV78uCfTrv^DK-q8K%)mxTjTg7#_#PH~FLpkE_*w62_p%NfPdiQ$$I!@l=^TnTqM=_yiW0ZAe)Eq==KvrBZF-rVw!!7eWliCuK)o0#H(5uHHcG zxCp|Ubov=k;ClWtr`B$8C&`CVV(t!JFhB==udLgo=Xqju3moZJK$QL{*J)Igfe@H9 zpp~Q7aMqfvqlPKF8ohx7_@jOmM0x99fuN0Pf*`a>1Lm?eTle(q&|k6-S%{pp?7Ihw zWgNM1B(sbImK^~5ka1sA_Els zANZ!*5Ohg5&@J7tH6MadghMHD_5&0VcVHoG?#x|S2o&3Sz}-2Ra}VG<(@$T>r?}cz z3;cRxUm9K}6O*_k`8&{AIM*aEAU!j3#txhrov~+F+@vDBt2OvXwh6Dl48 z!(F42k?x_%DhN2^>OxpNLTKbd*?I|1MGYj3<%fO~v;lk-b%6=f&;RQR2TM4lhb9maR*aLzN_e)H2vD>Cj@EK-B!iY>)%V`<*j@dgH)wa6~^sa!1Vj*n?d#qIPnwp zZMh<}GLxj(i;TjvUKG=-vtC%Gm~Qu1;X0^B^OP8(P}uFf7Pjz%JJlZC#i%9(u}-_R$(pRoeCkq0{UGQBYhBu9 H0mb)Eix~id literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/_parser.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/parser/__pycache__/_parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21946ab461253cb85bcd46d0b9cfe72145a4d78c GIT binary patch literal 40369 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 +- `W3C Date and Time Formats `_ +- `Time Formats (Planetary Rings Node) `_ +- `CPAN ParseDate module + `_ +- `Java SimpleDateFormat Class + `_ +""" +from __future__ import unicode_literals + +import datetime +import re +import string +import time +import warnings + +from calendar import monthrange +from io import StringIO + +import six +from six import integer_types, text_type + +from decimal import Decimal + +from warnings import warn + +from .. import relativedelta +from .. import tz + +__all__ = ["parse", "parserinfo", "ParserError"] + + +# TODO: pandas.core.tools.datetimes imports this explicitly. Might be worth +# making public and/or figuring out if there is something we can +# take off their plate. +class _timelex(object): + # Fractional seconds are sometimes split by a comma + _split_decimal = re.compile("([.,])") + + def __init__(self, instream): + if isinstance(instream, (bytes, bytearray)): + instream = instream.decode() + + if isinstance(instream, text_type): + instream = StringIO(instream) + elif getattr(instream, 'read', None) is None: + raise TypeError('Parser must be a string or character stream, not ' + '{itype}'.format(itype=instream.__class__.__name__)) + + self.instream = instream + self.charstack = [] + self.tokenstack = [] + self.eof = False + + def get_token(self): + """ + This function breaks the time string into lexical units (tokens), which + can be parsed by the parser. Lexical units are demarcated by changes in + the character set, so any continuous string of letters is considered + one unit, any continuous string of numbers is considered one unit. + + The main complication arises from the fact that dots ('.') can be used + both as separators (e.g. "Sep.20.2009") or decimal points (e.g. + "4:30:21.447"). As such, it is necessary to read the full context of + any dot-separated strings before breaking it into tokens; as such, this + function maintains a "token stack", for when the ambiguous context + demands that multiple tokens be parsed at once. + """ + if self.tokenstack: + return self.tokenstack.pop(0) + + seenletters = False + token = None + state = None + + while not self.eof: + # We only realize that we've reached the end of a token when we + # find a character that's not part of the current token - since + # that character may be part of the next token, it's stored in the + # charstack. + if self.charstack: + nextchar = self.charstack.pop(0) + else: + nextchar = self.instream.read(1) + while nextchar == '\x00': + nextchar = self.instream.read(1) + + if not nextchar: + self.eof = True + break + elif not state: + # First character of the token - determines if we're starting + # to parse a word, a number or something else. + token = nextchar + if self.isword(nextchar): + state = 'a' + elif self.isnum(nextchar): + state = '0' + elif self.isspace(nextchar): + token = ' ' + break # emit token + else: + break # emit token + elif state == 'a': + # If we've already started reading a word, we keep reading + # letters until we find something that's not part of a word. + seenletters = True + if self.isword(nextchar): + token += nextchar + elif nextchar == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0': + # If we've already started reading a number, we keep reading + # numbers until we find something that doesn't fit. + if self.isnum(nextchar): + token += nextchar + elif nextchar == '.' or (nextchar == ',' and len(token) >= 2): + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == 'a.': + # If we've seen some letters and a dot separator, continue + # parsing, and the tokens will be broken up later. + seenletters = True + if nextchar == '.' or self.isword(nextchar): + token += nextchar + elif self.isnum(nextchar) and token[-1] == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0.': + # If we've seen at least one dot separator, keep going, we'll + # break up the tokens later. + if nextchar == '.' or self.isnum(nextchar): + token += nextchar + elif self.isword(nextchar) and token[-1] == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + + if (state in ('a.', '0.') and (seenletters or token.count('.') > 1 or + token[-1] in '.,')): + l = self._split_decimal.split(token) + token = l[0] + for tok in l[1:]: + if tok: + self.tokenstack.append(tok) + + if state == '0.' and token.count('.') == 0: + token = token.replace(',', '.') + + return token + + def __iter__(self): + return self + + def __next__(self): + token = self.get_token() + if token is None: + raise StopIteration + + return token + + def next(self): + return self.__next__() # Python 2.x support + + @classmethod + def split(cls, s): + return list(cls(s)) + + @classmethod + def isword(cls, nextchar): + """ Whether or not the next character is part of a word """ + return nextchar.isalpha() + + @classmethod + def isnum(cls, nextchar): + """ Whether the next character is part of a number """ + return nextchar.isdigit() + + @classmethod + def isspace(cls, nextchar): + """ Whether the next character is whitespace """ + return nextchar.isspace() + + +class _resultbase(object): + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def _repr(self, classname): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (classname, ", ".join(l)) + + def __len__(self): + return (sum(getattr(self, attr) is not None + for attr in self.__slots__)) + + def __repr__(self): + return self._repr(self.__class__.__name__) + + +class parserinfo(object): + """ + Class which handles what inputs are accepted. Subclass this to customize + the language and acceptable values for each parameter. + + :param dayfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the day (``True``) or month (``False``). If + ``yearfirst`` is set to ``True``, this distinguishes between YDM + and YMD. Default is ``False``. + + :param yearfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the year. If ``True``, the first number is taken + to be the year, otherwise the last number is taken to be the year. + Default is ``False``. + """ + + # m from a.m/p.m, t from ISO T separator + JUMP = [" ", ".", ",", ";", "-", "/", "'", + "at", "on", "and", "ad", "m", "t", "of", + "st", "nd", "rd", "th"] + + WEEKDAYS = [("Mon", "Monday"), + ("Tue", "Tuesday"), # TODO: "Tues" + ("Wed", "Wednesday"), + ("Thu", "Thursday"), # TODO: "Thurs" + ("Fri", "Friday"), + ("Sat", "Saturday"), + ("Sun", "Sunday")] + MONTHS = [("Jan", "January"), + ("Feb", "February"), # TODO: "Febr" + ("Mar", "March"), + ("Apr", "April"), + ("May", "May"), + ("Jun", "June"), + ("Jul", "July"), + ("Aug", "August"), + ("Sep", "Sept", "September"), + ("Oct", "October"), + ("Nov", "November"), + ("Dec", "December")] + HMS = [("h", "hour", "hours"), + ("m", "minute", "minutes"), + ("s", "second", "seconds")] + AMPM = [("am", "a"), + ("pm", "p")] + UTCZONE = ["UTC", "GMT", "Z", "z"] + PERTAIN = ["of"] + TZOFFSET = {} + # TODO: ERA = ["AD", "BC", "CE", "BCE", "Stardate", + # "Anno Domini", "Year of Our Lord"] + + def __init__(self, dayfirst=False, yearfirst=False): + self._jump = self._convert(self.JUMP) + self._weekdays = self._convert(self.WEEKDAYS) + self._months = self._convert(self.MONTHS) + self._hms = self._convert(self.HMS) + self._ampm = self._convert(self.AMPM) + self._utczone = self._convert(self.UTCZONE) + self._pertain = self._convert(self.PERTAIN) + + self.dayfirst = dayfirst + self.yearfirst = yearfirst + + self._year = time.localtime().tm_year + self._century = self._year // 100 * 100 + + def _convert(self, lst): + dct = {} + for i, v in enumerate(lst): + if isinstance(v, tuple): + for v in v: + dct[v.lower()] = i + else: + dct[v.lower()] = i + return dct + + def jump(self, name): + return name.lower() in self._jump + + def weekday(self, name): + try: + return self._weekdays[name.lower()] + except KeyError: + pass + return None + + def month(self, name): + try: + return self._months[name.lower()] + 1 + except KeyError: + pass + return None + + def hms(self, name): + try: + return self._hms[name.lower()] + except KeyError: + return None + + def ampm(self, name): + try: + return self._ampm[name.lower()] + except KeyError: + return None + + def pertain(self, name): + return name.lower() in self._pertain + + def utczone(self, name): + return name.lower() in self._utczone + + def tzoffset(self, name): + if name in self._utczone: + return 0 + + return self.TZOFFSET.get(name) + + def convertyear(self, year, century_specified=False): + """ + Converts two-digit years to year within [-50, 49] + range of self._year (current local time) + """ + + # Function contract is that the year is always positive + assert year >= 0 + + if year < 100 and not century_specified: + # assume current century to start + year += self._century + + if year >= self._year + 50: # if too far in future + year -= 100 + elif year < self._year - 50: # if too far in past + year += 100 + + return year + + def validate(self, res): + # move to info + if res.year is not None: + res.year = self.convertyear(res.year, res.century_specified) + + if ((res.tzoffset == 0 and not res.tzname) or + (res.tzname == 'Z' or res.tzname == 'z')): + res.tzname = "UTC" + res.tzoffset = 0 + elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): + res.tzoffset = 0 + return True + + +class _ymd(list): + def __init__(self, *args, **kwargs): + super(self.__class__, self).__init__(*args, **kwargs) + self.century_specified = False + self.dstridx = None + self.mstridx = None + self.ystridx = None + + @property + def has_year(self): + return self.ystridx is not None + + @property + def has_month(self): + return self.mstridx is not None + + @property + def has_day(self): + return self.dstridx is not None + + def could_be_day(self, value): + if self.has_day: + return False + elif not self.has_month: + return 1 <= value <= 31 + elif not self.has_year: + # Be permissive, assume leap year + month = self[self.mstridx] + return 1 <= value <= monthrange(2000, month)[1] + else: + month = self[self.mstridx] + year = self[self.ystridx] + return 1 <= value <= monthrange(year, month)[1] + + def append(self, val, label=None): + if hasattr(val, '__len__'): + if val.isdigit() and len(val) > 2: + self.century_specified = True + if label not in [None, 'Y']: # pragma: no cover + raise ValueError(label) + label = 'Y' + elif val > 100: + self.century_specified = True + if label not in [None, 'Y']: # pragma: no cover + raise ValueError(label) + label = 'Y' + + super(self.__class__, self).append(int(val)) + + if label == 'M': + if self.has_month: + raise ValueError('Month is already set') + self.mstridx = len(self) - 1 + elif label == 'D': + if self.has_day: + raise ValueError('Day is already set') + self.dstridx = len(self) - 1 + elif label == 'Y': + if self.has_year: + raise ValueError('Year is already set') + self.ystridx = len(self) - 1 + + def _resolve_from_stridxs(self, strids): + """ + Try to resolve the identities of year/month/day elements using + ystridx, mstridx, and dstridx, if enough of these are specified. + """ + if len(self) == 3 and len(strids) == 2: + # we can back out the remaining stridx value + missing = [x for x in range(3) if x not in strids.values()] + key = [x for x in ['y', 'm', 'd'] if x not in strids] + assert len(missing) == len(key) == 1 + key = key[0] + val = missing[0] + strids[key] = val + + assert len(self) == len(strids) # otherwise this should not be called + out = {key: self[strids[key]] for key in strids} + return (out.get('y'), out.get('m'), out.get('d')) + + def resolve_ymd(self, yearfirst, dayfirst): + len_ymd = len(self) + year, month, day = (None, None, None) + + strids = (('y', self.ystridx), + ('m', self.mstridx), + ('d', self.dstridx)) + + strids = {key: val for key, val in strids if val is not None} + if (len(self) == len(strids) > 0 or + (len(self) == 3 and len(strids) == 2)): + return self._resolve_from_stridxs(strids) + + mstridx = self.mstridx + + if len_ymd > 3: + raise ValueError("More than three YMD values") + elif len_ymd == 1 or (mstridx is not None and len_ymd == 2): + # One member, or two members with a month string + if mstridx is not None: + month = self[mstridx] + # since mstridx is 0 or 1, self[mstridx-1] always + # looks up the other element + other = self[mstridx - 1] + else: + other = self[0] + + if len_ymd > 1 or mstridx is None: + if other > 31: + year = other + else: + day = other + + elif len_ymd == 2: + # Two members with numbers + if self[0] > 31: + # 99-01 + year, month = self + elif self[1] > 31: + # 01-99 + month, year = self + elif dayfirst and self[1] <= 12: + # 13-01 + day, month = self + else: + # 01-13 + month, day = self + + elif len_ymd == 3: + # Three members + if mstridx == 0: + if self[1] > 31: + # Apr-2003-25 + month, year, day = self + else: + month, day, year = self + elif mstridx == 1: + if self[0] > 31 or (yearfirst and self[2] <= 31): + # 99-Jan-01 + year, month, day = self + else: + # 01-Jan-01 + # Give precedence to day-first, since + # two-digit years is usually hand-written. + day, month, year = self + + elif mstridx == 2: + # WTF!? + if self[1] > 31: + # 01-99-Jan + day, year, month = self + else: + # 99-01-Jan + year, day, month = self + + else: + if (self[0] > 31 or + self.ystridx == 0 or + (yearfirst and self[1] <= 12 and self[2] <= 31)): + # 99-01-01 + if dayfirst and self[2] <= 12: + year, day, month = self + else: + year, month, day = self + elif self[0] > 12 or (dayfirst and self[1] <= 12): + # 13-01-01 + day, month, year = self + else: + # 01-13-01 + month, day, year = self + + return year, month, day + + +class parser(object): + def __init__(self, info=None): + self.info = info or parserinfo() + + def parse(self, timestr, default=None, + ignoretz=False, tzinfos=None, **kwargs): + """ + Parse the date/time string into a :class:`datetime.datetime` object. + + :param timestr: + Any date/time string using the supported formats. + + :param default: + The default datetime object, if this is a datetime object and not + ``None``, elements specified in ``timestr`` replace elements in the + default object. + + :param ignoretz: + If set ``True``, time zones in parsed strings are ignored and a + naive :class:`datetime.datetime` object is returned. + + :param tzinfos: + Additional time zone names / aliases which may be present in the + string. This argument maps time zone names (and optionally offsets + from those time zones) to time zones. This parameter can be a + dictionary with timezone aliases mapping time zone names to time + zones or a function taking two parameters (``tzname`` and + ``tzoffset``) and returning a time zone. + + The timezones to which the names are mapped can be an integer + offset from UTC in seconds or a :class:`tzinfo` object. + + .. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> from dateutil.parser import parse + >>> from dateutil.tz import gettz + >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")} + >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos) + datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200)) + >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos) + datetime.datetime(2012, 1, 19, 17, 21, + tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago')) + + This parameter is ignored if ``ignoretz`` is set. + + :param \\*\\*kwargs: + Keyword arguments as passed to ``_parse()``. + + :return: + Returns a :class:`datetime.datetime` object or, if the + ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the + first element being a :class:`datetime.datetime` object, the second + a tuple containing the fuzzy tokens. + + :raises ParserError: + Raised for invalid or unknown string format, if the provided + :class:`tzinfo` is not in a valid format, or if an invalid date + would be created. + + :raises TypeError: + Raised for non-string or character stream input. + + :raises OverflowError: + Raised if the parsed date exceeds the largest valid C integer on + your system. + """ + + if default is None: + default = datetime.datetime.now().replace(hour=0, minute=0, + second=0, microsecond=0) + + res, skipped_tokens = self._parse(timestr, **kwargs) + + if res is None: + raise ParserError("Unknown string format: %s", timestr) + + if len(res) == 0: + raise ParserError("String does not contain a date: %s", timestr) + + try: + ret = self._build_naive(res, default) + except ValueError as e: + six.raise_from(ParserError(str(e) + ": %s", timestr), e) + + if not ignoretz: + ret = self._build_tzaware(ret, res, tzinfos) + + if kwargs.get('fuzzy_with_tokens', False): + return ret, skipped_tokens + else: + return ret + + class _result(_resultbase): + __slots__ = ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond", + "tzname", "tzoffset", "ampm","any_unused_tokens"] + + def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False, + fuzzy_with_tokens=False): + """ + Private method which performs the heavy lifting of parsing, called from + ``parse()``, which passes on its ``kwargs`` to this function. + + :param timestr: + The string to parse. + + :param dayfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the day (``True``) or month (``False``). If + ``yearfirst`` is set to ``True``, this distinguishes between YDM + and YMD. If set to ``None``, this value is retrieved from the + current :class:`parserinfo` object (which itself defaults to + ``False``). + + :param yearfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the year. If ``True``, the first number is taken + to be the year, otherwise the last number is taken to be the year. + If this is set to ``None``, the value is retrieved from the current + :class:`parserinfo` object (which itself defaults to ``False``). + + :param fuzzy: + Whether to allow fuzzy parsing, allowing for string like "Today is + January 1, 2047 at 8:21:00AM". + + :param fuzzy_with_tokens: + If ``True``, ``fuzzy`` is automatically set to True, and the parser + will return a tuple where the first element is the parsed + :class:`datetime.datetime` datetimestamp and the second element is + a tuple containing the portions of the string which were ignored: + + .. doctest:: + + >>> from dateutil.parser import parse + >>> parse("Today is January 1, 2047 at 8:21:00AM", fuzzy_with_tokens=True) + (datetime.datetime(2047, 1, 1, 8, 21), (u'Today is ', u' ', u'at ')) + + """ + if fuzzy_with_tokens: + fuzzy = True + + info = self.info + + if dayfirst is None: + dayfirst = info.dayfirst + + if yearfirst is None: + yearfirst = info.yearfirst + + res = self._result() + l = _timelex.split(timestr) # Splits the timestr into tokens + + skipped_idxs = [] + + # year/month/day list + ymd = _ymd() + + len_l = len(l) + i = 0 + try: + while i < len_l: + + # Check if it's a number + value_repr = l[i] + try: + value = float(value_repr) + except ValueError: + value = None + + if value is not None: + # Numeric token + i = self._parse_numeric_token(l, i, info, ymd, res, fuzzy) + + # Check weekday + elif info.weekday(l[i]) is not None: + value = info.weekday(l[i]) + res.weekday = value + + # Check month name + elif info.month(l[i]) is not None: + value = info.month(l[i]) + ymd.append(value, 'M') + + if i + 1 < len_l: + if l[i + 1] in ('-', '/'): + # Jan-01[-99] + sep = l[i + 1] + ymd.append(l[i + 2]) + + if i + 3 < len_l and l[i + 3] == sep: + # Jan-01-99 + ymd.append(l[i + 4]) + i += 2 + + i += 2 + + elif (i + 4 < len_l and l[i + 1] == l[i + 3] == ' ' and + info.pertain(l[i + 2])): + # Jan of 01 + # In this case, 01 is clearly year + if l[i + 4].isdigit(): + # Convert it here to become unambiguous + value = int(l[i + 4]) + year = str(info.convertyear(value)) + ymd.append(year, 'Y') + else: + # Wrong guess + pass + # TODO: not hit in tests + i += 4 + + # Check am/pm + elif info.ampm(l[i]) is not None: + value = info.ampm(l[i]) + val_is_ampm = self._ampm_valid(res.hour, res.ampm, fuzzy) + + if val_is_ampm: + res.hour = self._adjust_ampm(res.hour, value) + res.ampm = value + + elif fuzzy: + skipped_idxs.append(i) + + # Check for a timezone name + elif self._could_be_tzname(res.hour, res.tzname, res.tzoffset, l[i]): + res.tzname = l[i] + res.tzoffset = info.tzoffset(res.tzname) + + # Check for something like GMT+3, or BRST+3. Notice + # that it doesn't mean "I am 3 hours after GMT", but + # "my time +3 is GMT". If found, we reverse the + # logic so that timezone parsing code will get it + # right. + if i + 1 < len_l and l[i + 1] in ('+', '-'): + l[i + 1] = ('+', '-')[l[i + 1] == '+'] + res.tzoffset = None + if info.utczone(res.tzname): + # With something like GMT+3, the timezone + # is *not* GMT. + res.tzname = None + + # Check for a numbered timezone + elif res.hour is not None and l[i] in ('+', '-'): + signal = (-1, 1)[l[i] == '+'] + len_li = len(l[i + 1]) + + # TODO: check that l[i + 1] is integer? + if len_li == 4: + # -0300 + hour_offset = int(l[i + 1][:2]) + min_offset = int(l[i + 1][2:]) + elif i + 2 < len_l and l[i + 2] == ':': + # -03:00 + hour_offset = int(l[i + 1]) + min_offset = int(l[i + 3]) # TODO: Check that l[i+3] is minute-like? + i += 2 + elif len_li <= 2: + # -[0]3 + hour_offset = int(l[i + 1][:2]) + min_offset = 0 + else: + raise ValueError(timestr) + + res.tzoffset = signal * (hour_offset * 3600 + min_offset * 60) + + # Look for a timezone name between parenthesis + if (i + 5 < len_l and + info.jump(l[i + 2]) and l[i + 3] == '(' and + l[i + 5] == ')' and + 3 <= len(l[i + 4]) and + self._could_be_tzname(res.hour, res.tzname, + None, l[i + 4])): + # -0300 (BRST) + res.tzname = l[i + 4] + i += 4 + + i += 1 + + # Check jumps + elif not (info.jump(l[i]) or fuzzy): + raise ValueError(timestr) + + else: + skipped_idxs.append(i) + i += 1 + + # Process year/month/day + year, month, day = ymd.resolve_ymd(yearfirst, dayfirst) + + res.century_specified = ymd.century_specified + res.year = year + res.month = month + res.day = day + + except (IndexError, ValueError): + return None, None + + if not info.validate(res): + return None, None + + if fuzzy_with_tokens: + skipped_tokens = self._recombine_skipped(l, skipped_idxs) + return res, tuple(skipped_tokens) + else: + return res, None + + def _parse_numeric_token(self, tokens, idx, info, ymd, res, fuzzy): + # Token is a number + value_repr = tokens[idx] + try: + value = self._to_decimal(value_repr) + except Exception as e: + six.raise_from(ValueError('Unknown numeric token'), e) + + len_li = len(value_repr) + + len_l = len(tokens) + + if (len(ymd) == 3 and len_li in (2, 4) and + res.hour is None and + (idx + 1 >= len_l or + (tokens[idx + 1] != ':' and + info.hms(tokens[idx + 1]) is None))): + # 19990101T23[59] + s = tokens[idx] + res.hour = int(s[:2]) + + if len_li == 4: + res.minute = int(s[2:]) + + elif len_li == 6 or (len_li > 6 and tokens[idx].find('.') == 6): + # YYMMDD or HHMMSS[.ss] + s = tokens[idx] + + if not ymd and '.' not in tokens[idx]: + ymd.append(s[:2]) + ymd.append(s[2:4]) + ymd.append(s[4:]) + else: + # 19990101T235959[.59] + + # TODO: Check if res attributes already set. + res.hour = int(s[:2]) + res.minute = int(s[2:4]) + res.second, res.microsecond = self._parsems(s[4:]) + + elif len_li in (8, 12, 14): + # YYYYMMDD + s = tokens[idx] + ymd.append(s[:4], 'Y') + ymd.append(s[4:6]) + ymd.append(s[6:8]) + + if len_li > 8: + res.hour = int(s[8:10]) + res.minute = int(s[10:12]) + + if len_li > 12: + res.second = int(s[12:]) + + elif self._find_hms_idx(idx, tokens, info, allow_jump=True) is not None: + # HH[ ]h or MM[ ]m or SS[.ss][ ]s + hms_idx = self._find_hms_idx(idx, tokens, info, allow_jump=True) + (idx, hms) = self._parse_hms(idx, tokens, info, hms_idx) + if hms is not None: + # TODO: checking that hour/minute/second are not + # already set? + self._assign_hms(res, value_repr, hms) + + elif idx + 2 < len_l and tokens[idx + 1] == ':': + # HH:MM[:SS[.ss]] + res.hour = int(value) + value = self._to_decimal(tokens[idx + 2]) # TODO: try/except for this? + (res.minute, res.second) = self._parse_min_sec(value) + + if idx + 4 < len_l and tokens[idx + 3] == ':': + res.second, res.microsecond = self._parsems(tokens[idx + 4]) + + idx += 2 + + idx += 2 + + elif idx + 1 < len_l and tokens[idx + 1] in ('-', '/', '.'): + sep = tokens[idx + 1] + ymd.append(value_repr) + + if idx + 2 < len_l and not info.jump(tokens[idx + 2]): + if tokens[idx + 2].isdigit(): + # 01-01[-01] + ymd.append(tokens[idx + 2]) + else: + # 01-Jan[-01] + value = info.month(tokens[idx + 2]) + + if value is not None: + ymd.append(value, 'M') + else: + raise ValueError() + + if idx + 3 < len_l and tokens[idx + 3] == sep: + # We have three members + value = info.month(tokens[idx + 4]) + + if value is not None: + ymd.append(value, 'M') + else: + ymd.append(tokens[idx + 4]) + idx += 2 + + idx += 1 + idx += 1 + + elif idx + 1 >= len_l or info.jump(tokens[idx + 1]): + if idx + 2 < len_l and info.ampm(tokens[idx + 2]) is not None: + # 12 am + hour = int(value) + res.hour = self._adjust_ampm(hour, info.ampm(tokens[idx + 2])) + idx += 1 + else: + # Year, month or day + ymd.append(value) + idx += 1 + + elif info.ampm(tokens[idx + 1]) is not None and (0 <= value < 24): + # 12am + hour = int(value) + res.hour = self._adjust_ampm(hour, info.ampm(tokens[idx + 1])) + idx += 1 + + elif ymd.could_be_day(value): + ymd.append(value) + + elif not fuzzy: + raise ValueError() + + return idx + + def _find_hms_idx(self, idx, tokens, info, allow_jump): + len_l = len(tokens) + + if idx+1 < len_l and info.hms(tokens[idx+1]) is not None: + # There is an "h", "m", or "s" label following this token. We take + # assign the upcoming label to the current token. + # e.g. the "12" in 12h" + hms_idx = idx + 1 + + elif (allow_jump and idx+2 < len_l and tokens[idx+1] == ' ' and + info.hms(tokens[idx+2]) is not None): + # There is a space and then an "h", "m", or "s" label. + # e.g. the "12" in "12 h" + hms_idx = idx + 2 + + elif idx > 0 and info.hms(tokens[idx-1]) is not None: + # There is a "h", "m", or "s" preceding this token. Since neither + # of the previous cases was hit, there is no label following this + # token, so we use the previous label. + # e.g. the "04" in "12h04" + hms_idx = idx-1 + + elif (1 < idx == len_l-1 and tokens[idx-1] == ' ' and + info.hms(tokens[idx-2]) is not None): + # If we are looking at the final token, we allow for a + # backward-looking check to skip over a space. + # TODO: Are we sure this is the right condition here? + hms_idx = idx - 2 + + else: + hms_idx = None + + return hms_idx + + def _assign_hms(self, res, value_repr, hms): + # See GH issue #427, fixing float rounding + value = self._to_decimal(value_repr) + + if hms == 0: + # Hour + res.hour = int(value) + if value % 1: + res.minute = int(60*(value % 1)) + + elif hms == 1: + (res.minute, res.second) = self._parse_min_sec(value) + + elif hms == 2: + (res.second, res.microsecond) = self._parsems(value_repr) + + def _could_be_tzname(self, hour, tzname, tzoffset, token): + return (hour is not None and + tzname is None and + tzoffset is None and + len(token) <= 5 and + (all(x in string.ascii_uppercase for x in token) + or token in self.info.UTCZONE)) + + def _ampm_valid(self, hour, ampm, fuzzy): + """ + For fuzzy parsing, 'a' or 'am' (both valid English words) + may erroneously trigger the AM/PM flag. Deal with that + here. + """ + val_is_ampm = True + + # If there's already an AM/PM flag, this one isn't one. + if fuzzy and ampm is not None: + val_is_ampm = False + + # If AM/PM is found and hour is not, raise a ValueError + if hour is None: + if fuzzy: + val_is_ampm = False + else: + raise ValueError('No hour specified with AM or PM flag.') + elif not 0 <= hour <= 12: + # If AM/PM is found, it's a 12 hour clock, so raise + # an error for invalid range + if fuzzy: + val_is_ampm = False + else: + raise ValueError('Invalid hour specified for 12-hour clock.') + + return val_is_ampm + + def _adjust_ampm(self, hour, ampm): + if hour < 12 and ampm == 1: + hour += 12 + elif hour == 12 and ampm == 0: + hour = 0 + return hour + + def _parse_min_sec(self, value): + # TODO: Every usage of this function sets res.second to the return + # value. Are there any cases where second will be returned as None and + # we *don't* want to set res.second = None? + minute = int(value) + second = None + + sec_remainder = value % 1 + if sec_remainder: + second = int(60 * sec_remainder) + return (minute, second) + + def _parse_hms(self, idx, tokens, info, hms_idx): + # TODO: Is this going to admit a lot of false-positives for when we + # just happen to have digits and "h", "m" or "s" characters in non-date + # text? I guess hex hashes won't have that problem, but there's plenty + # of random junk out there. + if hms_idx is None: + hms = None + new_idx = idx + elif hms_idx > idx: + hms = info.hms(tokens[hms_idx]) + new_idx = hms_idx + else: + # Looking backwards, increment one. + hms = info.hms(tokens[hms_idx]) + 1 + new_idx = idx + + return (new_idx, hms) + + # ------------------------------------------------------------------ + # Handling for individual tokens. These are kept as methods instead + # of functions for the sake of customizability via subclassing. + + def _parsems(self, value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + def _to_decimal(self, val): + try: + decimal_value = Decimal(val) + # See GH 662, edge case, infinite value should not be converted + # via `_to_decimal` + if not decimal_value.is_finite(): + raise ValueError("Converted decimal value is infinite or NaN") + except Exception as e: + msg = "Could not convert %s to decimal" % val + six.raise_from(ValueError(msg), e) + else: + return decimal_value + + # ------------------------------------------------------------------ + # Post-Parsing construction of datetime output. These are kept as + # methods instead of functions for the sake of customizability via + # subclassing. + + def _build_tzinfo(self, tzinfos, tzname, tzoffset): + if callable(tzinfos): + tzdata = tzinfos(tzname, tzoffset) + else: + tzdata = tzinfos.get(tzname) + # handle case where tzinfo is paased an options that returns None + # eg tzinfos = {'BRST' : None} + if isinstance(tzdata, datetime.tzinfo) or tzdata is None: + tzinfo = tzdata + elif isinstance(tzdata, text_type): + tzinfo = tz.tzstr(tzdata) + elif isinstance(tzdata, integer_types): + tzinfo = tz.tzoffset(tzname, tzdata) + else: + raise TypeError("Offset must be tzinfo subclass, tz string, " + "or int offset.") + return tzinfo + + def _build_tzaware(self, naive, res, tzinfos): + if (callable(tzinfos) or (tzinfos and res.tzname in tzinfos)): + tzinfo = self._build_tzinfo(tzinfos, res.tzname, res.tzoffset) + aware = naive.replace(tzinfo=tzinfo) + aware = self._assign_tzname(aware, res.tzname) + + elif res.tzname and res.tzname in time.tzname: + aware = naive.replace(tzinfo=tz.tzlocal()) + + # Handle ambiguous local datetime + aware = self._assign_tzname(aware, res.tzname) + + # This is mostly relevant for winter GMT zones parsed in the UK + if (aware.tzname() != res.tzname and + res.tzname in self.info.UTCZONE): + aware = aware.replace(tzinfo=tz.UTC) + + elif res.tzoffset == 0: + aware = naive.replace(tzinfo=tz.UTC) + + elif res.tzoffset: + aware = naive.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) + + elif not res.tzname and not res.tzoffset: + # i.e. no timezone information was found. + aware = naive + + elif res.tzname: + # tz-like string was parsed but we don't know what to do + # with it + warnings.warn("tzname {tzname} identified but not understood. " + "Pass `tzinfos` argument in order to correctly " + "return a timezone-aware datetime. In a future " + "version, this will raise an " + "exception.".format(tzname=res.tzname), + category=UnknownTimezoneWarning) + aware = naive + + return aware + + def _build_naive(self, res, default): + repl = {} + for attr in ("year", "month", "day", "hour", + "minute", "second", "microsecond"): + value = getattr(res, attr) + if value is not None: + repl[attr] = value + + if 'day' not in repl: + # If the default day exceeds the last day of the month, fall back + # to the end of the month. + cyear = default.year if res.year is None else res.year + cmonth = default.month if res.month is None else res.month + cday = default.day if res.day is None else res.day + + if cday > monthrange(cyear, cmonth)[1]: + repl['day'] = monthrange(cyear, cmonth)[1] + + naive = default.replace(**repl) + + if res.weekday is not None and not res.day: + naive = naive + relativedelta.relativedelta(weekday=res.weekday) + + return naive + + def _assign_tzname(self, dt, tzname): + if dt.tzname() != tzname: + new_dt = tz.enfold(dt, fold=1) + if new_dt.tzname() == tzname: + return new_dt + + return dt + + def _recombine_skipped(self, tokens, skipped_idxs): + """ + >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"] + >>> skipped_idxs = [0, 1, 2, 5] + >>> _recombine_skipped(tokens, skipped_idxs) + ["foo bar", "baz"] + """ + skipped_tokens = [] + for i, idx in enumerate(sorted(skipped_idxs)): + if i > 0 and idx - 1 == skipped_idxs[i - 1]: + skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx] + else: + skipped_tokens.append(tokens[idx]) + + return skipped_tokens + + +DEFAULTPARSER = parser() + + +def parse(timestr, parserinfo=None, **kwargs): + """ + + Parse a string in one of the supported formats, using the + ``parserinfo`` parameters. + + :param timestr: + A string containing a date/time stamp. + + :param parserinfo: + A :class:`parserinfo` object containing parameters for the parser. + If ``None``, the default arguments to the :class:`parserinfo` + constructor are used. + + The ``**kwargs`` parameter takes the following keyword arguments: + + :param default: + The default datetime object, if this is a datetime object and not + ``None``, elements specified in ``timestr`` replace elements in the + default object. + + :param ignoretz: + If set ``True``, time zones in parsed strings are ignored and a naive + :class:`datetime` object is returned. + + :param tzinfos: + Additional time zone names / aliases which may be present in the + string. This argument maps time zone names (and optionally offsets + from those time zones) to time zones. This parameter can be a + dictionary with timezone aliases mapping time zone names to time + zones or a function taking two parameters (``tzname`` and + ``tzoffset``) and returning a time zone. + + The timezones to which the names are mapped can be an integer + offset from UTC in seconds or a :class:`tzinfo` object. + + .. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> from dateutil.parser import parse + >>> from dateutil.tz import gettz + >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")} + >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos) + datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200)) + >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos) + datetime.datetime(2012, 1, 19, 17, 21, + tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago')) + + This parameter is ignored if ``ignoretz`` is set. + + :param dayfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the day (``True``) or month (``False``). If + ``yearfirst`` is set to ``True``, this distinguishes between YDM and + YMD. If set to ``None``, this value is retrieved from the current + :class:`parserinfo` object (which itself defaults to ``False``). + + :param yearfirst: + Whether to interpret the first value in an ambiguous 3-integer date + (e.g. 01/05/09) as the year. If ``True``, the first number is taken to + be the year, otherwise the last number is taken to be the year. If + this is set to ``None``, the value is retrieved from the current + :class:`parserinfo` object (which itself defaults to ``False``). + + :param fuzzy: + Whether to allow fuzzy parsing, allowing for string like "Today is + January 1, 2047 at 8:21:00AM". + + :param fuzzy_with_tokens: + If ``True``, ``fuzzy`` is automatically set to True, and the parser + will return a tuple where the first element is the parsed + :class:`datetime.datetime` datetimestamp and the second element is + a tuple containing the portions of the string which were ignored: + + .. doctest:: + + >>> from dateutil.parser import parse + >>> parse("Today is January 1, 2047 at 8:21:00AM", fuzzy_with_tokens=True) + (datetime.datetime(2047, 1, 1, 8, 21), (u'Today is ', u' ', u'at ')) + + :return: + Returns a :class:`datetime.datetime` object or, if the + ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the + first element being a :class:`datetime.datetime` object, the second + a tuple containing the fuzzy tokens. + + :raises ParserError: + Raised for invalid or unknown string formats, if the provided + :class:`tzinfo` is not in a valid format, or if an invalid date would + be created. + + :raises OverflowError: + Raised if the parsed date exceeds the largest valid C integer on + your system. + """ + if parserinfo: + return parser(parserinfo).parse(timestr, **kwargs) + else: + return DEFAULTPARSER.parse(timestr, **kwargs) + + +class _tzparser(object): + + class _result(_resultbase): + + __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", + "start", "end"] + + class _attr(_resultbase): + __slots__ = ["month", "week", "weekday", + "yday", "jyday", "day", "time"] + + def __repr__(self): + return self._repr("") + + def __init__(self): + _resultbase.__init__(self) + self.start = self._attr() + self.end = self._attr() + + def parse(self, tzstr): + res = self._result() + l = [x for x in re.split(r'([,:.]|[a-zA-Z]+|[0-9]+)',tzstr) if x] + used_idxs = list() + try: + + len_l = len(l) + + i = 0 + while i < len_l: + # BRST+3[BRDT[+2]] + j = i + while j < len_l and not [x for x in l[j] + if x in "0123456789:,-+"]: + j += 1 + if j != i: + if not res.stdabbr: + offattr = "stdoffset" + res.stdabbr = "".join(l[i:j]) + else: + offattr = "dstoffset" + res.dstabbr = "".join(l[i:j]) + + for ii in range(j): + used_idxs.append(ii) + i = j + if (i < len_l and (l[i] in ('+', '-') or l[i][0] in + "0123456789")): + if l[i] in ('+', '-'): + # Yes, that's right. See the TZ variable + # documentation. + signal = (1, -1)[l[i] == '+'] + used_idxs.append(i) + i += 1 + else: + signal = -1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + setattr(res, offattr, (int(l[i][:2]) * 3600 + + int(l[i][2:]) * 60) * signal) + elif i + 1 < len_l and l[i + 1] == ':': + # -03:00 + setattr(res, offattr, + (int(l[i]) * 3600 + + int(l[i + 2]) * 60) * signal) + used_idxs.append(i) + i += 2 + elif len_li <= 2: + # -[0]3 + setattr(res, offattr, + int(l[i][:2]) * 3600 * signal) + else: + return None + used_idxs.append(i) + i += 1 + if res.dstabbr: + break + else: + break + + + if i < len_l: + for j in range(i, len_l): + if l[j] == ';': + l[j] = ',' + + assert l[i] == ',' + + i += 1 + + if i >= len_l: + pass + elif (8 <= l.count(',') <= 9 and + not [y for x in l[i:] if x != ',' + for y in x if y not in "0123456789+-"]): + # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] + for x in (res.start, res.end): + x.month = int(l[i]) + used_idxs.append(i) + i += 2 + if l[i] == '-': + value = int(l[i + 1]) * -1 + used_idxs.append(i) + i += 1 + else: + value = int(l[i]) + used_idxs.append(i) + i += 2 + if value: + x.week = value + x.weekday = (int(l[i]) - 1) % 7 + else: + x.day = int(l[i]) + used_idxs.append(i) + i += 2 + x.time = int(l[i]) + used_idxs.append(i) + i += 2 + if i < len_l: + if l[i] in ('-', '+'): + signal = (-1, 1)[l[i] == "+"] + used_idxs.append(i) + i += 1 + else: + signal = 1 + used_idxs.append(i) + res.dstoffset = (res.stdoffset + int(l[i]) * signal) + + # This was a made-up format that is not in normal use + warn(('Parsed time zone "%s"' % tzstr) + + 'is in a non-standard dateutil-specific format, which ' + + 'is now deprecated; support for parsing this format ' + + 'will be removed in future versions. It is recommended ' + + 'that you switch to a standard format like the GNU ' + + 'TZ variable format.', tz.DeprecatedTzFormatWarning) + elif (l.count(',') == 2 and l[i:].count('/') <= 2 and + not [y for x in l[i:] if x not in (',', '/', 'J', 'M', + '.', '-', ':') + for y in x if y not in "0123456789"]): + for x in (res.start, res.end): + if l[i] == 'J': + # non-leap year day (1 based) + used_idxs.append(i) + i += 1 + x.jyday = int(l[i]) + elif l[i] == 'M': + # month[-.]week[-.]weekday + used_idxs.append(i) + i += 1 + x.month = int(l[i]) + used_idxs.append(i) + i += 1 + assert l[i] in ('-', '.') + used_idxs.append(i) + i += 1 + x.week = int(l[i]) + if x.week == 5: + x.week = -1 + used_idxs.append(i) + i += 1 + assert l[i] in ('-', '.') + used_idxs.append(i) + i += 1 + x.weekday = (int(l[i]) - 1) % 7 + else: + # year day (zero based) + x.yday = int(l[i]) + 1 + + used_idxs.append(i) + i += 1 + + if i < len_l and l[i] == '/': + used_idxs.append(i) + i += 1 + # start time + len_li = len(l[i]) + if len_li == 4: + # -0300 + x.time = (int(l[i][:2]) * 3600 + + int(l[i][2:]) * 60) + elif i + 1 < len_l and l[i + 1] == ':': + # -03:00 + x.time = int(l[i]) * 3600 + int(l[i + 2]) * 60 + used_idxs.append(i) + i += 2 + if i + 1 < len_l and l[i + 1] == ':': + used_idxs.append(i) + i += 2 + x.time += int(l[i]) + elif len_li <= 2: + # -[0]3 + x.time = (int(l[i][:2]) * 3600) + else: + return None + used_idxs.append(i) + i += 1 + + assert i == len_l or l[i] == ',' + + i += 1 + + assert i >= len_l + + except (IndexError, ValueError, AssertionError): + return None + + unused_idxs = set(range(len_l)).difference(used_idxs) + res.any_unused_tokens = not {l[n] for n in unused_idxs}.issubset({",",":"}) + return res + + +DEFAULTTZPARSER = _tzparser() + + +def _parsetz(tzstr): + return DEFAULTTZPARSER.parse(tzstr) + + +class ParserError(ValueError): + """Exception subclass used for any failure to parse a datetime string. + + This is a subclass of :py:exc:`ValueError`, and should be raised any time + earlier versions of ``dateutil`` would have raised ``ValueError``. + + .. versionadded:: 2.8.1 + """ + def __str__(self): + try: + return self.args[0] % self.args[1:] + except (TypeError, IndexError): + return super(ParserError, self).__str__() + + def __repr__(self): + args = ", ".join("'%s'" % arg for arg in self.args) + return "%s(%s)" % (self.__class__.__name__, args) + + +class UnknownTimezoneWarning(RuntimeWarning): + """Raised when the parser finds a timezone it cannot parse into a tzinfo. + + .. versionadded:: 2.7.0 + """ +# vim:ts=4:sw=4:et diff --git a/.venv/lib/python3.7/site-packages/dateutil/parser/isoparser.py b/.venv/lib/python3.7/site-packages/dateutil/parser/isoparser.py new file mode 100644 index 0000000..5d7bee3 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/parser/isoparser.py @@ -0,0 +1,416 @@ +# -*- coding: utf-8 -*- +""" +This module offers a parser for ISO-8601 strings + +It is intended to support all valid date, time and datetime formats per the +ISO-8601 specification. + +..versionadded:: 2.7.0 +""" +from datetime import datetime, timedelta, time, date +import calendar +from dateutil import tz + +from functools import wraps + +import re +import six + +__all__ = ["isoparse", "isoparser"] + + +def _takes_ascii(f): + @wraps(f) + def func(self, str_in, *args, **kwargs): + # If it's a stream, read the whole thing + str_in = getattr(str_in, 'read', lambda: str_in)() + + # If it's unicode, turn it into bytes, since ISO-8601 only covers ASCII + if isinstance(str_in, six.text_type): + # ASCII is the same in UTF-8 + try: + str_in = str_in.encode('ascii') + except UnicodeEncodeError as e: + msg = 'ISO-8601 strings should contain only ASCII characters' + six.raise_from(ValueError(msg), e) + + return f(self, str_in, *args, **kwargs) + + return func + + +class isoparser(object): + def __init__(self, sep=None): + """ + :param sep: + A single character that separates date and time portions. If + ``None``, the parser will accept any single character. + For strict ISO-8601 adherence, pass ``'T'``. + """ + if sep is not None: + if (len(sep) != 1 or ord(sep) >= 128 or sep in '0123456789'): + raise ValueError('Separator must be a single, non-numeric ' + + 'ASCII character') + + sep = sep.encode('ascii') + + self._sep = sep + + @_takes_ascii + def isoparse(self, dt_str): + """ + Parse an ISO-8601 datetime string into a :class:`datetime.datetime`. + + An ISO-8601 datetime string consists of a date portion, followed + optionally by a time portion - the date and time portions are separated + by a single character separator, which is ``T`` in the official + standard. Incomplete date formats (such as ``YYYY-MM``) may *not* be + combined with a time portion. + + Supported date formats are: + + Common: + + - ``YYYY`` + - ``YYYY-MM`` or ``YYYYMM`` + - ``YYYY-MM-DD`` or ``YYYYMMDD`` + + Uncommon: + + - ``YYYY-Www`` or ``YYYYWww`` - ISO week (day defaults to 0) + - ``YYYY-Www-D`` or ``YYYYWwwD`` - ISO week and day + + The ISO week and day numbering follows the same logic as + :func:`datetime.date.isocalendar`. + + Supported time formats are: + + - ``hh`` + - ``hh:mm`` or ``hhmm`` + - ``hh:mm:ss`` or ``hhmmss`` + - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits) + + Midnight is a special case for `hh`, as the standard supports both + 00:00 and 24:00 as a representation. The decimal separator can be + either a dot or a comma. + + + .. caution:: + + Support for fractional components other than seconds is part of the + ISO-8601 standard, but is not currently implemented in this parser. + + Supported time zone offset formats are: + + - `Z` (UTC) + - `±HH:MM` + - `±HHMM` + - `±HH` + + Offsets will be represented as :class:`dateutil.tz.tzoffset` objects, + with the exception of UTC, which will be represented as + :class:`dateutil.tz.tzutc`. Time zone offsets equivalent to UTC (such + as `+00:00`) will also be represented as :class:`dateutil.tz.tzutc`. + + :param dt_str: + A string or stream containing only an ISO-8601 datetime string + + :return: + Returns a :class:`datetime.datetime` representing the string. + Unspecified components default to their lowest value. + + .. warning:: + + As of version 2.7.0, the strictness of the parser should not be + considered a stable part of the contract. Any valid ISO-8601 string + that parses correctly with the default settings will continue to + parse correctly in future versions, but invalid strings that + currently fail (e.g. ``2017-01-01T00:00+00:00:00``) are not + guaranteed to continue failing in future versions if they encode + a valid date. + + .. versionadded:: 2.7.0 + """ + components, pos = self._parse_isodate(dt_str) + + if len(dt_str) > pos: + if self._sep is None or dt_str[pos:pos + 1] == self._sep: + components += self._parse_isotime(dt_str[pos + 1:]) + else: + raise ValueError('String contains unknown ISO components') + + if len(components) > 3 and components[3] == 24: + components[3] = 0 + return datetime(*components) + timedelta(days=1) + + return datetime(*components) + + @_takes_ascii + def parse_isodate(self, datestr): + """ + Parse the date portion of an ISO string. + + :param datestr: + The string portion of an ISO string, without a separator + + :return: + Returns a :class:`datetime.date` object + """ + components, pos = self._parse_isodate(datestr) + if pos < len(datestr): + raise ValueError('String contains unknown ISO ' + + 'components: {!r}'.format(datestr.decode('ascii'))) + return date(*components) + + @_takes_ascii + def parse_isotime(self, timestr): + """ + Parse the time portion of an ISO string. + + :param timestr: + The time portion of an ISO string, without a separator + + :return: + Returns a :class:`datetime.time` object + """ + components = self._parse_isotime(timestr) + if components[0] == 24: + components[0] = 0 + return time(*components) + + @_takes_ascii + def parse_tzstr(self, tzstr, zero_as_utc=True): + """ + Parse a valid ISO time zone string. + + See :func:`isoparser.isoparse` for details on supported formats. + + :param tzstr: + A string representing an ISO time zone offset + + :param zero_as_utc: + Whether to return :class:`dateutil.tz.tzutc` for zero-offset zones + + :return: + Returns :class:`dateutil.tz.tzoffset` for offsets and + :class:`dateutil.tz.tzutc` for ``Z`` and (if ``zero_as_utc`` is + specified) offsets equivalent to UTC. + """ + return self._parse_tzstr(tzstr, zero_as_utc=zero_as_utc) + + # Constants + _DATE_SEP = b'-' + _TIME_SEP = b':' + _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)') + + def _parse_isodate(self, dt_str): + try: + return self._parse_isodate_common(dt_str) + except ValueError: + return self._parse_isodate_uncommon(dt_str) + + def _parse_isodate_common(self, dt_str): + len_str = len(dt_str) + components = [1, 1, 1] + + if len_str < 4: + raise ValueError('ISO string too short') + + # Year + components[0] = int(dt_str[0:4]) + pos = 4 + if pos >= len_str: + return components, pos + + has_sep = dt_str[pos:pos + 1] == self._DATE_SEP + if has_sep: + pos += 1 + + # Month + if len_str - pos < 2: + raise ValueError('Invalid common month') + + components[1] = int(dt_str[pos:pos + 2]) + pos += 2 + + if pos >= len_str: + if has_sep: + return components, pos + else: + raise ValueError('Invalid ISO format') + + if has_sep: + if dt_str[pos:pos + 1] != self._DATE_SEP: + raise ValueError('Invalid separator in ISO string') + pos += 1 + + # Day + if len_str - pos < 2: + raise ValueError('Invalid common day') + components[2] = int(dt_str[pos:pos + 2]) + return components, pos + 2 + + def _parse_isodate_uncommon(self, dt_str): + if len(dt_str) < 4: + raise ValueError('ISO string too short') + + # All ISO formats start with the year + year = int(dt_str[0:4]) + + has_sep = dt_str[4:5] == self._DATE_SEP + + pos = 4 + has_sep # Skip '-' if it's there + if dt_str[pos:pos + 1] == b'W': + # YYYY-?Www-?D? + pos += 1 + weekno = int(dt_str[pos:pos + 2]) + pos += 2 + + dayno = 1 + if len(dt_str) > pos: + if (dt_str[pos:pos + 1] == self._DATE_SEP) != has_sep: + raise ValueError('Inconsistent use of dash separator') + + pos += has_sep + + dayno = int(dt_str[pos:pos + 1]) + pos += 1 + + base_date = self._calculate_weekdate(year, weekno, dayno) + else: + # YYYYDDD or YYYY-DDD + if len(dt_str) - pos < 3: + raise ValueError('Invalid ordinal day') + + ordinal_day = int(dt_str[pos:pos + 3]) + pos += 3 + + if ordinal_day < 1 or ordinal_day > (365 + calendar.isleap(year)): + raise ValueError('Invalid ordinal day' + + ' {} for year {}'.format(ordinal_day, year)) + + base_date = date(year, 1, 1) + timedelta(days=ordinal_day - 1) + + components = [base_date.year, base_date.month, base_date.day] + return components, pos + + def _calculate_weekdate(self, year, week, day): + """ + Calculate the day of corresponding to the ISO year-week-day calendar. + + This function is effectively the inverse of + :func:`datetime.date.isocalendar`. + + :param year: + The year in the ISO calendar + + :param week: + The week in the ISO calendar - range is [1, 53] + + :param day: + The day in the ISO calendar - range is [1 (MON), 7 (SUN)] + + :return: + Returns a :class:`datetime.date` + """ + if not 0 < week < 54: + raise ValueError('Invalid week: {}'.format(week)) + + if not 0 < day < 8: # Range is 1-7 + raise ValueError('Invalid weekday: {}'.format(day)) + + # Get week 1 for the specific year: + jan_4 = date(year, 1, 4) # Week 1 always has January 4th in it + week_1 = jan_4 - timedelta(days=jan_4.isocalendar()[2] - 1) + + # Now add the specific number of weeks and days to get what we want + week_offset = (week - 1) * 7 + (day - 1) + return week_1 + timedelta(days=week_offset) + + def _parse_isotime(self, timestr): + len_str = len(timestr) + components = [0, 0, 0, 0, None] + pos = 0 + comp = -1 + + if len_str < 2: + raise ValueError('ISO time too short') + + has_sep = False + + while pos < len_str and comp < 5: + comp += 1 + + if timestr[pos:pos + 1] in b'-+Zz': + # Detect time zone boundary + components[-1] = self._parse_tzstr(timestr[pos:]) + pos = len_str + break + + if comp == 1 and timestr[pos:pos+1] == self._TIME_SEP: + has_sep = True + pos += 1 + elif comp == 2 and has_sep: + if timestr[pos:pos+1] != self._TIME_SEP: + raise ValueError('Inconsistent use of colon separator') + pos += 1 + + if comp < 3: + # Hour, minute, second + components[comp] = int(timestr[pos:pos + 2]) + pos += 2 + + if comp == 3: + # Fraction of a second + frac = self._FRACTION_REGEX.match(timestr[pos:]) + if not frac: + continue + + us_str = frac.group(1)[:6] # Truncate to microseconds + components[comp] = int(us_str) * 10**(6 - len(us_str)) + pos += len(frac.group()) + + if pos < len_str: + raise ValueError('Unused components in ISO string') + + if components[0] == 24: + # Standard supports 00:00 and 24:00 as representations of midnight + if any(component != 0 for component in components[1:4]): + raise ValueError('Hour may only be 24 at 24:00:00.000') + + return components + + def _parse_tzstr(self, tzstr, zero_as_utc=True): + if tzstr == b'Z' or tzstr == b'z': + return tz.UTC + + if len(tzstr) not in {3, 5, 6}: + raise ValueError('Time zone offset must be 1, 3, 5 or 6 characters') + + if tzstr[0:1] == b'-': + mult = -1 + elif tzstr[0:1] == b'+': + mult = 1 + else: + raise ValueError('Time zone offset requires sign') + + hours = int(tzstr[1:3]) + if len(tzstr) == 3: + minutes = 0 + else: + minutes = int(tzstr[(4 if tzstr[3:4] == self._TIME_SEP else 3):]) + + if zero_as_utc and hours == 0 and minutes == 0: + return tz.UTC + else: + if minutes > 59: + raise ValueError('Invalid minutes in time zone offset') + + if hours > 23: + raise ValueError('Invalid hours in time zone offset') + + return tz.tzoffset(None, mult * (hours * 60 + minutes) * 60) + + +DEFAULT_ISOPARSER = isoparser() +isoparse = DEFAULT_ISOPARSER.isoparse diff --git a/.venv/lib/python3.7/site-packages/dateutil/relativedelta.py b/.venv/lib/python3.7/site-packages/dateutil/relativedelta.py new file mode 100644 index 0000000..a9e85f7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/relativedelta.py @@ -0,0 +1,599 @@ +# -*- coding: utf-8 -*- +import datetime +import calendar + +import operator +from math import copysign + +from six import integer_types +from warnings import warn + +from ._common import weekday + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple(weekday(x) for x in range(7)) + +__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + + +class relativedelta(object): + """ + The relativedelta type is designed to be applied to an existing datetime and + can replace specific components of that datetime, or represents an interval + of time. + + It is based on the specification of the excellent work done by M.-A. Lemburg + in his + `mx.DateTime `_ extension. + However, notice that this type does *NOT* implement the same algorithm as + his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. + + There are two different ways to build a relativedelta instance. The + first one is passing it two date/datetime classes:: + + relativedelta(datetime1, datetime2) + + The second one is passing it any number of the following keyword arguments:: + + relativedelta(arg1=x,arg2=y,arg3=z...) + + year, month, day, hour, minute, second, microsecond: + Absolute information (argument is singular); adding or subtracting a + relativedelta with absolute information does not perform an arithmetic + operation, but rather REPLACES the corresponding value in the + original datetime with the value(s) in relativedelta. + + years, months, weeks, days, hours, minutes, seconds, microseconds: + Relative information, may be negative (argument is plural); adding + or subtracting a relativedelta with relative information performs + the corresponding arithmetic operation on the original datetime value + with the information in the relativedelta. + + weekday: + One of the weekday instances (MO, TU, etc) available in the + relativedelta module. These instances may receive a parameter N, + specifying the Nth weekday, which could be positive or negative + (like MO(+1) or MO(-2)). Not specifying it is the same as specifying + +1. You can also use an integer, where 0=MO. This argument is always + relative e.g. if the calculated date is already Monday, using MO(1) + or MO(-1) won't change the day. To effectively make it absolute, use + it in combination with the day argument (e.g. day=1, MO(1) for first + Monday of the month). + + leapdays: + Will add given days to the date found, if year is a leap + year, and the date found is post 28 of february. + + yearday, nlyearday: + Set the yearday or the non-leap year day (jump leap days). + These are converted to day/month/leapdays information. + + There are relative and absolute forms of the keyword + arguments. The plural is relative, and the singular is + absolute. For each argument in the order below, the absolute form + is applied first (by setting each attribute to that value) and + then the relative form (by adding the value to the attribute). + + The order of attributes considered when this relativedelta is + added to a datetime is: + + 1. Year + 2. Month + 3. Day + 4. Hours + 5. Minutes + 6. Seconds + 7. Microseconds + + Finally, weekday is applied, using the rule described above. + + For example + + >>> from datetime import datetime + >>> from dateutil.relativedelta import relativedelta, MO + >>> dt = datetime(2018, 4, 9, 13, 37, 0) + >>> delta = relativedelta(hours=25, day=1, weekday=MO(1)) + >>> dt + delta + datetime.datetime(2018, 4, 2, 14, 37) + + First, the day is set to 1 (the first of the month), then 25 hours + are added, to get to the 2nd day and 14th hour, finally the + weekday is applied, but since the 2nd is already a Monday there is + no effect. + + """ + + def __init__(self, dt1=None, dt2=None, + years=0, months=0, days=0, leapdays=0, weeks=0, + hours=0, minutes=0, seconds=0, microseconds=0, + year=None, month=None, day=None, weekday=None, + yearday=None, nlyearday=None, + hour=None, minute=None, second=None, microsecond=None): + + if dt1 and dt2: + # datetime is a subclass of date. So both must be date + if not (isinstance(dt1, datetime.date) and + isinstance(dt2, datetime.date)): + raise TypeError("relativedelta only diffs datetime/date") + + # We allow two dates, or two datetimes, so we coerce them to be + # of the same type + if (isinstance(dt1, datetime.datetime) != + isinstance(dt2, datetime.datetime)): + if not isinstance(dt1, datetime.datetime): + dt1 = datetime.datetime.fromordinal(dt1.toordinal()) + elif not isinstance(dt2, datetime.datetime): + dt2 = datetime.datetime.fromordinal(dt2.toordinal()) + + self.years = 0 + self.months = 0 + self.days = 0 + self.leapdays = 0 + self.hours = 0 + self.minutes = 0 + self.seconds = 0 + self.microseconds = 0 + self.year = None + self.month = None + self.day = None + self.weekday = None + self.hour = None + self.minute = None + self.second = None + self.microsecond = None + self._has_time = 0 + + # Get year / month delta between the two + months = (dt1.year - dt2.year) * 12 + (dt1.month - dt2.month) + self._set_months(months) + + # Remove the year/month delta so the timedelta is just well-defined + # time units (seconds, days and microseconds) + dtm = self.__radd__(dt2) + + # If we've overshot our target, make an adjustment + if dt1 < dt2: + compare = operator.gt + increment = 1 + else: + compare = operator.lt + increment = -1 + + while compare(dt1, dtm): + months += increment + self._set_months(months) + dtm = self.__radd__(dt2) + + # Get the timedelta between the "months-adjusted" date and dt1 + delta = dt1 - dtm + self.seconds = delta.seconds + delta.days * 86400 + self.microseconds = delta.microseconds + else: + # Check for non-integer values in integer-only quantities + if any(x is not None and x != int(x) for x in (years, months)): + raise ValueError("Non-integer years and months are " + "ambiguous and not currently supported.") + + # Relative information + self.years = int(years) + self.months = int(months) + self.days = days + weeks * 7 + self.leapdays = leapdays + self.hours = hours + self.minutes = minutes + self.seconds = seconds + self.microseconds = microseconds + + # Absolute information + self.year = year + self.month = month + self.day = day + self.hour = hour + self.minute = minute + self.second = second + self.microsecond = microsecond + + if any(x is not None and int(x) != x + for x in (year, month, day, hour, + minute, second, microsecond)): + # For now we'll deprecate floats - later it'll be an error. + warn("Non-integer value passed as absolute information. " + + "This is not a well-defined condition and will raise " + + "errors in future versions.", DeprecationWarning) + + if isinstance(weekday, integer_types): + self.weekday = weekdays[weekday] + else: + self.weekday = weekday + + yday = 0 + if nlyearday: + yday = nlyearday + elif yearday: + yday = yearday + if yearday > 59: + self.leapdays = -1 + if yday: + ydayidx = [31, 59, 90, 120, 151, 181, 212, + 243, 273, 304, 334, 366] + for idx, ydays in enumerate(ydayidx): + if yday <= ydays: + self.month = idx+1 + if idx == 0: + self.day = yday + else: + self.day = yday-ydayidx[idx-1] + break + else: + raise ValueError("invalid year day (%d)" % yday) + + self._fix() + + def _fix(self): + if abs(self.microseconds) > 999999: + s = _sign(self.microseconds) + div, mod = divmod(self.microseconds * s, 1000000) + self.microseconds = mod * s + self.seconds += div * s + if abs(self.seconds) > 59: + s = _sign(self.seconds) + div, mod = divmod(self.seconds * s, 60) + self.seconds = mod * s + self.minutes += div * s + if abs(self.minutes) > 59: + s = _sign(self.minutes) + div, mod = divmod(self.minutes * s, 60) + self.minutes = mod * s + self.hours += div * s + if abs(self.hours) > 23: + s = _sign(self.hours) + div, mod = divmod(self.hours * s, 24) + self.hours = mod * s + self.days += div * s + if abs(self.months) > 11: + s = _sign(self.months) + div, mod = divmod(self.months * s, 12) + self.months = mod * s + self.years += div * s + if (self.hours or self.minutes or self.seconds or self.microseconds + or self.hour is not None or self.minute is not None or + self.second is not None or self.microsecond is not None): + self._has_time = 1 + else: + self._has_time = 0 + + @property + def weeks(self): + return int(self.days / 7.0) + + @weeks.setter + def weeks(self, value): + self.days = self.days - (self.weeks * 7) + value * 7 + + def _set_months(self, months): + self.months = months + if abs(self.months) > 11: + s = _sign(self.months) + div, mod = divmod(self.months * s, 12) + self.months = mod * s + self.years = div * s + else: + self.years = 0 + + def normalized(self): + """ + Return a version of this object represented entirely using integer + values for the relative attributes. + + >>> relativedelta(days=1.5, hours=2).normalized() + relativedelta(days=+1, hours=+14) + + :return: + Returns a :class:`dateutil.relativedelta.relativedelta` object. + """ + # Cascade remainders down (rounding each to roughly nearest microsecond) + days = int(self.days) + + hours_f = round(self.hours + 24 * (self.days - days), 11) + hours = int(hours_f) + + minutes_f = round(self.minutes + 60 * (hours_f - hours), 10) + minutes = int(minutes_f) + + seconds_f = round(self.seconds + 60 * (minutes_f - minutes), 8) + seconds = int(seconds_f) + + microseconds = round(self.microseconds + 1e6 * (seconds_f - seconds)) + + # Constructor carries overflow back up with call to _fix() + return self.__class__(years=self.years, months=self.months, + days=days, hours=hours, minutes=minutes, + seconds=seconds, microseconds=microseconds, + leapdays=self.leapdays, year=self.year, + month=self.month, day=self.day, + weekday=self.weekday, hour=self.hour, + minute=self.minute, second=self.second, + microsecond=self.microsecond) + + def __add__(self, other): + if isinstance(other, relativedelta): + return self.__class__(years=other.years + self.years, + months=other.months + self.months, + days=other.days + self.days, + hours=other.hours + self.hours, + minutes=other.minutes + self.minutes, + seconds=other.seconds + self.seconds, + microseconds=(other.microseconds + + self.microseconds), + leapdays=other.leapdays or self.leapdays, + year=(other.year if other.year is not None + else self.year), + month=(other.month if other.month is not None + else self.month), + day=(other.day if other.day is not None + else self.day), + weekday=(other.weekday if other.weekday is not None + else self.weekday), + hour=(other.hour if other.hour is not None + else self.hour), + minute=(other.minute if other.minute is not None + else self.minute), + second=(other.second if other.second is not None + else self.second), + microsecond=(other.microsecond if other.microsecond + is not None else + self.microsecond)) + if isinstance(other, datetime.timedelta): + return self.__class__(years=self.years, + months=self.months, + days=self.days + other.days, + hours=self.hours, + minutes=self.minutes, + seconds=self.seconds + other.seconds, + microseconds=self.microseconds + other.microseconds, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + if not isinstance(other, datetime.date): + return NotImplemented + elif self._has_time and not isinstance(other, datetime.datetime): + other = datetime.datetime.fromordinal(other.toordinal()) + year = (self.year or other.year)+self.years + month = self.month or other.month + if self.months: + assert 1 <= abs(self.months) <= 12 + month += self.months + if month > 12: + year += 1 + month -= 12 + elif month < 1: + year -= 1 + month += 12 + day = min(calendar.monthrange(year, month)[1], + self.day or other.day) + repl = {"year": year, "month": month, "day": day} + for attr in ["hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + repl[attr] = value + days = self.days + if self.leapdays and month > 2 and calendar.isleap(year): + days += self.leapdays + ret = (other.replace(**repl) + + datetime.timedelta(days=days, + hours=self.hours, + minutes=self.minutes, + seconds=self.seconds, + microseconds=self.microseconds)) + if self.weekday: + weekday, nth = self.weekday.weekday, self.weekday.n or 1 + jumpdays = (abs(nth) - 1) * 7 + if nth > 0: + jumpdays += (7 - ret.weekday() + weekday) % 7 + else: + jumpdays += (ret.weekday() - weekday) % 7 + jumpdays *= -1 + ret += datetime.timedelta(days=jumpdays) + return ret + + def __radd__(self, other): + return self.__add__(other) + + def __rsub__(self, other): + return self.__neg__().__radd__(other) + + def __sub__(self, other): + if not isinstance(other, relativedelta): + return NotImplemented # In case the other object defines __rsub__ + return self.__class__(years=self.years - other.years, + months=self.months - other.months, + days=self.days - other.days, + hours=self.hours - other.hours, + minutes=self.minutes - other.minutes, + seconds=self.seconds - other.seconds, + microseconds=self.microseconds - other.microseconds, + leapdays=self.leapdays or other.leapdays, + year=(self.year if self.year is not None + else other.year), + month=(self.month if self.month is not None else + other.month), + day=(self.day if self.day is not None else + other.day), + weekday=(self.weekday if self.weekday is not None else + other.weekday), + hour=(self.hour if self.hour is not None else + other.hour), + minute=(self.minute if self.minute is not None else + other.minute), + second=(self.second if self.second is not None else + other.second), + microsecond=(self.microsecond if self.microsecond + is not None else + other.microsecond)) + + def __abs__(self): + return self.__class__(years=abs(self.years), + months=abs(self.months), + days=abs(self.days), + hours=abs(self.hours), + minutes=abs(self.minutes), + seconds=abs(self.seconds), + microseconds=abs(self.microseconds), + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __neg__(self): + return self.__class__(years=-self.years, + months=-self.months, + days=-self.days, + hours=-self.hours, + minutes=-self.minutes, + seconds=-self.seconds, + microseconds=-self.microseconds, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __bool__(self): + return not (not self.years and + not self.months and + not self.days and + not self.hours and + not self.minutes and + not self.seconds and + not self.microseconds and + not self.leapdays and + self.year is None and + self.month is None and + self.day is None and + self.weekday is None and + self.hour is None and + self.minute is None and + self.second is None and + self.microsecond is None) + # Compatibility with Python 2.x + __nonzero__ = __bool__ + + def __mul__(self, other): + try: + f = float(other) + except TypeError: + return NotImplemented + + return self.__class__(years=int(self.years * f), + months=int(self.months * f), + days=int(self.days * f), + hours=int(self.hours * f), + minutes=int(self.minutes * f), + seconds=int(self.seconds * f), + microseconds=int(self.microseconds * f), + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + __rmul__ = __mul__ + + def __eq__(self, other): + if not isinstance(other, relativedelta): + return NotImplemented + if self.weekday or other.weekday: + if not self.weekday or not other.weekday: + return False + if self.weekday.weekday != other.weekday.weekday: + return False + n1, n2 = self.weekday.n, other.weekday.n + if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): + return False + return (self.years == other.years and + self.months == other.months and + self.days == other.days and + self.hours == other.hours and + self.minutes == other.minutes and + self.seconds == other.seconds and + self.microseconds == other.microseconds and + self.leapdays == other.leapdays and + self.year == other.year and + self.month == other.month and + self.day == other.day and + self.hour == other.hour and + self.minute == other.minute and + self.second == other.second and + self.microsecond == other.microsecond) + + def __hash__(self): + return hash(( + self.weekday, + self.years, + self.months, + self.days, + self.hours, + self.minutes, + self.seconds, + self.microseconds, + self.leapdays, + self.year, + self.month, + self.day, + self.hour, + self.minute, + self.second, + self.microsecond, + )) + + def __ne__(self, other): + return not self.__eq__(other) + + def __div__(self, other): + try: + reciprocal = 1 / float(other) + except TypeError: + return NotImplemented + + return self.__mul__(reciprocal) + + __truediv__ = __div__ + + def __repr__(self): + l = [] + for attr in ["years", "months", "days", "leapdays", + "hours", "minutes", "seconds", "microseconds"]: + value = getattr(self, attr) + if value: + l.append("{attr}={value:+g}".format(attr=attr, value=value)) + for attr in ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + l.append("{attr}={value}".format(attr=attr, value=repr(value))) + return "{classname}({attrs})".format(classname=self.__class__.__name__, + attrs=", ".join(l)) + + +def _sign(x): + return int(copysign(1, x)) + +# vim:ts=4:sw=4:et diff --git a/.venv/lib/python3.7/site-packages/dateutil/rrule.py b/.venv/lib/python3.7/site-packages/dateutil/rrule.py new file mode 100644 index 0000000..b320339 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/rrule.py @@ -0,0 +1,1737 @@ +# -*- coding: utf-8 -*- +""" +The rrule module offers a small, complete, and very fast, implementation of +the recurrence rules documented in the +`iCalendar RFC `_, +including support for caching of results. +""" +import calendar +import datetime +import heapq +import itertools +import re +import sys +from functools import wraps +# For warning about deprecation of until and count +from warnings import warn + +from six import advance_iterator, integer_types + +from six.moves import _thread, range + +from ._common import weekday as weekdaybase + +try: + from math import gcd +except ImportError: + from fractions import gcd + +__all__ = ["rrule", "rruleset", "rrulestr", + "YEARLY", "MONTHLY", "WEEKLY", "DAILY", + "HOURLY", "MINUTELY", "SECONDLY", + "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +# Every mask is 7 days longer to handle cross-year weekly periods. +M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30 + + [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) +M365MASK = list(M366MASK) +M29, M30, M31 = list(range(1, 30)), list(range(1, 31)), list(range(1, 32)) +MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +MDAY365MASK = list(MDAY366MASK) +M29, M30, M31 = list(range(-29, 0)), list(range(-30, 0)), list(range(-31, 0)) +NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +NMDAY365MASK = list(NMDAY366MASK) +M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366) +M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365) +WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55 +del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] +MDAY365MASK = tuple(MDAY365MASK) +M365MASK = tuple(M365MASK) + +FREQNAMES = ['YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'] + +(YEARLY, + MONTHLY, + WEEKLY, + DAILY, + HOURLY, + MINUTELY, + SECONDLY) = list(range(7)) + +# Imported on demand. +easter = None +parser = None + + +class weekday(weekdaybase): + """ + This version of weekday does not allow n = 0. + """ + def __init__(self, wkday, n=None): + if n == 0: + raise ValueError("Can't create weekday with n==0") + + super(weekday, self).__init__(wkday, n) + + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple(weekday(x) for x in range(7)) + + +def _invalidates_cache(f): + """ + Decorator for rruleset methods which may invalidate the + cached length. + """ + @wraps(f) + def inner_func(self, *args, **kwargs): + rv = f(self, *args, **kwargs) + self._invalidate_cache() + return rv + + return inner_func + + +class rrulebase(object): + def __init__(self, cache=False): + if cache: + self._cache = [] + self._cache_lock = _thread.allocate_lock() + self._invalidate_cache() + else: + self._cache = None + self._cache_complete = False + self._len = None + + def __iter__(self): + if self._cache_complete: + return iter(self._cache) + elif self._cache is None: + return self._iter() + else: + return self._iter_cached() + + def _invalidate_cache(self): + if self._cache is not None: + self._cache = [] + self._cache_complete = False + self._cache_gen = self._iter() + + if self._cache_lock.locked(): + self._cache_lock.release() + + self._len = None + + def _iter_cached(self): + i = 0 + gen = self._cache_gen + cache = self._cache + acquire = self._cache_lock.acquire + release = self._cache_lock.release + while gen: + if i == len(cache): + acquire() + if self._cache_complete: + break + try: + for j in range(10): + cache.append(advance_iterator(gen)) + except StopIteration: + self._cache_gen = gen = None + self._cache_complete = True + break + release() + yield cache[i] + i += 1 + while i < self._len: + yield cache[i] + i += 1 + + def __getitem__(self, item): + if self._cache_complete: + return self._cache[item] + elif isinstance(item, slice): + if item.step and item.step < 0: + return list(iter(self))[item] + else: + return list(itertools.islice(self, + item.start or 0, + item.stop or sys.maxsize, + item.step or 1)) + elif item >= 0: + gen = iter(self) + try: + for i in range(item+1): + res = advance_iterator(gen) + except StopIteration: + raise IndexError + return res + else: + return list(iter(self))[item] + + def __contains__(self, item): + if self._cache_complete: + return item in self._cache + else: + for i in self: + if i == item: + return True + elif i > item: + return False + return False + + # __len__() introduces a large performance penalty. + def count(self): + """ Returns the number of recurrences in this set. It will have go + trough the whole recurrence, if this hasn't been done before. """ + if self._len is None: + for x in self: + pass + return self._len + + def before(self, dt, inc=False): + """ Returns the last recurrence before the given datetime instance. The + inc keyword defines what happens if dt is an occurrence. With + inc=True, if dt itself is an occurrence, it will be returned. """ + if self._cache_complete: + gen = self._cache + else: + gen = self + last = None + if inc: + for i in gen: + if i > dt: + break + last = i + else: + for i in gen: + if i >= dt: + break + last = i + return last + + def after(self, dt, inc=False): + """ Returns the first recurrence after the given datetime instance. The + inc keyword defines what happens if dt is an occurrence. With + inc=True, if dt itself is an occurrence, it will be returned. """ + if self._cache_complete: + gen = self._cache + else: + gen = self + if inc: + for i in gen: + if i >= dt: + return i + else: + for i in gen: + if i > dt: + return i + return None + + def xafter(self, dt, count=None, inc=False): + """ + Generator which yields up to `count` recurrences after the given + datetime instance, equivalent to `after`. + + :param dt: + The datetime at which to start generating recurrences. + + :param count: + The maximum number of recurrences to generate. If `None` (default), + dates are generated until the recurrence rule is exhausted. + + :param inc: + If `dt` is an instance of the rule and `inc` is `True`, it is + included in the output. + + :yields: Yields a sequence of `datetime` objects. + """ + + if self._cache_complete: + gen = self._cache + else: + gen = self + + # Select the comparison function + if inc: + comp = lambda dc, dtc: dc >= dtc + else: + comp = lambda dc, dtc: dc > dtc + + # Generate dates + n = 0 + for d in gen: + if comp(d, dt): + if count is not None: + n += 1 + if n > count: + break + + yield d + + def between(self, after, before, inc=False, count=1): + """ Returns all the occurrences of the rrule between after and before. + The inc keyword defines what happens if after and/or before are + themselves occurrences. With inc=True, they will be included in the + list, if they are found in the recurrence set. """ + if self._cache_complete: + gen = self._cache + else: + gen = self + started = False + l = [] + if inc: + for i in gen: + if i > before: + break + elif not started: + if i >= after: + started = True + l.append(i) + else: + l.append(i) + else: + for i in gen: + if i >= before: + break + elif not started: + if i > after: + started = True + l.append(i) + else: + l.append(i) + return l + + +class rrule(rrulebase): + """ + That's the base of the rrule operation. It accepts all the keywords + defined in the RFC as its constructor parameters (except byday, + which was renamed to byweekday) and more. The constructor prototype is:: + + rrule(freq) + + Where freq must be one of YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, + or SECONDLY. + + .. note:: + Per RFC section 3.3.10, recurrence instances falling on invalid dates + and times are ignored rather than coerced: + + Recurrence rules may generate recurrence instances with an invalid + date (e.g., February 30) or nonexistent local time (e.g., 1:30 AM + on a day where the local time is moved forward by an hour at 1:00 + AM). Such recurrence instances MUST be ignored and MUST NOT be + counted as part of the recurrence set. + + This can lead to possibly surprising behavior when, for example, the + start date occurs at the end of the month: + + >>> from dateutil.rrule import rrule, MONTHLY + >>> from datetime import datetime + >>> start_date = datetime(2014, 12, 31) + >>> list(rrule(freq=MONTHLY, count=4, dtstart=start_date)) + ... # doctest: +NORMALIZE_WHITESPACE + [datetime.datetime(2014, 12, 31, 0, 0), + datetime.datetime(2015, 1, 31, 0, 0), + datetime.datetime(2015, 3, 31, 0, 0), + datetime.datetime(2015, 5, 31, 0, 0)] + + Additionally, it supports the following keyword arguments: + + :param dtstart: + The recurrence start. Besides being the base for the recurrence, + missing parameters in the final recurrence instances will also be + extracted from this date. If not given, datetime.now() will be used + instead. + :param interval: + The interval between each freq iteration. For example, when using + YEARLY, an interval of 2 means once every two years, but with HOURLY, + it means once every two hours. The default interval is 1. + :param wkst: + The week start day. Must be one of the MO, TU, WE constants, or an + integer, specifying the first day of the week. This will affect + recurrences based on weekly periods. The default week start is got + from calendar.firstweekday(), and may be modified by + calendar.setfirstweekday(). + :param count: + If given, this determines how many occurrences will be generated. + + .. note:: + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. + :param until: + If given, this must be a datetime instance specifying the upper-bound + limit of the recurrence. The last recurrence in the rule is the greatest + datetime that is less than or equal to the value specified in the + ``until`` parameter. + + .. note:: + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. + :param bysetpos: + If given, it must be either an integer, or a sequence of integers, + positive or negative. Each given integer will specify an occurrence + number, corresponding to the nth occurrence of the rule inside the + frequency period. For example, a bysetpos of -1 if combined with a + MONTHLY frequency, and a byweekday of (MO, TU, WE, TH, FR), will + result in the last work day of every month. + :param bymonth: + If given, it must be either an integer, or a sequence of integers, + meaning the months to apply the recurrence to. + :param bymonthday: + If given, it must be either an integer, or a sequence of integers, + meaning the month days to apply the recurrence to. + :param byyearday: + If given, it must be either an integer, or a sequence of integers, + meaning the year days to apply the recurrence to. + :param byeaster: + If given, it must be either an integer, or a sequence of integers, + positive or negative. Each integer will define an offset from the + Easter Sunday. Passing the offset 0 to byeaster will yield the Easter + Sunday itself. This is an extension to the RFC specification. + :param byweekno: + If given, it must be either an integer, or a sequence of integers, + meaning the week numbers to apply the recurrence to. Week numbers + have the meaning described in ISO8601, that is, the first week of + the year is that containing at least four days of the new year. + :param byweekday: + If given, it must be either an integer (0 == MO), a sequence of + integers, one of the weekday constants (MO, TU, etc), or a sequence + of these constants. When given, these variables will define the + weekdays where the recurrence will be applied. It's also possible to + use an argument n for the weekday instances, which will mean the nth + occurrence of this weekday in the period. For example, with MONTHLY, + or with YEARLY and BYMONTH, using FR(+1) in byweekday will specify the + first friday of the month where the recurrence happens. Notice that in + the RFC documentation, this is specified as BYDAY, but was renamed to + avoid the ambiguity of that keyword. + :param byhour: + If given, it must be either an integer, or a sequence of integers, + meaning the hours to apply the recurrence to. + :param byminute: + If given, it must be either an integer, or a sequence of integers, + meaning the minutes to apply the recurrence to. + :param bysecond: + If given, it must be either an integer, or a sequence of integers, + meaning the seconds to apply the recurrence to. + :param cache: + If given, it must be a boolean value specifying to enable or disable + caching of results. If you will use the same rrule instance multiple + times, enabling caching will improve the performance considerably. + """ + def __init__(self, freq, dtstart=None, + interval=1, wkst=None, count=None, until=None, bysetpos=None, + bymonth=None, bymonthday=None, byyearday=None, byeaster=None, + byweekno=None, byweekday=None, + byhour=None, byminute=None, bysecond=None, + cache=False): + super(rrule, self).__init__(cache) + global easter + if not dtstart: + if until and until.tzinfo: + dtstart = datetime.datetime.now(tz=until.tzinfo).replace(microsecond=0) + else: + dtstart = datetime.datetime.now().replace(microsecond=0) + elif not isinstance(dtstart, datetime.datetime): + dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) + else: + dtstart = dtstart.replace(microsecond=0) + self._dtstart = dtstart + self._tzinfo = dtstart.tzinfo + self._freq = freq + self._interval = interval + self._count = count + + # Cache the original byxxx rules, if they are provided, as the _byxxx + # attributes do not necessarily map to the inputs, and this can be + # a problem in generating the strings. Only store things if they've + # been supplied (the string retrieval will just use .get()) + self._original_rule = {} + + if until and not isinstance(until, datetime.datetime): + until = datetime.datetime.fromordinal(until.toordinal()) + self._until = until + + if self._dtstart and self._until: + if (self._dtstart.tzinfo is not None) != (self._until.tzinfo is not None): + # According to RFC5545 Section 3.3.10: + # https://tools.ietf.org/html/rfc5545#section-3.3.10 + # + # > If the "DTSTART" property is specified as a date with UTC + # > time or a date with local time and time zone reference, + # > then the UNTIL rule part MUST be specified as a date with + # > UTC time. + raise ValueError( + 'RRULE UNTIL values must be specified in UTC when DTSTART ' + 'is timezone-aware' + ) + + if count is not None and until: + warn("Using both 'count' and 'until' is inconsistent with RFC 5545" + " and has been deprecated in dateutil. Future versions will " + "raise an error.", DeprecationWarning) + + if wkst is None: + self._wkst = calendar.firstweekday() + elif isinstance(wkst, integer_types): + self._wkst = wkst + else: + self._wkst = wkst.weekday + + if bysetpos is None: + self._bysetpos = None + elif isinstance(bysetpos, integer_types): + if bysetpos == 0 or not (-366 <= bysetpos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + self._bysetpos = (bysetpos,) + else: + self._bysetpos = tuple(bysetpos) + for pos in self._bysetpos: + if pos == 0 or not (-366 <= pos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + + if self._bysetpos: + self._original_rule['bysetpos'] = self._bysetpos + + if (byweekno is None and byyearday is None and bymonthday is None and + byweekday is None and byeaster is None): + if freq == YEARLY: + if bymonth is None: + bymonth = dtstart.month + self._original_rule['bymonth'] = None + bymonthday = dtstart.day + self._original_rule['bymonthday'] = None + elif freq == MONTHLY: + bymonthday = dtstart.day + self._original_rule['bymonthday'] = None + elif freq == WEEKLY: + byweekday = dtstart.weekday() + self._original_rule['byweekday'] = None + + # bymonth + if bymonth is None: + self._bymonth = None + else: + if isinstance(bymonth, integer_types): + bymonth = (bymonth,) + + self._bymonth = tuple(sorted(set(bymonth))) + + if 'bymonth' not in self._original_rule: + self._original_rule['bymonth'] = self._bymonth + + # byyearday + if byyearday is None: + self._byyearday = None + else: + if isinstance(byyearday, integer_types): + byyearday = (byyearday,) + + self._byyearday = tuple(sorted(set(byyearday))) + self._original_rule['byyearday'] = self._byyearday + + # byeaster + if byeaster is not None: + if not easter: + from dateutil import easter + if isinstance(byeaster, integer_types): + self._byeaster = (byeaster,) + else: + self._byeaster = tuple(sorted(byeaster)) + + self._original_rule['byeaster'] = self._byeaster + else: + self._byeaster = None + + # bymonthday + if bymonthday is None: + self._bymonthday = () + self._bynmonthday = () + else: + if isinstance(bymonthday, integer_types): + bymonthday = (bymonthday,) + + bymonthday = set(bymonthday) # Ensure it's unique + + self._bymonthday = tuple(sorted(x for x in bymonthday if x > 0)) + self._bynmonthday = tuple(sorted(x for x in bymonthday if x < 0)) + + # Storing positive numbers first, then negative numbers + if 'bymonthday' not in self._original_rule: + self._original_rule['bymonthday'] = tuple( + itertools.chain(self._bymonthday, self._bynmonthday)) + + # byweekno + if byweekno is None: + self._byweekno = None + else: + if isinstance(byweekno, integer_types): + byweekno = (byweekno,) + + self._byweekno = tuple(sorted(set(byweekno))) + + self._original_rule['byweekno'] = self._byweekno + + # byweekday / bynweekday + if byweekday is None: + self._byweekday = None + self._bynweekday = None + else: + # If it's one of the valid non-sequence types, convert to a + # single-element sequence before the iterator that builds the + # byweekday set. + if isinstance(byweekday, integer_types) or hasattr(byweekday, "n"): + byweekday = (byweekday,) + + self._byweekday = set() + self._bynweekday = set() + for wday in byweekday: + if isinstance(wday, integer_types): + self._byweekday.add(wday) + elif not wday.n or freq > MONTHLY: + self._byweekday.add(wday.weekday) + else: + self._bynweekday.add((wday.weekday, wday.n)) + + if not self._byweekday: + self._byweekday = None + elif not self._bynweekday: + self._bynweekday = None + + if self._byweekday is not None: + self._byweekday = tuple(sorted(self._byweekday)) + orig_byweekday = [weekday(x) for x in self._byweekday] + else: + orig_byweekday = () + + if self._bynweekday is not None: + self._bynweekday = tuple(sorted(self._bynweekday)) + orig_bynweekday = [weekday(*x) for x in self._bynweekday] + else: + orig_bynweekday = () + + if 'byweekday' not in self._original_rule: + self._original_rule['byweekday'] = tuple(itertools.chain( + orig_byweekday, orig_bynweekday)) + + # byhour + if byhour is None: + if freq < HOURLY: + self._byhour = {dtstart.hour} + else: + self._byhour = None + else: + if isinstance(byhour, integer_types): + byhour = (byhour,) + + if freq == HOURLY: + self._byhour = self.__construct_byset(start=dtstart.hour, + byxxx=byhour, + base=24) + else: + self._byhour = set(byhour) + + self._byhour = tuple(sorted(self._byhour)) + self._original_rule['byhour'] = self._byhour + + # byminute + if byminute is None: + if freq < MINUTELY: + self._byminute = {dtstart.minute} + else: + self._byminute = None + else: + if isinstance(byminute, integer_types): + byminute = (byminute,) + + if freq == MINUTELY: + self._byminute = self.__construct_byset(start=dtstart.minute, + byxxx=byminute, + base=60) + else: + self._byminute = set(byminute) + + self._byminute = tuple(sorted(self._byminute)) + self._original_rule['byminute'] = self._byminute + + # bysecond + if bysecond is None: + if freq < SECONDLY: + self._bysecond = ((dtstart.second,)) + else: + self._bysecond = None + else: + if isinstance(bysecond, integer_types): + bysecond = (bysecond,) + + self._bysecond = set(bysecond) + + if freq == SECONDLY: + self._bysecond = self.__construct_byset(start=dtstart.second, + byxxx=bysecond, + base=60) + else: + self._bysecond = set(bysecond) + + self._bysecond = tuple(sorted(self._bysecond)) + self._original_rule['bysecond'] = self._bysecond + + if self._freq >= HOURLY: + self._timeset = None + else: + self._timeset = [] + for hour in self._byhour: + for minute in self._byminute: + for second in self._bysecond: + self._timeset.append( + datetime.time(hour, minute, second, + tzinfo=self._tzinfo)) + self._timeset.sort() + self._timeset = tuple(self._timeset) + + def __str__(self): + """ + Output a string that would generate this RRULE if passed to rrulestr. + This is mostly compatible with RFC5545, except for the + dateutil-specific extension BYEASTER. + """ + + output = [] + h, m, s = [None] * 3 + if self._dtstart: + output.append(self._dtstart.strftime('DTSTART:%Y%m%dT%H%M%S')) + h, m, s = self._dtstart.timetuple()[3:6] + + parts = ['FREQ=' + FREQNAMES[self._freq]] + if self._interval != 1: + parts.append('INTERVAL=' + str(self._interval)) + + if self._wkst: + parts.append('WKST=' + repr(weekday(self._wkst))[0:2]) + + if self._count is not None: + parts.append('COUNT=' + str(self._count)) + + if self._until: + parts.append(self._until.strftime('UNTIL=%Y%m%dT%H%M%S')) + + if self._original_rule.get('byweekday') is not None: + # The str() method on weekday objects doesn't generate + # RFC5545-compliant strings, so we should modify that. + original_rule = dict(self._original_rule) + wday_strings = [] + for wday in original_rule['byweekday']: + if wday.n: + wday_strings.append('{n:+d}{wday}'.format( + n=wday.n, + wday=repr(wday)[0:2])) + else: + wday_strings.append(repr(wday)) + + original_rule['byweekday'] = wday_strings + else: + original_rule = self._original_rule + + partfmt = '{name}={vals}' + for name, key in [('BYSETPOS', 'bysetpos'), + ('BYMONTH', 'bymonth'), + ('BYMONTHDAY', 'bymonthday'), + ('BYYEARDAY', 'byyearday'), + ('BYWEEKNO', 'byweekno'), + ('BYDAY', 'byweekday'), + ('BYHOUR', 'byhour'), + ('BYMINUTE', 'byminute'), + ('BYSECOND', 'bysecond'), + ('BYEASTER', 'byeaster')]: + value = original_rule.get(key) + if value: + parts.append(partfmt.format(name=name, vals=(','.join(str(v) + for v in value)))) + + output.append('RRULE:' + ';'.join(parts)) + return '\n'.join(output) + + def replace(self, **kwargs): + """Return new rrule with same attributes except for those attributes given new + values by whichever keyword arguments are specified.""" + new_kwargs = {"interval": self._interval, + "count": self._count, + "dtstart": self._dtstart, + "freq": self._freq, + "until": self._until, + "wkst": self._wkst, + "cache": False if self._cache is None else True } + new_kwargs.update(self._original_rule) + new_kwargs.update(kwargs) + return rrule(**new_kwargs) + + def _iter(self): + year, month, day, hour, minute, second, weekday, yearday, _ = \ + self._dtstart.timetuple() + + # Some local variables to speed things up a bit + freq = self._freq + interval = self._interval + wkst = self._wkst + until = self._until + bymonth = self._bymonth + byweekno = self._byweekno + byyearday = self._byyearday + byweekday = self._byweekday + byeaster = self._byeaster + bymonthday = self._bymonthday + bynmonthday = self._bynmonthday + bysetpos = self._bysetpos + byhour = self._byhour + byminute = self._byminute + bysecond = self._bysecond + + ii = _iterinfo(self) + ii.rebuild(year, month) + + getdayset = {YEARLY: ii.ydayset, + MONTHLY: ii.mdayset, + WEEKLY: ii.wdayset, + DAILY: ii.ddayset, + HOURLY: ii.ddayset, + MINUTELY: ii.ddayset, + SECONDLY: ii.ddayset}[freq] + + if freq < HOURLY: + timeset = self._timeset + else: + gettimeset = {HOURLY: ii.htimeset, + MINUTELY: ii.mtimeset, + SECONDLY: ii.stimeset}[freq] + if ((freq >= HOURLY and + self._byhour and hour not in self._byhour) or + (freq >= MINUTELY and + self._byminute and minute not in self._byminute) or + (freq >= SECONDLY and + self._bysecond and second not in self._bysecond)): + timeset = () + else: + timeset = gettimeset(hour, minute, second) + + total = 0 + count = self._count + while True: + # Get dayset with the right frequency + dayset, start, end = getdayset(year, month, day) + + # Do the "hard" work ;-) + filtered = False + for i in dayset[start:end]: + if ((bymonth and ii.mmask[i] not in bymonth) or + (byweekno and not ii.wnomask[i]) or + (byweekday and ii.wdaymask[i] not in byweekday) or + (ii.nwdaymask and not ii.nwdaymask[i]) or + (byeaster and not ii.eastermask[i]) or + ((bymonthday or bynmonthday) and + ii.mdaymask[i] not in bymonthday and + ii.nmdaymask[i] not in bynmonthday) or + (byyearday and + ((i < ii.yearlen and i+1 not in byyearday and + -ii.yearlen+i not in byyearday) or + (i >= ii.yearlen and i+1-ii.yearlen not in byyearday and + -ii.nextyearlen+i-ii.yearlen not in byyearday)))): + dayset[i] = None + filtered = True + + # Output results + if bysetpos and timeset: + poslist = [] + for pos in bysetpos: + if pos < 0: + daypos, timepos = divmod(pos, len(timeset)) + else: + daypos, timepos = divmod(pos-1, len(timeset)) + try: + i = [x for x in dayset[start:end] + if x is not None][daypos] + time = timeset[timepos] + except IndexError: + pass + else: + date = datetime.date.fromordinal(ii.yearordinal+i) + res = datetime.datetime.combine(date, time) + if res not in poslist: + poslist.append(res) + poslist.sort() + for res in poslist: + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + if count is not None: + count -= 1 + if count < 0: + self._len = total + return + total += 1 + yield res + else: + for i in dayset[start:end]: + if i is not None: + date = datetime.date.fromordinal(ii.yearordinal + i) + for time in timeset: + res = datetime.datetime.combine(date, time) + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + if count is not None: + count -= 1 + if count < 0: + self._len = total + return + + total += 1 + yield res + + # Handle frequency and interval + fixday = False + if freq == YEARLY: + year += interval + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == MONTHLY: + month += interval + if month > 12: + div, mod = divmod(month, 12) + month = mod + year += div + if month == 0: + month = 12 + year -= 1 + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == WEEKLY: + if wkst > weekday: + day += -(weekday+1+(6-wkst))+self._interval*7 + else: + day += -(weekday-wkst)+self._interval*7 + weekday = wkst + fixday = True + elif freq == DAILY: + day += interval + fixday = True + elif freq == HOURLY: + if filtered: + # Jump to one iteration before next day + hour += ((23-hour)//interval)*interval + + if byhour: + ndays, hour = self.__mod_distance(value=hour, + byxxx=self._byhour, + base=24) + else: + ndays, hour = divmod(hour+interval, 24) + + if ndays: + day += ndays + fixday = True + + timeset = gettimeset(hour, minute, second) + elif freq == MINUTELY: + if filtered: + # Jump to one iteration before next day + minute += ((1439-(hour*60+minute))//interval)*interval + + valid = False + rep_rate = (24*60) + for j in range(rep_rate // gcd(interval, rep_rate)): + if byminute: + nhours, minute = \ + self.__mod_distance(value=minute, + byxxx=self._byminute, + base=60) + else: + nhours, minute = divmod(minute+interval, 60) + + div, hour = divmod(hour+nhours, 24) + if div: + day += div + fixday = True + filtered = False + + if not byhour or hour in byhour: + valid = True + break + + if not valid: + raise ValueError('Invalid combination of interval and ' + + 'byhour resulting in empty rule.') + + timeset = gettimeset(hour, minute, second) + elif freq == SECONDLY: + if filtered: + # Jump to one iteration before next day + second += (((86399 - (hour * 3600 + minute * 60 + second)) + // interval) * interval) + + rep_rate = (24 * 3600) + valid = False + for j in range(0, rep_rate // gcd(interval, rep_rate)): + if bysecond: + nminutes, second = \ + self.__mod_distance(value=second, + byxxx=self._bysecond, + base=60) + else: + nminutes, second = divmod(second+interval, 60) + + div, minute = divmod(minute+nminutes, 60) + if div: + hour += div + div, hour = divmod(hour, 24) + if div: + day += div + fixday = True + + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute) and + (not bysecond or second in bysecond)): + valid = True + break + + if not valid: + raise ValueError('Invalid combination of interval, ' + + 'byhour and byminute resulting in empty' + + ' rule.') + + timeset = gettimeset(hour, minute, second) + + if fixday and day > 28: + daysinmonth = calendar.monthrange(year, month)[1] + if day > daysinmonth: + while day > daysinmonth: + day -= daysinmonth + month += 1 + if month == 13: + month = 1 + year += 1 + if year > datetime.MAXYEAR: + self._len = total + return + daysinmonth = calendar.monthrange(year, month)[1] + ii.rebuild(year, month) + + def __construct_byset(self, start, byxxx, base): + """ + If a `BYXXX` sequence is passed to the constructor at the same level as + `FREQ` (e.g. `FREQ=HOURLY,BYHOUR={2,4,7},INTERVAL=3`), there are some + specifications which cannot be reached given some starting conditions. + + This occurs whenever the interval is not coprime with the base of a + given unit and the difference between the starting position and the + ending position is not coprime with the greatest common denominator + between the interval and the base. For example, with a FREQ of hourly + starting at 17:00 and an interval of 4, the only valid values for + BYHOUR would be {21, 1, 5, 9, 13, 17}, because 4 and 24 are not + coprime. + + :param start: + Specifies the starting position. + :param byxxx: + An iterable containing the list of allowed values. + :param base: + The largest allowable value for the specified frequency (e.g. + 24 hours, 60 minutes). + + This does not preserve the type of the iterable, returning a set, since + the values should be unique and the order is irrelevant, this will + speed up later lookups. + + In the event of an empty set, raises a :exception:`ValueError`, as this + results in an empty rrule. + """ + + cset = set() + + # Support a single byxxx value. + if isinstance(byxxx, integer_types): + byxxx = (byxxx, ) + + for num in byxxx: + i_gcd = gcd(self._interval, base) + # Use divmod rather than % because we need to wrap negative nums. + if i_gcd == 1 or divmod(num - start, i_gcd)[1] == 0: + cset.add(num) + + if len(cset) == 0: + raise ValueError("Invalid rrule byxxx generates an empty set.") + + return cset + + def __mod_distance(self, value, byxxx, base): + """ + Calculates the next value in a sequence where the `FREQ` parameter is + specified along with a `BYXXX` parameter at the same "level" + (e.g. `HOURLY` specified with `BYHOUR`). + + :param value: + The old value of the component. + :param byxxx: + The `BYXXX` set, which should have been generated by + `rrule._construct_byset`, or something else which checks that a + valid rule is present. + :param base: + The largest allowable value for the specified frequency (e.g. + 24 hours, 60 minutes). + + If a valid value is not found after `base` iterations (the maximum + number before the sequence would start to repeat), this raises a + :exception:`ValueError`, as no valid values were found. + + This returns a tuple of `divmod(n*interval, base)`, where `n` is the + smallest number of `interval` repetitions until the next specified + value in `byxxx` is found. + """ + accumulator = 0 + for ii in range(1, base + 1): + # Using divmod() over % to account for negative intervals + div, value = divmod(value + self._interval, base) + accumulator += div + if value in byxxx: + return (accumulator, value) + + +class _iterinfo(object): + __slots__ = ["rrule", "lastyear", "lastmonth", + "yearlen", "nextyearlen", "yearordinal", "yearweekday", + "mmask", "mrange", "mdaymask", "nmdaymask", + "wdaymask", "wnomask", "nwdaymask", "eastermask"] + + def __init__(self, rrule): + for attr in self.__slots__: + setattr(self, attr, None) + self.rrule = rrule + + def rebuild(self, year, month): + # Every mask is 7 days longer to handle cross-year weekly periods. + rr = self.rrule + if year != self.lastyear: + self.yearlen = 365 + calendar.isleap(year) + self.nextyearlen = 365 + calendar.isleap(year + 1) + firstyday = datetime.date(year, 1, 1) + self.yearordinal = firstyday.toordinal() + self.yearweekday = firstyday.weekday() + + wday = datetime.date(year, 1, 1).weekday() + if self.yearlen == 365: + self.mmask = M365MASK + self.mdaymask = MDAY365MASK + self.nmdaymask = NMDAY365MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M365RANGE + else: + self.mmask = M366MASK + self.mdaymask = MDAY366MASK + self.nmdaymask = NMDAY366MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M366RANGE + + if not rr._byweekno: + self.wnomask = None + else: + self.wnomask = [0]*(self.yearlen+7) + # no1wkst = firstwkst = self.wdaymask.index(rr._wkst) + no1wkst = firstwkst = (7-self.yearweekday+rr._wkst) % 7 + if no1wkst >= 4: + no1wkst = 0 + # Number of days in the year, plus the days we got + # from last year. + wyearlen = self.yearlen+(self.yearweekday-rr._wkst) % 7 + else: + # Number of days in the year, minus the days we + # left in last year. + wyearlen = self.yearlen-no1wkst + div, mod = divmod(wyearlen, 7) + numweeks = div+mod//4 + for n in rr._byweekno: + if n < 0: + n += numweeks+1 + if not (0 < n <= numweeks): + continue + if n > 1: + i = no1wkst+(n-1)*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + else: + i = no1wkst + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if 1 in rr._byweekno: + # Check week number 1 of next year as well + # TODO: Check -numweeks for next year. + i = no1wkst+numweeks*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + if i < self.yearlen: + # If week starts in next year, we + # don't care about it. + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if no1wkst: + # Check last week number of last year as + # well. If no1wkst is 0, either the year + # started on week start, or week number 1 + # got days from last year, so there are no + # days from last year's last week number in + # this year. + if -1 not in rr._byweekno: + lyearweekday = datetime.date(year-1, 1, 1).weekday() + lno1wkst = (7-lyearweekday+rr._wkst) % 7 + lyearlen = 365+calendar.isleap(year-1) + if lno1wkst >= 4: + lno1wkst = 0 + lnumweeks = 52+(lyearlen + + (lyearweekday-rr._wkst) % 7) % 7//4 + else: + lnumweeks = 52+(self.yearlen-no1wkst) % 7//4 + else: + lnumweeks = -1 + if lnumweeks in rr._byweekno: + for i in range(no1wkst): + self.wnomask[i] = 1 + + if (rr._bynweekday and (month != self.lastmonth or + year != self.lastyear)): + ranges = [] + if rr._freq == YEARLY: + if rr._bymonth: + for month in rr._bymonth: + ranges.append(self.mrange[month-1:month+1]) + else: + ranges = [(0, self.yearlen)] + elif rr._freq == MONTHLY: + ranges = [self.mrange[month-1:month+1]] + if ranges: + # Weekly frequency won't get here, so we may not + # care about cross-year weekly periods. + self.nwdaymask = [0]*self.yearlen + for first, last in ranges: + last -= 1 + for wday, n in rr._bynweekday: + if n < 0: + i = last+(n+1)*7 + i -= (self.wdaymask[i]-wday) % 7 + else: + i = first+(n-1)*7 + i += (7-self.wdaymask[i]+wday) % 7 + if first <= i <= last: + self.nwdaymask[i] = 1 + + if rr._byeaster: + self.eastermask = [0]*(self.yearlen+7) + eyday = easter.easter(year).toordinal()-self.yearordinal + for offset in rr._byeaster: + self.eastermask[eyday+offset] = 1 + + self.lastyear = year + self.lastmonth = month + + def ydayset(self, year, month, day): + return list(range(self.yearlen)), 0, self.yearlen + + def mdayset(self, year, month, day): + dset = [None]*self.yearlen + start, end = self.mrange[month-1:month+1] + for i in range(start, end): + dset[i] = i + return dset, start, end + + def wdayset(self, year, month, day): + # We need to handle cross-year weeks here. + dset = [None]*(self.yearlen+7) + i = datetime.date(year, month, day).toordinal()-self.yearordinal + start = i + for j in range(7): + dset[i] = i + i += 1 + # if (not (0 <= i < self.yearlen) or + # self.wdaymask[i] == self.rrule._wkst): + # This will cross the year boundary, if necessary. + if self.wdaymask[i] == self.rrule._wkst: + break + return dset, start, i + + def ddayset(self, year, month, day): + dset = [None] * self.yearlen + i = datetime.date(year, month, day).toordinal() - self.yearordinal + dset[i] = i + return dset, i, i + 1 + + def htimeset(self, hour, minute, second): + tset = [] + rr = self.rrule + for minute in rr._byminute: + for second in rr._bysecond: + tset.append(datetime.time(hour, minute, second, + tzinfo=rr._tzinfo)) + tset.sort() + return tset + + def mtimeset(self, hour, minute, second): + tset = [] + rr = self.rrule + for second in rr._bysecond: + tset.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) + tset.sort() + return tset + + def stimeset(self, hour, minute, second): + return (datetime.time(hour, minute, second, + tzinfo=self.rrule._tzinfo),) + + +class rruleset(rrulebase): + """ The rruleset type allows more complex recurrence setups, mixing + multiple rules, dates, exclusion rules, and exclusion dates. The type + constructor takes the following keyword arguments: + + :param cache: If True, caching of results will be enabled, improving + performance of multiple queries considerably. """ + + class _genitem(object): + def __init__(self, genlist, gen): + try: + self.dt = advance_iterator(gen) + genlist.append(self) + except StopIteration: + pass + self.genlist = genlist + self.gen = gen + + def __next__(self): + try: + self.dt = advance_iterator(self.gen) + except StopIteration: + if self.genlist[0] is self: + heapq.heappop(self.genlist) + else: + self.genlist.remove(self) + heapq.heapify(self.genlist) + + next = __next__ + + def __lt__(self, other): + return self.dt < other.dt + + def __gt__(self, other): + return self.dt > other.dt + + def __eq__(self, other): + return self.dt == other.dt + + def __ne__(self, other): + return self.dt != other.dt + + def __init__(self, cache=False): + super(rruleset, self).__init__(cache) + self._rrule = [] + self._rdate = [] + self._exrule = [] + self._exdate = [] + + @_invalidates_cache + def rrule(self, rrule): + """ Include the given :py:class:`rrule` instance in the recurrence set + generation. """ + self._rrule.append(rrule) + + @_invalidates_cache + def rdate(self, rdate): + """ Include the given :py:class:`datetime` instance in the recurrence + set generation. """ + self._rdate.append(rdate) + + @_invalidates_cache + def exrule(self, exrule): + """ Include the given rrule instance in the recurrence set exclusion + list. Dates which are part of the given recurrence rules will not + be generated, even if some inclusive rrule or rdate matches them. + """ + self._exrule.append(exrule) + + @_invalidates_cache + def exdate(self, exdate): + """ Include the given datetime instance in the recurrence set + exclusion list. Dates included that way will not be generated, + even if some inclusive rrule or rdate matches them. """ + self._exdate.append(exdate) + + def _iter(self): + rlist = [] + self._rdate.sort() + self._genitem(rlist, iter(self._rdate)) + for gen in [iter(x) for x in self._rrule]: + self._genitem(rlist, gen) + exlist = [] + self._exdate.sort() + self._genitem(exlist, iter(self._exdate)) + for gen in [iter(x) for x in self._exrule]: + self._genitem(exlist, gen) + lastdt = None + total = 0 + heapq.heapify(rlist) + heapq.heapify(exlist) + while rlist: + ritem = rlist[0] + if not lastdt or lastdt != ritem.dt: + while exlist and exlist[0] < ritem: + exitem = exlist[0] + advance_iterator(exitem) + if exlist and exlist[0] is exitem: + heapq.heapreplace(exlist, exitem) + if not exlist or ritem != exlist[0]: + total += 1 + yield ritem.dt + lastdt = ritem.dt + advance_iterator(ritem) + if rlist and rlist[0] is ritem: + heapq.heapreplace(rlist, ritem) + self._len = total + + + + +class _rrulestr(object): + """ Parses a string representation of a recurrence rule or set of + recurrence rules. + + :param s: + Required, a string defining one or more recurrence rules. + + :param dtstart: + If given, used as the default recurrence start if not specified in the + rule string. + + :param cache: + If set ``True`` caching of results will be enabled, improving + performance of multiple queries considerably. + + :param unfold: + If set ``True`` indicates that a rule string is split over more + than one line and should be joined before processing. + + :param forceset: + If set ``True`` forces a :class:`dateutil.rrule.rruleset` to + be returned. + + :param compatible: + If set ``True`` forces ``unfold`` and ``forceset`` to be ``True``. + + :param ignoretz: + If set ``True``, time zones in parsed strings are ignored and a naive + :class:`datetime.datetime` object is returned. + + :param tzids: + If given, a callable or mapping used to retrieve a + :class:`datetime.tzinfo` from a string representation. + Defaults to :func:`dateutil.tz.gettz`. + + :param tzinfos: + Additional time zone names / aliases which may be present in a string + representation. See :func:`dateutil.parser.parse` for more + information. + + :return: + Returns a :class:`dateutil.rrule.rruleset` or + :class:`dateutil.rrule.rrule` + """ + + _freq_map = {"YEARLY": YEARLY, + "MONTHLY": MONTHLY, + "WEEKLY": WEEKLY, + "DAILY": DAILY, + "HOURLY": HOURLY, + "MINUTELY": MINUTELY, + "SECONDLY": SECONDLY} + + _weekday_map = {"MO": 0, "TU": 1, "WE": 2, "TH": 3, + "FR": 4, "SA": 5, "SU": 6} + + def _handle_int(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = int(value) + + def _handle_int_list(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = [int(x) for x in value.split(',')] + + _handle_INTERVAL = _handle_int + _handle_COUNT = _handle_int + _handle_BYSETPOS = _handle_int_list + _handle_BYMONTH = _handle_int_list + _handle_BYMONTHDAY = _handle_int_list + _handle_BYYEARDAY = _handle_int_list + _handle_BYEASTER = _handle_int_list + _handle_BYWEEKNO = _handle_int_list + _handle_BYHOUR = _handle_int_list + _handle_BYMINUTE = _handle_int_list + _handle_BYSECOND = _handle_int_list + + def _handle_FREQ(self, rrkwargs, name, value, **kwargs): + rrkwargs["freq"] = self._freq_map[value] + + def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): + global parser + if not parser: + from dateutil import parser + try: + rrkwargs["until"] = parser.parse(value, + ignoretz=kwargs.get("ignoretz"), + tzinfos=kwargs.get("tzinfos")) + except ValueError: + raise ValueError("invalid until date") + + def _handle_WKST(self, rrkwargs, name, value, **kwargs): + rrkwargs["wkst"] = self._weekday_map[value] + + def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwargs): + """ + Two ways to specify this: +1MO or MO(+1) + """ + l = [] + for wday in value.split(','): + if '(' in wday: + # If it's of the form TH(+1), etc. + splt = wday.split('(') + w = splt[0] + n = int(splt[1][:-1]) + elif len(wday): + # If it's of the form +1MO + for i in range(len(wday)): + if wday[i] not in '+-0123456789': + break + n = wday[:i] or None + w = wday[i:] + if n: + n = int(n) + else: + raise ValueError("Invalid (empty) BYDAY specification.") + + l.append(weekdays[self._weekday_map[w]](n)) + rrkwargs["byweekday"] = l + + _handle_BYDAY = _handle_BYWEEKDAY + + def _parse_rfc_rrule(self, line, + dtstart=None, + cache=False, + ignoretz=False, + tzinfos=None): + if line.find(':') != -1: + name, value = line.split(':') + if name != "RRULE": + raise ValueError("unknown parameter name") + else: + value = line + rrkwargs = {} + for pair in value.split(';'): + name, value = pair.split('=') + name = name.upper() + value = value.upper() + try: + getattr(self, "_handle_"+name)(rrkwargs, name, value, + ignoretz=ignoretz, + tzinfos=tzinfos) + except AttributeError: + raise ValueError("unknown parameter '%s'" % name) + except (KeyError, ValueError): + raise ValueError("invalid '%s': %s" % (name, value)) + return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + + def _parse_date_value(self, date_value, parms, rule_tzids, + ignoretz, tzids, tzinfos): + global parser + if not parser: + from dateutil import parser + + datevals = [] + value_found = False + TZID = None + + for parm in parms: + if parm.startswith("TZID="): + try: + tzkey = rule_tzids[parm.split('TZID=')[-1]] + except KeyError: + continue + if tzids is None: + from . import tz + tzlookup = tz.gettz + elif callable(tzids): + tzlookup = tzids + else: + tzlookup = getattr(tzids, 'get', None) + if tzlookup is None: + msg = ('tzids must be a callable, mapping, or None, ' + 'not %s' % tzids) + raise ValueError(msg) + + TZID = tzlookup(tzkey) + continue + + # RFC 5445 3.8.2.4: The VALUE parameter is optional, but may be found + # only once. + if parm not in {"VALUE=DATE-TIME", "VALUE=DATE"}: + raise ValueError("unsupported parm: " + parm) + else: + if value_found: + msg = ("Duplicate value parameter found in: " + parm) + raise ValueError(msg) + value_found = True + + for datestr in date_value.split(','): + date = parser.parse(datestr, ignoretz=ignoretz, tzinfos=tzinfos) + if TZID is not None: + if date.tzinfo is None: + date = date.replace(tzinfo=TZID) + else: + raise ValueError('DTSTART/EXDATE specifies multiple timezone') + datevals.append(date) + + return datevals + + def _parse_rfc(self, s, + dtstart=None, + cache=False, + unfold=False, + forceset=False, + compatible=False, + ignoretz=False, + tzids=None, + tzinfos=None): + global parser + if compatible: + forceset = True + unfold = True + + TZID_NAMES = dict(map( + lambda x: (x.upper(), x), + re.findall('TZID=(?P[^:]+):', s) + )) + s = s.upper() + if not s.strip(): + raise ValueError("empty string") + if unfold: + lines = s.splitlines() + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + else: + lines = s.split() + if (not forceset and len(lines) == 1 and (s.find(':') == -1 or + s.startswith('RRULE:'))): + return self._parse_rfc_rrule(lines[0], cache=cache, + dtstart=dtstart, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + rrulevals = [] + rdatevals = [] + exrulevals = [] + exdatevals = [] + for line in lines: + if not line: + continue + if line.find(':') == -1: + name = "RRULE" + value = line + else: + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0] + parms = parms[1:] + if name == "RRULE": + for parm in parms: + raise ValueError("unsupported RRULE parm: "+parm) + rrulevals.append(value) + elif name == "RDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError("unsupported RDATE parm: "+parm) + rdatevals.append(value) + elif name == "EXRULE": + for parm in parms: + raise ValueError("unsupported EXRULE parm: "+parm) + exrulevals.append(value) + elif name == "EXDATE": + exdatevals.extend( + self._parse_date_value(value, parms, + TZID_NAMES, ignoretz, + tzids, tzinfos) + ) + elif name == "DTSTART": + dtvals = self._parse_date_value(value, parms, TZID_NAMES, + ignoretz, tzids, tzinfos) + if len(dtvals) != 1: + raise ValueError("Multiple DTSTART values specified:" + + value) + dtstart = dtvals[0] + else: + raise ValueError("unsupported property: "+name) + if (forceset or len(rrulevals) > 1 or rdatevals + or exrulevals or exdatevals): + if not parser and (rdatevals or exdatevals): + from dateutil import parser + rset = rruleset(cache=cache) + for value in rrulevals: + rset.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in rdatevals: + for datestr in value.split(','): + rset.rdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exrulevals: + rset.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exdatevals: + rset.exdate(value) + if compatible and dtstart: + rset.rdate(dtstart) + return rset + else: + return self._parse_rfc_rrule(rrulevals[0], + dtstart=dtstart, + cache=cache, + ignoretz=ignoretz, + tzinfos=tzinfos) + + def __call__(self, s, **kwargs): + return self._parse_rfc(s, **kwargs) + + +rrulestr = _rrulestr() + +# vim:ts=4:sw=4:et diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__init__.py b/.venv/lib/python3.7/site-packages/dateutil/tz/__init__.py new file mode 100644 index 0000000..af1352c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tz/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from .tz import * +from .tz import __doc__ + +__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", + "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz", + "enfold", "datetime_ambiguous", "datetime_exists", + "resolve_imaginary", "UTC", "DeprecatedTzFormatWarning"] + + +class DeprecatedTzFormatWarning(Warning): + """Warning raised when time zones are parsed from deprecated formats.""" diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68c6f8af2663f254be404a4a20f6efbf8f8680cd GIT binary patch literal 663 zcmYLG&2H2%5Vn)uY)E(Mc7a20xh~Q+FMv=f2rj6XE<*Cfax+e9$+1)0Y1v%q!<2X6 zNpj`HD{#WjmSrT5$Mg5i=ebxcGUVm->Jffognos`KUsR?+#mbdD?orH+J-xlsKEqd z1Tjot3JJ_0g=dh#5zJu$&*2!Ba007(Nuo~(Ucl-B!HUPguGdv%xg#^zOImE@{Uu{uv#c)c0>GS`+hk6z+1yh z-vPG$M{OGBzA~ePs!Pw~Ac54mKQ{avM+5^R5nvKS zEbq1AHfM(CEi)lh8QtV?fX=HC*`8glCqqi9VxA2hGD;f_oecJz(%X*7eZ<5b?*}qr z!=w81u5e9Tw4&VzWgU}pbIa{DG_)_;ox9O$6Mm#~LKX+Z^#!Fu2}kK!yBj$i`Gz*~ wD#e%U=@9v)1gNk`-_wsVd*V1||Ht23p?XN)>}P%(+SvKnYaV4d!wJsfzY~DFjsO4v literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_common.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_common.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2039daacb6a6dc999c73906d257e623f3a70dc5 GIT binary patch literal 12219 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 aN=#O69X1bSo~>JrGiw|5*W8n95C0Pp!D$Ep literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_factories.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/_factories.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0e1e5b7aa58459db7b886103602f88d6f8e2cdd GIT binary patch literal 2860 zcmb_e&2!sC6yMd#viubc{UB|jm?>Wdk{n=$9y(Ac6D~|T&<AhX;+xOo7eoy+W(`gd;UAgzWXn^)7 z8r9DS)HX~yl0s%C-T|w1R|%=4_&iMv zn00RUl#E4!4_807Q1m;XND@&&BJU{~P(g+FB#fBTneajPpAw%$HQ2Cb+x-6YUYhS_ z(iC|@7hcdCUN69Vtc%eIe-(EiHi1RepCe9OSYkD%4 zO4Y!L4RJg*ocEb!Nv5qIt6gn_{YQAmyg5&@SZmJzAb;K2GNbX-fEOdU&5 zrLTKnlw=6$?}zGYmHvz!xpLslB7GIWld6uQ$~1|y3^Jt(w})FBCp#$CP+)1%(zue) zCheXLZQ&xo!sYQua&DWPj|wr#P;Yboa1v+p8JDT^YCDT6CK4lQ=Dalo6^Jm6P#(ZP!-Fk*EX#j(GoQ-!`Rz~%gf)Y<1( z4S936YQR7e`2yJ&*e(QfcQDY>oL57P*wyeYPz;$-2RqNOLxi6%pr*WLf?3^-hXTRq z?L5O%?Kf=wk&O419M}sFK=~%lCK4M+TI8`hu-8_1KBlZzc!2i$*(czTihP$Rak3}v zjpxsEold1f*4Yj)p-AAMIo$SbYwo}q|8#~9)mOoZ#;lMgAq~9gmDRnEd5p2+5Alu6 zy91a06@($BXXv4)*0FibydyI39mNa59EK&kMNAX5LpYpaYu{HtqBU$IZGM7=`2c#!SLAE*Eh&9C zF1E7`ZO@0EXZju6OmziGg@E^JUZ)LFJK4_2|hY)`Mldc6(;>%QiN-WpUtq-!js z7g?9CpMMVXrnLk6txyV2&=L1sUcC&nSKwOoqp+@U1Uc z0EG>q3&NYtsQ-^x3QN&%D2!4eChhvEEzU3qId&WY=cnk?d(PxBcNC^-5$-1)IRgHB z{@er~r}^Vv*2~%~$+MlD%bpU}pI`|zq7{~W2pA_b&#}aP8Z24jFIZ9o_EanZHUUfO zu%_l%5&}zdw1$o6u|)MCjDAzS4>xrK#TzJGquxSo1I3#tuwSZ86mNs5kWY2g9v3?O zfzQFO-o+<{9 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/tz.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/tz.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3fd1a76085709a64da3d3d25976609e47e1cf5c GIT binary patch literal 45244 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 EzhLnR(*OVf literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/win.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/tz/__pycache__/win.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3562c4e4def19d27eeb03638956d0e2f859f8477 GIT binary patch literal 11073 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 RSBvKSJ^cI0{4ebK{{l41I%@y` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/_common.py b/.venv/lib/python3.7/site-packages/dateutil/tz/_common.py new file mode 100644 index 0000000..e6ac118 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tz/_common.py @@ -0,0 +1,419 @@ +from six import PY2 + +from functools import wraps + +from datetime import datetime, timedelta, tzinfo + + +ZERO = timedelta(0) + +__all__ = ['tzname_in_python2', 'enfold'] + + +def tzname_in_python2(namefunc): + """Change unicode output into bytestrings in Python 2 + + tzname() API changed in Python 3. It used to return bytes, but was changed + to unicode strings + """ + if PY2: + @wraps(namefunc) + def adjust_encoding(*args, **kwargs): + name = namefunc(*args, **kwargs) + if name is not None: + name = name.encode() + + return name + + return adjust_encoding + else: + return namefunc + + +# The following is adapted from Alexander Belopolsky's tz library +# https://github.com/abalkin/tz +if hasattr(datetime, 'fold'): + # This is the pre-python 3.6 fold situation + def enfold(dt, fold=1): + """ + Provides a unified interface for assigning the ``fold`` attribute to + datetimes both before and after the implementation of PEP-495. + + :param fold: + The value for the ``fold`` attribute in the returned datetime. This + should be either 0 or 1. + + :return: + Returns an object for which ``getattr(dt, 'fold', 0)`` returns + ``fold`` for all versions of Python. In versions prior to + Python 3.6, this is a ``_DatetimeWithFold`` object, which is a + subclass of :py:class:`datetime.datetime` with the ``fold`` + attribute added, if ``fold`` is 1. + + .. versionadded:: 2.6.0 + """ + return dt.replace(fold=fold) + +else: + class _DatetimeWithFold(datetime): + """ + This is a class designed to provide a PEP 495-compliant interface for + Python versions before 3.6. It is used only for dates in a fold, so + the ``fold`` attribute is fixed at ``1``. + + .. versionadded:: 2.6.0 + """ + __slots__ = () + + def replace(self, *args, **kwargs): + """ + Return a datetime with the same attributes, except for those + attributes given new values by whichever keyword arguments are + specified. Note that tzinfo=None can be specified to create a naive + datetime from an aware datetime with no conversion of date and time + data. + + This is reimplemented in ``_DatetimeWithFold`` because pypy3 will + return a ``datetime.datetime`` even if ``fold`` is unchanged. + """ + argnames = ( + 'year', 'month', 'day', 'hour', 'minute', 'second', + 'microsecond', 'tzinfo' + ) + + for arg, argname in zip(args, argnames): + if argname in kwargs: + raise TypeError('Duplicate argument: {}'.format(argname)) + + kwargs[argname] = arg + + for argname in argnames: + if argname not in kwargs: + kwargs[argname] = getattr(self, argname) + + dt_class = self.__class__ if kwargs.get('fold', 1) else datetime + + return dt_class(**kwargs) + + @property + def fold(self): + return 1 + + def enfold(dt, fold=1): + """ + Provides a unified interface for assigning the ``fold`` attribute to + datetimes both before and after the implementation of PEP-495. + + :param fold: + The value for the ``fold`` attribute in the returned datetime. This + should be either 0 or 1. + + :return: + Returns an object for which ``getattr(dt, 'fold', 0)`` returns + ``fold`` for all versions of Python. In versions prior to + Python 3.6, this is a ``_DatetimeWithFold`` object, which is a + subclass of :py:class:`datetime.datetime` with the ``fold`` + attribute added, if ``fold`` is 1. + + .. versionadded:: 2.6.0 + """ + if getattr(dt, 'fold', 0) == fold: + return dt + + args = dt.timetuple()[:6] + args += (dt.microsecond, dt.tzinfo) + + if fold: + return _DatetimeWithFold(*args) + else: + return datetime(*args) + + +def _validate_fromutc_inputs(f): + """ + The CPython version of ``fromutc`` checks that the input is a ``datetime`` + object and that ``self`` is attached as its ``tzinfo``. + """ + @wraps(f) + def fromutc(self, dt): + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + return f(self, dt) + + return fromutc + + +class _tzinfo(tzinfo): + """ + Base class for all ``dateutil`` ``tzinfo`` objects. + """ + + def is_ambiguous(self, dt): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + + + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + + dt = dt.replace(tzinfo=self) + + wall_0 = enfold(dt, fold=0) + wall_1 = enfold(dt, fold=1) + + same_offset = wall_0.utcoffset() == wall_1.utcoffset() + same_dt = wall_0.replace(tzinfo=None) == wall_1.replace(tzinfo=None) + + return same_dt and not same_offset + + def _fold_status(self, dt_utc, dt_wall): + """ + Determine the fold status of a "wall" datetime, given a representation + of the same datetime as a (naive) UTC datetime. This is calculated based + on the assumption that ``dt.utcoffset() - dt.dst()`` is constant for all + datetimes, and that this offset is the actual number of hours separating + ``dt_utc`` and ``dt_wall``. + + :param dt_utc: + Representation of the datetime as UTC + + :param dt_wall: + Representation of the datetime as "wall time". This parameter must + either have a `fold` attribute or have a fold-naive + :class:`datetime.tzinfo` attached, otherwise the calculation may + fail. + """ + if self.is_ambiguous(dt_wall): + delta_wall = dt_wall - dt_utc + _fold = int(delta_wall == (dt_utc.utcoffset() - dt_utc.dst())) + else: + _fold = 0 + + return _fold + + def _fold(self, dt): + return getattr(dt, 'fold', 0) + + def _fromutc(self, dt): + """ + Given a timezone-aware datetime in a given timezone, calculates a + timezone-aware datetime in a new timezone. + + Since this is the one time that we *know* we have an unambiguous + datetime object, we take this opportunity to determine whether the + datetime is ambiguous and in a "fold" state (e.g. if it's the first + occurrence, chronologically, of the ambiguous datetime). + + :param dt: + A timezone-aware :class:`datetime.datetime` object. + """ + + # Re-implement the algorithm from Python's datetime.py + dtoff = dt.utcoffset() + if dtoff is None: + raise ValueError("fromutc() requires a non-None utcoffset() " + "result") + + # The original datetime.py code assumes that `dst()` defaults to + # zero during ambiguous times. PEP 495 inverts this presumption, so + # for pre-PEP 495 versions of python, we need to tweak the algorithm. + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc() requires a non-None dst() result") + delta = dtoff - dtdst + + dt += delta + # Set fold=1 so we can default to being in the fold for + # ambiguous dates. + dtdst = enfold(dt, fold=1).dst() + if dtdst is None: + raise ValueError("fromutc(): dt.dst gave inconsistent " + "results; cannot convert") + return dt + dtdst + + @_validate_fromutc_inputs + def fromutc(self, dt): + """ + Given a timezone-aware datetime in a given timezone, calculates a + timezone-aware datetime in a new timezone. + + Since this is the one time that we *know* we have an unambiguous + datetime object, we take this opportunity to determine whether the + datetime is ambiguous and in a "fold" state (e.g. if it's the first + occurrence, chronologically, of the ambiguous datetime). + + :param dt: + A timezone-aware :class:`datetime.datetime` object. + """ + dt_wall = self._fromutc(dt) + + # Calculate the fold status given the two datetimes. + _fold = self._fold_status(dt, dt_wall) + + # Set the default fold value for ambiguous dates + return enfold(dt_wall, fold=_fold) + + +class tzrangebase(_tzinfo): + """ + This is an abstract base class for time zones represented by an annual + transition into and out of DST. Child classes should implement the following + methods: + + * ``__init__(self, *args, **kwargs)`` + * ``transitions(self, year)`` - this is expected to return a tuple of + datetimes representing the DST on and off transitions in standard + time. + + A fully initialized ``tzrangebase`` subclass should also provide the + following attributes: + * ``hasdst``: Boolean whether or not the zone uses DST. + * ``_dst_offset`` / ``_std_offset``: :class:`datetime.timedelta` objects + representing the respective UTC offsets. + * ``_dst_abbr`` / ``_std_abbr``: Strings representing the timezone short + abbreviations in DST and STD, respectively. + * ``_hasdst``: Whether or not the zone has DST. + + .. versionadded:: 2.6.0 + """ + def __init__(self): + raise NotImplementedError('tzrangebase is an abstract base class') + + def utcoffset(self, dt): + isdst = self._isdst(dt) + + if isdst is None: + return None + elif isdst: + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + isdst = self._isdst(dt) + + if isdst is None: + return None + elif isdst: + return self._dst_base_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + if self._isdst(dt): + return self._dst_abbr + else: + return self._std_abbr + + def fromutc(self, dt): + """ Given a datetime in UTC, return local time """ + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") + + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + # Get transitions - if there are none, fixed offset + transitions = self.transitions(dt.year) + if transitions is None: + return dt + self.utcoffset(dt) + + # Get the transition times in UTC + dston, dstoff = transitions + + dston -= self._std_offset + dstoff -= self._std_offset + + utc_transitions = (dston, dstoff) + dt_utc = dt.replace(tzinfo=None) + + isdst = self._naive_isdst(dt_utc, utc_transitions) + + if isdst: + dt_wall = dt + self._dst_offset + else: + dt_wall = dt + self._std_offset + + _fold = int(not isdst and self.is_ambiguous(dt_wall)) + + return enfold(dt_wall, fold=_fold) + + def is_ambiguous(self, dt): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + + + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + if not self.hasdst: + return False + + start, end = self.transitions(dt.year) + + dt = dt.replace(tzinfo=None) + return (end <= dt < end + self._dst_base_offset) + + def _isdst(self, dt): + if not self.hasdst: + return False + elif dt is None: + return None + + transitions = self.transitions(dt.year) + + if transitions is None: + return False + + dt = dt.replace(tzinfo=None) + + isdst = self._naive_isdst(dt, transitions) + + # Handle ambiguous dates + if not isdst and self.is_ambiguous(dt): + return not self._fold(dt) + else: + return isdst + + def _naive_isdst(self, dt, transitions): + dston, dstoff = transitions + + dt = dt.replace(tzinfo=None) + + if dston < dstoff: + isdst = dston <= dt < dstoff + else: + isdst = not dstoff <= dt < dston + + return isdst + + @property + def _dst_base_offset(self): + return self._dst_offset - self._std_offset + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __repr__(self): + return "%s(...)" % self.__class__.__name__ + + __reduce__ = object.__reduce__ diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/_factories.py b/.venv/lib/python3.7/site-packages/dateutil/tz/_factories.py new file mode 100644 index 0000000..f8a6589 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tz/_factories.py @@ -0,0 +1,80 @@ +from datetime import timedelta +import weakref +from collections import OrderedDict + +from six.moves import _thread + + +class _TzSingleton(type): + def __init__(cls, *args, **kwargs): + cls.__instance = None + super(_TzSingleton, cls).__init__(*args, **kwargs) + + def __call__(cls): + if cls.__instance is None: + cls.__instance = super(_TzSingleton, cls).__call__() + return cls.__instance + + +class _TzFactory(type): + def instance(cls, *args, **kwargs): + """Alternate constructor that returns a fresh instance""" + return type.__call__(cls, *args, **kwargs) + + +class _TzOffsetFactory(_TzFactory): + def __init__(cls, *args, **kwargs): + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 + + cls._cache_lock = _thread.allocate_lock() + + def __call__(cls, name, offset): + if isinstance(offset, timedelta): + key = (name, offset.total_seconds()) + else: + key = (name, offset) + + instance = cls.__instances.get(key, None) + if instance is None: + instance = cls.__instances.setdefault(key, + cls.instance(name, offset)) + + # This lock may not be necessary in Python 3. See GH issue #901 + with cls._cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + + return instance + + +class _TzStrFactory(_TzFactory): + def __init__(cls, *args, **kwargs): + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 + + cls.__cache_lock = _thread.allocate_lock() + + def __call__(cls, s, posix_offset=False): + key = (s, posix_offset) + instance = cls.__instances.get(key, None) + + if instance is None: + instance = cls.__instances.setdefault(key, + cls.instance(s, posix_offset)) + + # This lock may not be necessary in Python 3. See GH issue #901 + with cls.__cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + + return instance + diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/tz.py b/.venv/lib/python3.7/site-packages/dateutil/tz/tz.py new file mode 100644 index 0000000..c67f56d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tz/tz.py @@ -0,0 +1,1849 @@ +# -*- coding: utf-8 -*- +""" +This module offers timezone implementations subclassing the abstract +:py:class:`datetime.tzinfo` type. There are classes to handle tzfile format +files (usually are in :file:`/etc/localtime`, :file:`/usr/share/zoneinfo`, +etc), TZ environment string (in all known formats), given ranges (with help +from relative deltas), local machine timezone, fixed offset timezone, and UTC +timezone. +""" +import datetime +import struct +import time +import sys +import os +import bisect +import weakref +from collections import OrderedDict + +import six +from six import string_types +from six.moves import _thread +from ._common import tzname_in_python2, _tzinfo +from ._common import tzrangebase, enfold +from ._common import _validate_fromutc_inputs + +from ._factories import _TzSingleton, _TzOffsetFactory +from ._factories import _TzStrFactory +try: + from .win import tzwin, tzwinlocal +except ImportError: + tzwin = tzwinlocal = None + +# For warning about rounding tzinfo +from warnings import warn + +ZERO = datetime.timedelta(0) +EPOCH = datetime.datetime.utcfromtimestamp(0) +EPOCHORDINAL = EPOCH.toordinal() + + +@six.add_metaclass(_TzSingleton) +class tzutc(datetime.tzinfo): + """ + This is a tzinfo object that represents the UTC time zone. + + **Examples:** + + .. doctest:: + + >>> from datetime import * + >>> from dateutil.tz import * + + >>> datetime.now() + datetime.datetime(2003, 9, 27, 9, 40, 1, 521290) + + >>> datetime.now(tzutc()) + datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc()) + + >>> datetime.now(tzutc()).tzname() + 'UTC' + + .. versionchanged:: 2.7.0 + ``tzutc()`` is now a singleton, so the result of ``tzutc()`` will + always return the same object. + + .. doctest:: + + >>> from dateutil.tz import tzutc, UTC + >>> tzutc() is tzutc() + True + >>> tzutc() is UTC + True + """ + def utcoffset(self, dt): + return ZERO + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return "UTC" + + def is_ambiguous(self, dt): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + + + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + return False + + @_validate_fromutc_inputs + def fromutc(self, dt): + """ + Fast track version of fromutc() returns the original ``dt`` object for + any valid :py:class:`datetime.datetime` object. + """ + return dt + + def __eq__(self, other): + if not isinstance(other, (tzutc, tzoffset)): + return NotImplemented + + return (isinstance(other, tzutc) or + (isinstance(other, tzoffset) and other._offset == ZERO)) + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + + +#: Convenience constant providing a :class:`tzutc()` instance +#: +#: .. versionadded:: 2.7.0 +UTC = tzutc() + + +@six.add_metaclass(_TzOffsetFactory) +class tzoffset(datetime.tzinfo): + """ + A simple class for representing a fixed offset from UTC. + + :param name: + The timezone name, to be returned when ``tzname()`` is called. + :param offset: + The time zone offset in seconds, or (since version 2.6.0, represented + as a :py:class:`datetime.timedelta` object). + """ + def __init__(self, name, offset): + self._name = name + + try: + # Allow a timedelta + offset = offset.total_seconds() + except (TypeError, AttributeError): + pass + + self._offset = datetime.timedelta(seconds=_get_supported_offset(offset)) + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._name + + @_validate_fromutc_inputs + def fromutc(self, dt): + return dt + self._offset + + def is_ambiguous(self, dt): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + return False + + def __eq__(self, other): + if not isinstance(other, tzoffset): + return NotImplemented + + return self._offset == other._offset + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __repr__(self): + return "%s(%s, %s)" % (self.__class__.__name__, + repr(self._name), + int(self._offset.total_seconds())) + + __reduce__ = object.__reduce__ + + +class tzlocal(_tzinfo): + """ + A :class:`tzinfo` subclass built around the ``time`` timezone functions. + """ + def __init__(self): + super(tzlocal, self).__init__() + + self._std_offset = datetime.timedelta(seconds=-time.timezone) + if time.daylight: + self._dst_offset = datetime.timedelta(seconds=-time.altzone) + else: + self._dst_offset = self._std_offset + + self._dst_saved = self._dst_offset - self._std_offset + self._hasdst = bool(self._dst_saved) + self._tznames = tuple(time.tzname) + + def utcoffset(self, dt): + if dt is None and self._hasdst: + return None + + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if dt is None and self._hasdst: + return None + + if self._isdst(dt): + return self._dst_offset - self._std_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._tznames[self._isdst(dt)] + + def is_ambiguous(self, dt): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + + + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + naive_dst = self._naive_is_dst(dt) + return (not naive_dst and + (naive_dst != self._naive_is_dst(dt - self._dst_saved))) + + def _naive_is_dst(self, dt): + timestamp = _datetime_to_timestamp(dt) + return time.localtime(timestamp + time.timezone).tm_isdst + + def _isdst(self, dt, fold_naive=True): + # We can't use mktime here. It is unstable when deciding if + # the hour near to a change is DST or not. + # + # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, + # dt.minute, dt.second, dt.weekday(), 0, -1)) + # return time.localtime(timestamp).tm_isdst + # + # The code above yields the following result: + # + # >>> import tz, datetime + # >>> t = tz.tzlocal() + # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + # 'BRDT' + # >>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() + # 'BRST' + # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + # 'BRST' + # >>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() + # 'BRDT' + # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + # 'BRDT' + # + # Here is a more stable implementation: + # + if not self._hasdst: + return False + + # Check for ambiguous times: + dstval = self._naive_is_dst(dt) + fold = getattr(dt, 'fold', None) + + if self.is_ambiguous(dt): + if fold is not None: + return not self._fold(dt) + else: + return True + + return dstval + + def __eq__(self, other): + if isinstance(other, tzlocal): + return (self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset) + elif isinstance(other, tzutc): + return (not self._hasdst and + self._tznames[0] in {'UTC', 'GMT'} and + self._std_offset == ZERO) + elif isinstance(other, tzoffset): + return (not self._hasdst and + self._tznames[0] == other._name and + self._std_offset == other._offset) + else: + return NotImplemented + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + + +class _ttinfo(object): + __slots__ = ["offset", "delta", "isdst", "abbr", + "isstd", "isgmt", "dstoffset"] + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def __repr__(self): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + + def __eq__(self, other): + if not isinstance(other, _ttinfo): + return NotImplemented + + return (self.offset == other.offset and + self.delta == other.delta and + self.isdst == other.isdst and + self.abbr == other.abbr and + self.isstd == other.isstd and + self.isgmt == other.isgmt and + self.dstoffset == other.dstoffset) + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __getstate__(self): + state = {} + for name in self.__slots__: + state[name] = getattr(self, name, None) + return state + + def __setstate__(self, state): + for name in self.__slots__: + if name in state: + setattr(self, name, state[name]) + + +class _tzfile(object): + """ + Lightweight class for holding the relevant transition and time zone + information read from binary tzfiles. + """ + attrs = ['trans_list', 'trans_list_utc', 'trans_idx', 'ttinfo_list', + 'ttinfo_std', 'ttinfo_dst', 'ttinfo_before', 'ttinfo_first'] + + def __init__(self, **kwargs): + for attr in self.attrs: + setattr(self, attr, kwargs.get(attr, None)) + + +class tzfile(_tzinfo): + """ + This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)`` + format timezone files to extract current and historical zone information. + + :param fileobj: + This can be an opened file stream or a file name that the time zone + information can be read from. + + :param filename: + This is an optional parameter specifying the source of the time zone + information in the event that ``fileobj`` is a file object. If omitted + and ``fileobj`` is a file stream, this parameter will be set either to + ``fileobj``'s ``name`` attribute or to ``repr(fileobj)``. + + See `Sources for Time Zone and Daylight Saving Time Data + `_ for more information. + Time zone files can be compiled from the `IANA Time Zone database files + `_ with the `zic time zone compiler + `_ + + .. note:: + + Only construct a ``tzfile`` directly if you have a specific timezone + file on disk that you want to read into a Python ``tzinfo`` object. + If you want to get a ``tzfile`` representing a specific IANA zone, + (e.g. ``'America/New_York'``), you should call + :func:`dateutil.tz.gettz` with the zone identifier. + + + **Examples:** + + Using the US Eastern time zone as an example, we can see that a ``tzfile`` + provides time zone information for the standard Daylight Saving offsets: + + .. testsetup:: tzfile + + from dateutil.tz import gettz + from datetime import datetime + + .. doctest:: tzfile + + >>> NYC = gettz('America/New_York') + >>> NYC + tzfile('/usr/share/zoneinfo/America/New_York') + + >>> print(datetime(2016, 1, 3, tzinfo=NYC)) # EST + 2016-01-03 00:00:00-05:00 + + >>> print(datetime(2016, 7, 7, tzinfo=NYC)) # EDT + 2016-07-07 00:00:00-04:00 + + + The ``tzfile`` structure contains a fully history of the time zone, + so historical dates will also have the right offsets. For example, before + the adoption of the UTC standards, New York used local solar mean time: + + .. doctest:: tzfile + + >>> print(datetime(1901, 4, 12, tzinfo=NYC)) # LMT + 1901-04-12 00:00:00-04:56 + + And during World War II, New York was on "Eastern War Time", which was a + state of permanent daylight saving time: + + .. doctest:: tzfile + + >>> print(datetime(1944, 2, 7, tzinfo=NYC)) # EWT + 1944-02-07 00:00:00-04:00 + + """ + + def __init__(self, fileobj, filename=None): + super(tzfile, self).__init__() + + file_opened_here = False + if isinstance(fileobj, string_types): + self._filename = fileobj + fileobj = open(fileobj, 'rb') + file_opened_here = True + elif filename is not None: + self._filename = filename + elif hasattr(fileobj, "name"): + self._filename = fileobj.name + else: + self._filename = repr(fileobj) + + if fileobj is not None: + if not file_opened_here: + fileobj = _nullcontext(fileobj) + + with fileobj as file_stream: + tzobj = self._read_tzfile(file_stream) + + self._set_tzdata(tzobj) + + def _set_tzdata(self, tzobj): + """ Set the time zone data of this object from a _tzfile object """ + # Copy the relevant attributes over as private attributes + for attr in _tzfile.attrs: + setattr(self, '_' + attr, getattr(tzobj, attr)) + + def _read_tzfile(self, fileobj): + out = _tzfile() + + # From tzfile(5): + # + # The time zone information files used by tzset(3) + # begin with the magic characters "TZif" to identify + # them as time zone information files, followed by + # sixteen bytes reserved for future use, followed by + # six four-byte values of type long, written in a + # ``standard'' byte order (the high-order byte + # of the value is written first). + if fileobj.read(4).decode() != "TZif": + raise ValueError("magic not found") + + fileobj.read(16) + + ( + # The number of UTC/local indicators stored in the file. + ttisgmtcnt, + + # The number of standard/wall indicators stored in the file. + ttisstdcnt, + + # The number of leap seconds for which data is + # stored in the file. + leapcnt, + + # The number of "transition times" for which data + # is stored in the file. + timecnt, + + # The number of "local time types" for which data + # is stored in the file (must not be zero). + typecnt, + + # The number of characters of "time zone + # abbreviation strings" stored in the file. + charcnt, + + ) = struct.unpack(">6l", fileobj.read(24)) + + # The above header is followed by tzh_timecnt four-byte + # values of type long, sorted in ascending order. + # These values are written in ``standard'' byte order. + # Each is used as a transition time (as returned by + # time(2)) at which the rules for computing local time + # change. + + if timecnt: + out.trans_list_utc = list(struct.unpack(">%dl" % timecnt, + fileobj.read(timecnt*4))) + else: + out.trans_list_utc = [] + + # Next come tzh_timecnt one-byte values of type unsigned + # char; each one tells which of the different types of + # ``local time'' types described in the file is associated + # with the same-indexed transition time. These values + # serve as indices into an array of ttinfo structures that + # appears next in the file. + + if timecnt: + out.trans_idx = struct.unpack(">%dB" % timecnt, + fileobj.read(timecnt)) + else: + out.trans_idx = [] + + # Each ttinfo structure is written as a four-byte value + # for tt_gmtoff of type long, in a standard byte + # order, followed by a one-byte value for tt_isdst + # and a one-byte value for tt_abbrind. In each + # structure, tt_gmtoff gives the number of + # seconds to be added to UTC, tt_isdst tells whether + # tm_isdst should be set by localtime(3), and + # tt_abbrind serves as an index into the array of + # time zone abbreviation characters that follow the + # ttinfo structure(s) in the file. + + ttinfo = [] + + for i in range(typecnt): + ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) + + abbr = fileobj.read(charcnt).decode() + + # Then there are tzh_leapcnt pairs of four-byte + # values, written in standard byte order; the + # first value of each pair gives the time (as + # returned by time(2)) at which a leap second + # occurs; the second gives the total number of + # leap seconds to be applied after the given time. + # The pairs of values are sorted in ascending order + # by time. + + # Not used, for now (but seek for correct file position) + if leapcnt: + fileobj.seek(leapcnt * 8, os.SEEK_CUR) + + # Then there are tzh_ttisstdcnt standard/wall + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as standard + # time or wall clock time, and are used when + # a time zone file is used in handling POSIX-style + # time zone environment variables. + + if ttisstdcnt: + isstd = struct.unpack(">%db" % ttisstdcnt, + fileobj.read(ttisstdcnt)) + + # Finally, there are tzh_ttisgmtcnt UTC/local + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as UTC or + # local time, and are used when a time zone file + # is used in handling POSIX-style time zone envi- + # ronment variables. + + if ttisgmtcnt: + isgmt = struct.unpack(">%db" % ttisgmtcnt, + fileobj.read(ttisgmtcnt)) + + # Build ttinfo list + out.ttinfo_list = [] + for i in range(typecnt): + gmtoff, isdst, abbrind = ttinfo[i] + gmtoff = _get_supported_offset(gmtoff) + tti = _ttinfo() + tti.offset = gmtoff + tti.dstoffset = datetime.timedelta(0) + tti.delta = datetime.timedelta(seconds=gmtoff) + tti.isdst = isdst + tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] + tti.isstd = (ttisstdcnt > i and isstd[i] != 0) + tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) + out.ttinfo_list.append(tti) + + # Replace ttinfo indexes for ttinfo objects. + out.trans_idx = [out.ttinfo_list[idx] for idx in out.trans_idx] + + # Set standard, dst, and before ttinfos. before will be + # used when a given time is before any transitions, + # and will be set to the first non-dst ttinfo, or to + # the first dst, if all of them are dst. + out.ttinfo_std = None + out.ttinfo_dst = None + out.ttinfo_before = None + if out.ttinfo_list: + if not out.trans_list_utc: + out.ttinfo_std = out.ttinfo_first = out.ttinfo_list[0] + else: + for i in range(timecnt-1, -1, -1): + tti = out.trans_idx[i] + if not out.ttinfo_std and not tti.isdst: + out.ttinfo_std = tti + elif not out.ttinfo_dst and tti.isdst: + out.ttinfo_dst = tti + + if out.ttinfo_std and out.ttinfo_dst: + break + else: + if out.ttinfo_dst and not out.ttinfo_std: + out.ttinfo_std = out.ttinfo_dst + + for tti in out.ttinfo_list: + if not tti.isdst: + out.ttinfo_before = tti + break + else: + out.ttinfo_before = out.ttinfo_list[0] + + # Now fix transition times to become relative to wall time. + # + # I'm not sure about this. In my tests, the tz source file + # is setup to wall time, and in the binary file isstd and + # isgmt are off, so it should be in wall time. OTOH, it's + # always in gmt time. Let me know if you have comments + # about this. + lastdst = None + lastoffset = None + lastdstoffset = None + lastbaseoffset = None + out.trans_list = [] + + for i, tti in enumerate(out.trans_idx): + offset = tti.offset + dstoffset = 0 + + if lastdst is not None: + if tti.isdst: + if not lastdst: + dstoffset = offset - lastoffset + + if not dstoffset and lastdstoffset: + dstoffset = lastdstoffset + + tti.dstoffset = datetime.timedelta(seconds=dstoffset) + lastdstoffset = dstoffset + + # If a time zone changes its base offset during a DST transition, + # then you need to adjust by the previous base offset to get the + # transition time in local time. Otherwise you use the current + # base offset. Ideally, I would have some mathematical proof of + # why this is true, but I haven't really thought about it enough. + baseoffset = offset - dstoffset + adjustment = baseoffset + if (lastbaseoffset is not None and baseoffset != lastbaseoffset + and tti.isdst != lastdst): + # The base DST has changed + adjustment = lastbaseoffset + + lastdst = tti.isdst + lastoffset = offset + lastbaseoffset = baseoffset + + out.trans_list.append(out.trans_list_utc[i] + adjustment) + + out.trans_idx = tuple(out.trans_idx) + out.trans_list = tuple(out.trans_list) + out.trans_list_utc = tuple(out.trans_list_utc) + + return out + + def _find_last_transition(self, dt, in_utc=False): + # If there's no list, there are no transitions to find + if not self._trans_list: + return None + + timestamp = _datetime_to_timestamp(dt) + + # Find where the timestamp fits in the transition list - if the + # timestamp is a transition time, it's part of the "after" period. + trans_list = self._trans_list_utc if in_utc else self._trans_list + idx = bisect.bisect_right(trans_list, timestamp) + + # We want to know when the previous transition was, so subtract off 1 + return idx - 1 + + def _get_ttinfo(self, idx): + # For no list or after the last transition, default to _ttinfo_std + if idx is None or (idx + 1) >= len(self._trans_list): + return self._ttinfo_std + + # If there is a list and the time is before it, return _ttinfo_before + if idx < 0: + return self._ttinfo_before + + return self._trans_idx[idx] + + def _find_ttinfo(self, dt): + idx = self._resolve_ambiguous_time(dt) + + return self._get_ttinfo(idx) + + def fromutc(self, dt): + """ + The ``tzfile`` implementation of :py:func:`datetime.tzinfo.fromutc`. + + :param dt: + A :py:class:`datetime.datetime` object. + + :raises TypeError: + Raised if ``dt`` is not a :py:class:`datetime.datetime` object. + + :raises ValueError: + Raised if this is called with a ``dt`` which does not have this + ``tzinfo`` attached. + + :return: + Returns a :py:class:`datetime.datetime` object representing the + wall time in ``self``'s time zone. + """ + # These isinstance checks are in datetime.tzinfo, so we'll preserve + # them, even if we don't care about duck typing. + if not isinstance(dt, datetime.datetime): + raise TypeError("fromutc() requires a datetime argument") + + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + # First treat UTC as wall time and get the transition we're in. + idx = self._find_last_transition(dt, in_utc=True) + tti = self._get_ttinfo(idx) + + dt_out = dt + datetime.timedelta(seconds=tti.offset) + + fold = self.is_ambiguous(dt_out, idx=idx) + + return enfold(dt_out, fold=int(fold)) + + def is_ambiguous(self, dt, idx=None): + """ + Whether or not the "wall time" of a given datetime is ambiguous in this + zone. + + :param dt: + A :py:class:`datetime.datetime`, naive or time zone aware. + + + :return: + Returns ``True`` if ambiguous, ``False`` otherwise. + + .. versionadded:: 2.6.0 + """ + if idx is None: + idx = self._find_last_transition(dt) + + # Calculate the difference in offsets from current to previous + timestamp = _datetime_to_timestamp(dt) + tti = self._get_ttinfo(idx) + + if idx is None or idx <= 0: + return False + + od = self._get_ttinfo(idx - 1).offset - tti.offset + tt = self._trans_list[idx] # Transition time + + return timestamp < tt + od + + def _resolve_ambiguous_time(self, dt): + idx = self._find_last_transition(dt) + + # If we have no transitions, return the index + _fold = self._fold(dt) + if idx is None or idx == 0: + return idx + + # If it's ambiguous and we're in a fold, shift to a different index. + idx_offset = int(not _fold and self.is_ambiguous(dt, idx)) + + return idx - idx_offset + + def utcoffset(self, dt): + if dt is None: + return None + + if not self._ttinfo_std: + return ZERO + + return self._find_ttinfo(dt).delta + + def dst(self, dt): + if dt is None: + return None + + if not self._ttinfo_dst: + return ZERO + + tti = self._find_ttinfo(dt) + + if not tti.isdst: + return ZERO + + # The documentation says that utcoffset()-dst() must + # be constant for every dt. + return tti.dstoffset + + @tzname_in_python2 + def tzname(self, dt): + if not self._ttinfo_std or dt is None: + return None + return self._find_ttinfo(dt).abbr + + def __eq__(self, other): + if not isinstance(other, tzfile): + return NotImplemented + return (self._trans_list == other._trans_list and + self._trans_idx == other._trans_idx and + self._ttinfo_list == other._ttinfo_list) + + __hash__ = None + + def __ne__(self, other): + return not (self == other) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._filename)) + + def __reduce__(self): + return self.__reduce_ex__(None) + + def __reduce_ex__(self, protocol): + return (self.__class__, (None, self._filename), self.__dict__) + + +class tzrange(tzrangebase): + """ + The ``tzrange`` object is a time zone specified by a set of offsets and + abbreviations, equivalent to the way the ``TZ`` variable can be specified + in POSIX-like systems, but using Python delta objects to specify DST + start, end and offsets. + + :param stdabbr: + The abbreviation for standard time (e.g. ``'EST'``). + + :param stdoffset: + An integer or :class:`datetime.timedelta` object or equivalent + specifying the base offset from UTC. + + If unspecified, +00:00 is used. + + :param dstabbr: + The abbreviation for DST / "Summer" time (e.g. ``'EDT'``). + + If specified, with no other DST information, DST is assumed to occur + and the default behavior or ``dstoffset``, ``start`` and ``end`` is + used. If unspecified and no other DST information is specified, it + is assumed that this zone has no DST. + + If this is unspecified and other DST information is *is* specified, + DST occurs in the zone but the time zone abbreviation is left + unchanged. + + :param dstoffset: + A an integer or :class:`datetime.timedelta` object or equivalent + specifying the UTC offset during DST. If unspecified and any other DST + information is specified, it is assumed to be the STD offset +1 hour. + + :param start: + A :class:`relativedelta.relativedelta` object or equivalent specifying + the time and time of year that daylight savings time starts. To + specify, for example, that DST starts at 2AM on the 2nd Sunday in + March, pass: + + ``relativedelta(hours=2, month=3, day=1, weekday=SU(+2))`` + + If unspecified and any other DST information is specified, the default + value is 2 AM on the first Sunday in April. + + :param end: + A :class:`relativedelta.relativedelta` object or equivalent + representing the time and time of year that daylight savings time + ends, with the same specification method as in ``start``. One note is + that this should point to the first time in the *standard* zone, so if + a transition occurs at 2AM in the DST zone and the clocks are set back + 1 hour to 1AM, set the ``hours`` parameter to +1. + + + **Examples:** + + .. testsetup:: tzrange + + from dateutil.tz import tzrange, tzstr + + .. doctest:: tzrange + + >>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT") + True + + >>> from dateutil.relativedelta import * + >>> range1 = tzrange("EST", -18000, "EDT") + >>> range2 = tzrange("EST", -18000, "EDT", -14400, + ... relativedelta(hours=+2, month=4, day=1, + ... weekday=SU(+1)), + ... relativedelta(hours=+1, month=10, day=31, + ... weekday=SU(-1))) + >>> tzstr('EST5EDT') == range1 == range2 + True + + """ + def __init__(self, stdabbr, stdoffset=None, + dstabbr=None, dstoffset=None, + start=None, end=None): + + global relativedelta + from dateutil import relativedelta + + self._std_abbr = stdabbr + self._dst_abbr = dstabbr + + try: + stdoffset = stdoffset.total_seconds() + except (TypeError, AttributeError): + pass + + try: + dstoffset = dstoffset.total_seconds() + except (TypeError, AttributeError): + pass + + if stdoffset is not None: + self._std_offset = datetime.timedelta(seconds=stdoffset) + else: + self._std_offset = ZERO + + if dstoffset is not None: + self._dst_offset = datetime.timedelta(seconds=dstoffset) + elif dstabbr and stdoffset is not None: + self._dst_offset = self._std_offset + datetime.timedelta(hours=+1) + else: + self._dst_offset = ZERO + + if dstabbr and start is None: + self._start_delta = relativedelta.relativedelta( + hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) + else: + self._start_delta = start + + if dstabbr and end is None: + self._end_delta = relativedelta.relativedelta( + hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) + else: + self._end_delta = end + + self._dst_base_offset_ = self._dst_offset - self._std_offset + self.hasdst = bool(self._start_delta) + + def transitions(self, year): + """ + For a given year, get the DST on and off transition times, expressed + always on the standard time side. For zones with no transitions, this + function returns ``None``. + + :param year: + The year whose transitions you would like to query. + + :return: + Returns a :class:`tuple` of :class:`datetime.datetime` objects, + ``(dston, dstoff)`` for zones with an annual DST transition, or + ``None`` for fixed offset zones. + """ + if not self.hasdst: + return None + + base_year = datetime.datetime(year, 1, 1) + + start = base_year + self._start_delta + end = base_year + self._end_delta + + return (start, end) + + def __eq__(self, other): + if not isinstance(other, tzrange): + return NotImplemented + + return (self._std_abbr == other._std_abbr and + self._dst_abbr == other._dst_abbr and + self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset and + self._start_delta == other._start_delta and + self._end_delta == other._end_delta) + + @property + def _dst_base_offset(self): + return self._dst_base_offset_ + + +@six.add_metaclass(_TzStrFactory) +class tzstr(tzrange): + """ + ``tzstr`` objects are time zone objects specified by a time-zone string as + it would be passed to a ``TZ`` variable on POSIX-style systems (see + the `GNU C Library: TZ Variable`_ for more details). + + There is one notable exception, which is that POSIX-style time zones use an + inverted offset format, so normally ``GMT+3`` would be parsed as an offset + 3 hours *behind* GMT. The ``tzstr`` time zone object will parse this as an + offset 3 hours *ahead* of GMT. If you would like to maintain the POSIX + behavior, pass a ``True`` value to ``posix_offset``. + + The :class:`tzrange` object provides the same functionality, but is + specified using :class:`relativedelta.relativedelta` objects. rather than + strings. + + :param s: + A time zone string in ``TZ`` variable format. This can be a + :class:`bytes` (2.x: :class:`str`), :class:`str` (2.x: + :class:`unicode`) or a stream emitting unicode characters + (e.g. :class:`StringIO`). + + :param posix_offset: + Optional. If set to ``True``, interpret strings such as ``GMT+3`` or + ``UTC+3`` as being 3 hours *behind* UTC rather than ahead, per the + POSIX standard. + + .. caution:: + + Prior to version 2.7.0, this function also supported time zones + in the format: + + * ``EST5EDT,4,0,6,7200,10,0,26,7200,3600`` + * ``EST5EDT,4,1,0,7200,10,-1,0,7200,3600`` + + This format is non-standard and has been deprecated; this function + will raise a :class:`DeprecatedTZFormatWarning` until + support is removed in a future version. + + .. _`GNU C Library: TZ Variable`: + https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html + """ + def __init__(self, s, posix_offset=False): + global parser + from dateutil.parser import _parser as parser + + self._s = s + + res = parser._parsetz(s) + if res is None or res.any_unused_tokens: + raise ValueError("unknown string format") + + # Here we break the compatibility with the TZ variable handling. + # GMT-3 actually *means* the timezone -3. + if res.stdabbr in ("GMT", "UTC") and not posix_offset: + res.stdoffset *= -1 + + # We must initialize it first, since _delta() needs + # _std_offset and _dst_offset set. Use False in start/end + # to avoid building it two times. + tzrange.__init__(self, res.stdabbr, res.stdoffset, + res.dstabbr, res.dstoffset, + start=False, end=False) + + if not res.dstabbr: + self._start_delta = None + self._end_delta = None + else: + self._start_delta = self._delta(res.start) + if self._start_delta: + self._end_delta = self._delta(res.end, isend=1) + + self.hasdst = bool(self._start_delta) + + def _delta(self, x, isend=0): + from dateutil import relativedelta + kwargs = {} + if x.month is not None: + kwargs["month"] = x.month + if x.weekday is not None: + kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) + if x.week > 0: + kwargs["day"] = 1 + else: + kwargs["day"] = 31 + elif x.day: + kwargs["day"] = x.day + elif x.yday is not None: + kwargs["yearday"] = x.yday + elif x.jyday is not None: + kwargs["nlyearday"] = x.jyday + if not kwargs: + # Default is to start on first sunday of april, and end + # on last sunday of october. + if not isend: + kwargs["month"] = 4 + kwargs["day"] = 1 + kwargs["weekday"] = relativedelta.SU(+1) + else: + kwargs["month"] = 10 + kwargs["day"] = 31 + kwargs["weekday"] = relativedelta.SU(-1) + if x.time is not None: + kwargs["seconds"] = x.time + else: + # Default is 2AM. + kwargs["seconds"] = 7200 + if isend: + # Convert to standard time, to follow the documented way + # of working with the extra hour. See the documentation + # of the tzinfo class. + delta = self._dst_offset - self._std_offset + kwargs["seconds"] -= delta.seconds + delta.days * 86400 + return relativedelta.relativedelta(**kwargs) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + + +class _tzicalvtzcomp(object): + def __init__(self, tzoffsetfrom, tzoffsetto, isdst, + tzname=None, rrule=None): + self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) + self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) + self.tzoffsetdiff = self.tzoffsetto - self.tzoffsetfrom + self.isdst = isdst + self.tzname = tzname + self.rrule = rrule + + +class _tzicalvtz(_tzinfo): + def __init__(self, tzid, comps=[]): + super(_tzicalvtz, self).__init__() + + self._tzid = tzid + self._comps = comps + self._cachedate = [] + self._cachecomp = [] + self._cache_lock = _thread.allocate_lock() + + def _find_comp(self, dt): + if len(self._comps) == 1: + return self._comps[0] + + dt = dt.replace(tzinfo=None) + + try: + with self._cache_lock: + return self._cachecomp[self._cachedate.index( + (dt, self._fold(dt)))] + except ValueError: + pass + + lastcompdt = None + lastcomp = None + + for comp in self._comps: + compdt = self._find_compdt(comp, dt) + + if compdt and (not lastcompdt or lastcompdt < compdt): + lastcompdt = compdt + lastcomp = comp + + if not lastcomp: + # RFC says nothing about what to do when a given + # time is before the first onset date. We'll look for the + # first standard component, or the first component, if + # none is found. + for comp in self._comps: + if not comp.isdst: + lastcomp = comp + break + else: + lastcomp = comp[0] + + with self._cache_lock: + self._cachedate.insert(0, (dt, self._fold(dt))) + self._cachecomp.insert(0, lastcomp) + + if len(self._cachedate) > 10: + self._cachedate.pop() + self._cachecomp.pop() + + return lastcomp + + def _find_compdt(self, comp, dt): + if comp.tzoffsetdiff < ZERO and self._fold(dt): + dt -= comp.tzoffsetdiff + + compdt = comp.rrule.before(dt, inc=True) + + return compdt + + def utcoffset(self, dt): + if dt is None: + return None + + return self._find_comp(dt).tzoffsetto + + def dst(self, dt): + comp = self._find_comp(dt) + if comp.isdst: + return comp.tzoffsetdiff + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._find_comp(dt).tzname + + def __repr__(self): + return "" % repr(self._tzid) + + __reduce__ = object.__reduce__ + + +class tzical(object): + """ + This object is designed to parse an iCalendar-style ``VTIMEZONE`` structure + as set out in `RFC 5545`_ Section 4.6.5 into one or more `tzinfo` objects. + + :param `fileobj`: + A file or stream in iCalendar format, which should be UTF-8 encoded + with CRLF endings. + + .. _`RFC 5545`: https://tools.ietf.org/html/rfc5545 + """ + def __init__(self, fileobj): + global rrule + from dateutil import rrule + + if isinstance(fileobj, string_types): + self._s = fileobj + # ical should be encoded in UTF-8 with CRLF + fileobj = open(fileobj, 'r') + else: + self._s = getattr(fileobj, 'name', repr(fileobj)) + fileobj = _nullcontext(fileobj) + + self._vtz = {} + + with fileobj as fobj: + self._parse_rfc(fobj.read()) + + def keys(self): + """ + Retrieves the available time zones as a list. + """ + return list(self._vtz.keys()) + + def get(self, tzid=None): + """ + Retrieve a :py:class:`datetime.tzinfo` object by its ``tzid``. + + :param tzid: + If there is exactly one time zone available, omitting ``tzid`` + or passing :py:const:`None` value returns it. Otherwise a valid + key (which can be retrieved from :func:`keys`) is required. + + :raises ValueError: + Raised if ``tzid`` is not specified but there are either more + or fewer than 1 zone defined. + + :returns: + Returns either a :py:class:`datetime.tzinfo` object representing + the relevant time zone or :py:const:`None` if the ``tzid`` was + not found. + """ + if tzid is None: + if len(self._vtz) == 0: + raise ValueError("no timezones defined") + elif len(self._vtz) > 1: + raise ValueError("more than one timezone available") + tzid = next(iter(self._vtz)) + + return self._vtz.get(tzid) + + def _parse_offset(self, s): + s = s.strip() + if not s: + raise ValueError("empty offset") + if s[0] in ('+', '-'): + signal = (-1, +1)[s[0] == '+'] + s = s[1:] + else: + signal = +1 + if len(s) == 4: + return (int(s[:2]) * 3600 + int(s[2:]) * 60) * signal + elif len(s) == 6: + return (int(s[:2]) * 3600 + int(s[2:4]) * 60 + int(s[4:])) * signal + else: + raise ValueError("invalid offset: " + s) + + def _parse_rfc(self, s): + lines = s.splitlines() + if not lines: + raise ValueError("empty string") + + # Unfold + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + + tzid = None + comps = [] + invtz = False + comptype = None + for line in lines: + if not line: + continue + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0].upper() + parms = parms[1:] + if invtz: + if name == "BEGIN": + if value in ("STANDARD", "DAYLIGHT"): + # Process component + pass + else: + raise ValueError("unknown component: "+value) + comptype = value + founddtstart = False + tzoffsetfrom = None + tzoffsetto = None + rrulelines = [] + tzname = None + elif name == "END": + if value == "VTIMEZONE": + if comptype: + raise ValueError("component not closed: "+comptype) + if not tzid: + raise ValueError("mandatory TZID not found") + if not comps: + raise ValueError( + "at least one component is needed") + # Process vtimezone + self._vtz[tzid] = _tzicalvtz(tzid, comps) + invtz = False + elif value == comptype: + if not founddtstart: + raise ValueError("mandatory DTSTART not found") + if tzoffsetfrom is None: + raise ValueError( + "mandatory TZOFFSETFROM not found") + if tzoffsetto is None: + raise ValueError( + "mandatory TZOFFSETFROM not found") + # Process component + rr = None + if rrulelines: + rr = rrule.rrulestr("\n".join(rrulelines), + compatible=True, + ignoretz=True, + cache=True) + comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, + (comptype == "DAYLIGHT"), + tzname, rr) + comps.append(comp) + comptype = None + else: + raise ValueError("invalid component end: "+value) + elif comptype: + if name == "DTSTART": + # DTSTART in VTIMEZONE takes a subset of valid RRULE + # values under RFC 5545. + for parm in parms: + if parm != 'VALUE=DATE-TIME': + msg = ('Unsupported DTSTART param in ' + + 'VTIMEZONE: ' + parm) + raise ValueError(msg) + rrulelines.append(line) + founddtstart = True + elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): + rrulelines.append(line) + elif name == "TZOFFSETFROM": + if parms: + raise ValueError( + "unsupported %s parm: %s " % (name, parms[0])) + tzoffsetfrom = self._parse_offset(value) + elif name == "TZOFFSETTO": + if parms: + raise ValueError( + "unsupported TZOFFSETTO parm: "+parms[0]) + tzoffsetto = self._parse_offset(value) + elif name == "TZNAME": + if parms: + raise ValueError( + "unsupported TZNAME parm: "+parms[0]) + tzname = value + elif name == "COMMENT": + pass + else: + raise ValueError("unsupported property: "+name) + else: + if name == "TZID": + if parms: + raise ValueError( + "unsupported TZID parm: "+parms[0]) + tzid = value + elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): + pass + else: + raise ValueError("unsupported property: "+name) + elif name == "BEGIN" and value == "VTIMEZONE": + tzid = None + comps = [] + invtz = True + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + + +if sys.platform != "win32": + TZFILES = ["/etc/localtime", "localtime"] + TZPATHS = ["/usr/share/zoneinfo", + "/usr/lib/zoneinfo", + "/usr/share/lib/zoneinfo", + "/etc/zoneinfo"] +else: + TZFILES = [] + TZPATHS = [] + + +def __get_gettz(): + tzlocal_classes = (tzlocal,) + if tzwinlocal is not None: + tzlocal_classes += (tzwinlocal,) + + class GettzFunc(object): + """ + Retrieve a time zone object from a string representation + + This function is intended to retrieve the :py:class:`tzinfo` subclass + that best represents the time zone that would be used if a POSIX + `TZ variable`_ were set to the same value. + + If no argument or an empty string is passed to ``gettz``, local time + is returned: + + .. code-block:: python3 + + >>> gettz() + tzfile('/etc/localtime') + + This function is also the preferred way to map IANA tz database keys + to :class:`tzfile` objects: + + .. code-block:: python3 + + >>> gettz('Pacific/Kiritimati') + tzfile('/usr/share/zoneinfo/Pacific/Kiritimati') + + On Windows, the standard is extended to include the Windows-specific + zone names provided by the operating system: + + .. code-block:: python3 + + >>> gettz('Egypt Standard Time') + tzwin('Egypt Standard Time') + + Passing a GNU ``TZ`` style string time zone specification returns a + :class:`tzstr` object: + + .. code-block:: python3 + + >>> gettz('AEST-10AEDT-11,M10.1.0/2,M4.1.0/3') + tzstr('AEST-10AEDT-11,M10.1.0/2,M4.1.0/3') + + :param name: + A time zone name (IANA, or, on Windows, Windows keys), location of + a ``tzfile(5)`` zoneinfo file or ``TZ`` variable style time zone + specifier. An empty string, no argument or ``None`` is interpreted + as local time. + + :return: + Returns an instance of one of ``dateutil``'s :py:class:`tzinfo` + subclasses. + + .. versionchanged:: 2.7.0 + + After version 2.7.0, any two calls to ``gettz`` using the same + input strings will return the same object: + + .. code-block:: python3 + + >>> tz.gettz('America/Chicago') is tz.gettz('America/Chicago') + True + + In addition to improving performance, this ensures that + `"same zone" semantics`_ are used for datetimes in the same zone. + + + .. _`TZ variable`: + https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html + + .. _`"same zone" semantics`: + https://blog.ganssle.io/articles/2018/02/aware-datetime-arithmetic.html + """ + def __init__(self): + + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache_size = 8 + self.__strong_cache = OrderedDict() + self._cache_lock = _thread.allocate_lock() + + def __call__(self, name=None): + with self._cache_lock: + rv = self.__instances.get(name, None) + + if rv is None: + rv = self.nocache(name=name) + if not (name is None + or isinstance(rv, tzlocal_classes) + or rv is None): + # tzlocal is slightly more complicated than the other + # time zone providers because it depends on environment + # at construction time, so don't cache that. + # + # We also cannot store weak references to None, so we + # will also not store that. + self.__instances[name] = rv + else: + # No need for strong caching, return immediately + return rv + + self.__strong_cache[name] = self.__strong_cache.pop(name, rv) + + if len(self.__strong_cache) > self.__strong_cache_size: + self.__strong_cache.popitem(last=False) + + return rv + + def set_cache_size(self, size): + with self._cache_lock: + self.__strong_cache_size = size + while len(self.__strong_cache) > size: + self.__strong_cache.popitem(last=False) + + def cache_clear(self): + with self._cache_lock: + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache.clear() + + @staticmethod + def nocache(name=None): + """A non-cached version of gettz""" + tz = None + if not name: + try: + name = os.environ["TZ"] + except KeyError: + pass + if name is None or name in ("", ":"): + for filepath in TZFILES: + if not os.path.isabs(filepath): + filename = filepath + for path in TZPATHS: + filepath = os.path.join(path, filename) + if os.path.isfile(filepath): + break + else: + continue + if os.path.isfile(filepath): + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = tzlocal() + else: + try: + if name.startswith(":"): + name = name[1:] + except TypeError as e: + if isinstance(name, bytes): + new_msg = "gettz argument should be str, not bytes" + six.raise_from(TypeError(new_msg), e) + else: + raise + if os.path.isabs(name): + if os.path.isfile(name): + tz = tzfile(name) + else: + tz = None + else: + for path in TZPATHS: + filepath = os.path.join(path, name) + if not os.path.isfile(filepath): + filepath = filepath.replace(' ', '_') + if not os.path.isfile(filepath): + continue + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = None + if tzwin is not None: + try: + tz = tzwin(name) + except (WindowsError, UnicodeEncodeError): + # UnicodeEncodeError is for Python 2.7 compat + tz = None + + if not tz: + from dateutil.zoneinfo import get_zonefile_instance + tz = get_zonefile_instance().get(name) + + if not tz: + for c in name: + # name is not a tzstr unless it has at least + # one offset. For short values of "name", an + # explicit for loop seems to be the fastest way + # To determine if a string contains a digit + if c in "0123456789": + try: + tz = tzstr(name) + except ValueError: + pass + break + else: + if name in ("GMT", "UTC"): + tz = UTC + elif name in time.tzname: + tz = tzlocal() + return tz + + return GettzFunc() + + +gettz = __get_gettz() +del __get_gettz + + +def datetime_exists(dt, tz=None): + """ + Given a datetime and a time zone, determine whether or not a given datetime + would fall in a gap. + + :param dt: + A :class:`datetime.datetime` (whose time zone will be ignored if ``tz`` + is provided.) + + :param tz: + A :class:`datetime.tzinfo` with support for the ``fold`` attribute. If + ``None`` or not provided, the datetime's own time zone will be used. + + :return: + Returns a boolean value whether or not the "wall time" exists in + ``tz``. + + .. versionadded:: 2.7.0 + """ + if tz is None: + if dt.tzinfo is None: + raise ValueError('Datetime is naive and no time zone provided.') + tz = dt.tzinfo + + dt = dt.replace(tzinfo=None) + + # This is essentially a test of whether or not the datetime can survive + # a round trip to UTC. + dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz) + dt_rt = dt_rt.replace(tzinfo=None) + + return dt == dt_rt + + +def datetime_ambiguous(dt, tz=None): + """ + Given a datetime and a time zone, determine whether or not a given datetime + is ambiguous (i.e if there are two times differentiated only by their DST + status). + + :param dt: + A :class:`datetime.datetime` (whose time zone will be ignored if ``tz`` + is provided.) + + :param tz: + A :class:`datetime.tzinfo` with support for the ``fold`` attribute. If + ``None`` or not provided, the datetime's own time zone will be used. + + :return: + Returns a boolean value whether or not the "wall time" is ambiguous in + ``tz``. + + .. versionadded:: 2.6.0 + """ + if tz is None: + if dt.tzinfo is None: + raise ValueError('Datetime is naive and no time zone provided.') + + tz = dt.tzinfo + + # If a time zone defines its own "is_ambiguous" function, we'll use that. + is_ambiguous_fn = getattr(tz, 'is_ambiguous', None) + if is_ambiguous_fn is not None: + try: + return tz.is_ambiguous(dt) + except Exception: + pass + + # If it doesn't come out and tell us it's ambiguous, we'll just check if + # the fold attribute has any effect on this particular date and time. + dt = dt.replace(tzinfo=tz) + wall_0 = enfold(dt, fold=0) + wall_1 = enfold(dt, fold=1) + + same_offset = wall_0.utcoffset() == wall_1.utcoffset() + same_dst = wall_0.dst() == wall_1.dst() + + return not (same_offset and same_dst) + + +def resolve_imaginary(dt): + """ + Given a datetime that may be imaginary, return an existing datetime. + + This function assumes that an imaginary datetime represents what the + wall time would be in a zone had the offset transition not occurred, so + it will always fall forward by the transition's change in offset. + + .. doctest:: + + >>> from dateutil import tz + >>> from datetime import datetime + >>> NYC = tz.gettz('America/New_York') + >>> print(tz.resolve_imaginary(datetime(2017, 3, 12, 2, 30, tzinfo=NYC))) + 2017-03-12 03:30:00-04:00 + + >>> KIR = tz.gettz('Pacific/Kiritimati') + >>> print(tz.resolve_imaginary(datetime(1995, 1, 1, 12, 30, tzinfo=KIR))) + 1995-01-02 12:30:00+14:00 + + As a note, :func:`datetime.astimezone` is guaranteed to produce a valid, + existing datetime, so a round-trip to and from UTC is sufficient to get + an extant datetime, however, this generally "falls back" to an earlier time + rather than falling forward to the STD side (though no guarantees are made + about this behavior). + + :param dt: + A :class:`datetime.datetime` which may or may not exist. + + :return: + Returns an existing :class:`datetime.datetime`. If ``dt`` was not + imaginary, the datetime returned is guaranteed to be the same object + passed to the function. + + .. versionadded:: 2.7.0 + """ + if dt.tzinfo is not None and not datetime_exists(dt): + + curr_offset = (dt + datetime.timedelta(hours=24)).utcoffset() + old_offset = (dt - datetime.timedelta(hours=24)).utcoffset() + + dt += curr_offset - old_offset + + return dt + + +def _datetime_to_timestamp(dt): + """ + Convert a :class:`datetime.datetime` object to an epoch timestamp in + seconds since January 1, 1970, ignoring the time zone. + """ + return (dt.replace(tzinfo=None) - EPOCH).total_seconds() + + +if sys.version_info >= (3, 6): + def _get_supported_offset(second_offset): + return second_offset +else: + def _get_supported_offset(second_offset): + # For python pre-3.6, round to full-minutes if that's not the case. + # Python's datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 or https://bugs.python.org/issue5288 + # for some information. + old_offset = second_offset + calculated_offset = 60 * ((second_offset + 30) // 60) + return calculated_offset + + +try: + # Python 3.7 feature + from contextlib import nullcontext as _nullcontext +except ImportError: + class _nullcontext(object): + """ + Class for wrapping contexts so that they are passed through in a + with statement. + """ + def __init__(self, context): + self.context = context + + def __enter__(self): + return self.context + + def __exit__(*args, **kwargs): + pass + +# vim:ts=4:sw=4:et diff --git a/.venv/lib/python3.7/site-packages/dateutil/tz/win.py b/.venv/lib/python3.7/site-packages/dateutil/tz/win.py new file mode 100644 index 0000000..cde07ba --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tz/win.py @@ -0,0 +1,370 @@ +# -*- coding: utf-8 -*- +""" +This module provides an interface to the native time zone data on Windows, +including :py:class:`datetime.tzinfo` implementations. + +Attempting to import this module on a non-Windows platform will raise an +:py:obj:`ImportError`. +""" +# This code was originally contributed by Jeffrey Harris. +import datetime +import struct + +from six.moves import winreg +from six import text_type + +try: + import ctypes + from ctypes import wintypes +except ValueError: + # ValueError is raised on non-Windows systems for some horrible reason. + raise ImportError("Running tzwin on non-Windows system") + +from ._common import tzrangebase + +__all__ = ["tzwin", "tzwinlocal", "tzres"] + +ONEWEEK = datetime.timedelta(7) + +TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" +TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" +TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" + + +def _settzkeyname(): + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + try: + winreg.OpenKey(handle, TZKEYNAMENT).Close() + TZKEYNAME = TZKEYNAMENT + except WindowsError: + TZKEYNAME = TZKEYNAME9X + handle.Close() + return TZKEYNAME + + +TZKEYNAME = _settzkeyname() + + +class tzres(object): + """ + Class for accessing ``tzres.dll``, which contains timezone name related + resources. + + .. versionadded:: 2.5.0 + """ + p_wchar = ctypes.POINTER(wintypes.WCHAR) # Pointer to a wide char + + def __init__(self, tzres_loc='tzres.dll'): + # Load the user32 DLL so we can load strings from tzres + user32 = ctypes.WinDLL('user32') + + # Specify the LoadStringW function + user32.LoadStringW.argtypes = (wintypes.HINSTANCE, + wintypes.UINT, + wintypes.LPWSTR, + ctypes.c_int) + + self.LoadStringW = user32.LoadStringW + self._tzres = ctypes.WinDLL(tzres_loc) + self.tzres_loc = tzres_loc + + def load_name(self, offset): + """ + Load a timezone name from a DLL offset (integer). + + >>> from dateutil.tzwin import tzres + >>> tzr = tzres() + >>> print(tzr.load_name(112)) + 'Eastern Standard Time' + + :param offset: + A positive integer value referring to a string from the tzres dll. + + .. note:: + + Offsets found in the registry are generally of the form + ``@tzres.dll,-114``. The offset in this case is 114, not -114. + + """ + resource = self.p_wchar() + lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR) + nchar = self.LoadStringW(self._tzres._handle, offset, lpBuffer, 0) + return resource[:nchar] + + def name_from_string(self, tzname_str): + """ + Parse strings as returned from the Windows registry into the time zone + name as defined in the registry. + + >>> from dateutil.tzwin import tzres + >>> tzr = tzres() + >>> print(tzr.name_from_string('@tzres.dll,-251')) + 'Dateline Daylight Time' + >>> print(tzr.name_from_string('Eastern Standard Time')) + 'Eastern Standard Time' + + :param tzname_str: + A timezone name string as returned from a Windows registry key. + + :return: + Returns the localized timezone string from tzres.dll if the string + is of the form `@tzres.dll,-offset`, else returns the input string. + """ + if not tzname_str.startswith('@'): + return tzname_str + + name_splt = tzname_str.split(',-') + try: + offset = int(name_splt[1]) + except: + raise ValueError("Malformed timezone string.") + + return self.load_name(offset) + + +class tzwinbase(tzrangebase): + """tzinfo class based on win32's timezones available in the registry.""" + def __init__(self): + raise NotImplementedError('tzwinbase is an abstract base class') + + def __eq__(self, other): + # Compare on all relevant dimensions, including name. + if not isinstance(other, tzwinbase): + return NotImplemented + + return (self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset and + self._stddayofweek == other._stddayofweek and + self._dstdayofweek == other._dstdayofweek and + self._stdweeknumber == other._stdweeknumber and + self._dstweeknumber == other._dstweeknumber and + self._stdhour == other._stdhour and + self._dsthour == other._dsthour and + self._stdminute == other._stdminute and + self._dstminute == other._dstminute and + self._std_abbr == other._std_abbr and + self._dst_abbr == other._dst_abbr) + + @staticmethod + def list(): + """Return a list of all time zones known to the system.""" + with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle: + with winreg.OpenKey(handle, TZKEYNAME) as tzkey: + result = [winreg.EnumKey(tzkey, i) + for i in range(winreg.QueryInfoKey(tzkey)[0])] + return result + + def display(self): + """ + Return the display name of the time zone. + """ + return self._display + + def transitions(self, year): + """ + For a given year, get the DST on and off transition times, expressed + always on the standard time side. For zones with no transitions, this + function returns ``None``. + + :param year: + The year whose transitions you would like to query. + + :return: + Returns a :class:`tuple` of :class:`datetime.datetime` objects, + ``(dston, dstoff)`` for zones with an annual DST transition, or + ``None`` for fixed offset zones. + """ + + if not self.hasdst: + return None + + dston = picknthweekday(year, self._dstmonth, self._dstdayofweek, + self._dsthour, self._dstminute, + self._dstweeknumber) + + dstoff = picknthweekday(year, self._stdmonth, self._stddayofweek, + self._stdhour, self._stdminute, + self._stdweeknumber) + + # Ambiguous dates default to the STD side + dstoff -= self._dst_base_offset + + return dston, dstoff + + def _get_hasdst(self): + return self._dstmonth != 0 + + @property + def _dst_base_offset(self): + return self._dst_base_offset_ + + +class tzwin(tzwinbase): + """ + Time zone object created from the zone info in the Windows registry + + These are similar to :py:class:`dateutil.tz.tzrange` objects in that + the time zone data is provided in the format of a single offset rule + for either 0 or 2 time zone transitions per year. + + :param: name + The name of a Windows time zone key, e.g. "Eastern Standard Time". + The full list of keys can be retrieved with :func:`tzwin.list`. + """ + + def __init__(self, name): + self._name = name + + with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle: + tzkeyname = text_type("{kn}\\{name}").format(kn=TZKEYNAME, name=name) + with winreg.OpenKey(handle, tzkeyname) as tzkey: + keydict = valuestodict(tzkey) + + self._std_abbr = keydict["Std"] + self._dst_abbr = keydict["Dlt"] + + self._display = keydict["Display"] + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=3l16h", keydict["TZI"]) + stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 + dstoffset = stdoffset-tup[2] # + DaylightBias * -1 + self._std_offset = datetime.timedelta(minutes=stdoffset) + self._dst_offset = datetime.timedelta(minutes=dstoffset) + + # for the meaning see the win32 TIME_ZONE_INFORMATION structure docs + # http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[4:9] + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[12:17] + + self._dst_base_offset_ = self._dst_offset - self._std_offset + self.hasdst = self._get_hasdst() + + def __repr__(self): + return "tzwin(%s)" % repr(self._name) + + def __reduce__(self): + return (self.__class__, (self._name,)) + + +class tzwinlocal(tzwinbase): + """ + Class representing the local time zone information in the Windows registry + + While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time` + module) to retrieve time zone information, ``tzwinlocal`` retrieves the + rules directly from the Windows registry and creates an object like + :class:`dateutil.tz.tzwin`. + + Because Windows does not have an equivalent of :func:`time.tzset`, on + Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the + time zone settings *at the time that the process was started*, meaning + changes to the machine's time zone settings during the run of a program + on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`. + Because ``tzwinlocal`` reads the registry directly, it is unaffected by + this issue. + """ + def __init__(self): + with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle: + with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey: + keydict = valuestodict(tzlocalkey) + + self._std_abbr = keydict["StandardName"] + self._dst_abbr = keydict["DaylightName"] + + try: + tzkeyname = text_type('{kn}\\{sn}').format(kn=TZKEYNAME, + sn=self._std_abbr) + with winreg.OpenKey(handle, tzkeyname) as tzkey: + _keydict = valuestodict(tzkey) + self._display = _keydict["Display"] + except OSError: + self._display = None + + stdoffset = -keydict["Bias"]-keydict["StandardBias"] + dstoffset = stdoffset-keydict["DaylightBias"] + + self._std_offset = datetime.timedelta(minutes=stdoffset) + self._dst_offset = datetime.timedelta(minutes=dstoffset) + + # For reasons unclear, in this particular key, the day of week has been + # moved to the END of the SYSTEMTIME structure. + tup = struct.unpack("=8h", keydict["StandardStart"]) + + (self._stdmonth, + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[1:5] + + self._stddayofweek = tup[7] + + tup = struct.unpack("=8h", keydict["DaylightStart"]) + + (self._dstmonth, + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[1:5] + + self._dstdayofweek = tup[7] + + self._dst_base_offset_ = self._dst_offset - self._std_offset + self.hasdst = self._get_hasdst() + + def __repr__(self): + return "tzwinlocal()" + + def __str__(self): + # str will return the standard name, not the daylight name. + return "tzwinlocal(%s)" % repr(self._std_abbr) + + def __reduce__(self): + return (self.__class__, ()) + + +def picknthweekday(year, month, dayofweek, hour, minute, whichweek): + """ dayofweek == 0 means Sunday, whichweek 5 means last instance """ + first = datetime.datetime(year, month, 1, hour, minute) + + # This will work if dayofweek is ISO weekday (1-7) or Microsoft-style (0-6), + # Because 7 % 7 = 0 + weekdayone = first.replace(day=((dayofweek - first.isoweekday()) % 7) + 1) + wd = weekdayone + ((whichweek - 1) * ONEWEEK) + if (wd.month != month): + wd -= ONEWEEK + + return wd + + +def valuestodict(key): + """Convert a registry key's values to a dictionary.""" + dout = {} + size = winreg.QueryInfoKey(key)[1] + tz_res = None + + for i in range(size): + key_name, value, dtype = winreg.EnumValue(key, i) + if dtype == winreg.REG_DWORD or dtype == winreg.REG_DWORD_LITTLE_ENDIAN: + # If it's a DWORD (32-bit integer), it's stored as unsigned - convert + # that to a proper signed integer + if value & (1 << 31): + value = value - (1 << 32) + elif dtype == winreg.REG_SZ: + # If it's a reference to the tzres DLL, load the actual string + if value.startswith('@tzres'): + tz_res = tz_res or tzres() + value = tz_res.name_from_string(value) + + value = value.rstrip('\x00') # Remove trailing nulls + + dout[key_name] = value + + return dout diff --git a/.venv/lib/python3.7/site-packages/dateutil/tzwin.py b/.venv/lib/python3.7/site-packages/dateutil/tzwin.py new file mode 100644 index 0000000..cebc673 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/tzwin.py @@ -0,0 +1,2 @@ +# tzwin has moved to dateutil.tz.win +from .tz.win import * diff --git a/.venv/lib/python3.7/site-packages/dateutil/utils.py b/.venv/lib/python3.7/site-packages/dateutil/utils.py new file mode 100644 index 0000000..dd2d245 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/utils.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +""" +This module offers general convenience and utility functions for dealing with +datetimes. + +.. versionadded:: 2.7.0 +""" +from __future__ import unicode_literals + +from datetime import datetime, time + + +def today(tzinfo=None): + """ + Returns a :py:class:`datetime` representing the current day at midnight + + :param tzinfo: + The time zone to attach (also used to determine the current day). + + :return: + A :py:class:`datetime.datetime` object representing the current day + at midnight. + """ + + dt = datetime.now(tzinfo) + return datetime.combine(dt.date(), time(0, tzinfo=tzinfo)) + + +def default_tzinfo(dt, tzinfo): + """ + Sets the ``tzinfo`` parameter on naive datetimes only + + This is useful for example when you are provided a datetime that may have + either an implicit or explicit time zone, such as when parsing a time zone + string. + + .. doctest:: + + >>> from dateutil.tz import tzoffset + >>> from dateutil.parser import parse + >>> from dateutil.utils import default_tzinfo + >>> dflt_tz = tzoffset("EST", -18000) + >>> print(default_tzinfo(parse('2014-01-01 12:30 UTC'), dflt_tz)) + 2014-01-01 12:30:00+00:00 + >>> print(default_tzinfo(parse('2014-01-01 12:30'), dflt_tz)) + 2014-01-01 12:30:00-05:00 + + :param dt: + The datetime on which to replace the time zone + + :param tzinfo: + The :py:class:`datetime.tzinfo` subclass instance to assign to + ``dt`` if (and only if) it is naive. + + :return: + Returns an aware :py:class:`datetime.datetime`. + """ + if dt.tzinfo is not None: + return dt + else: + return dt.replace(tzinfo=tzinfo) + + +def within_delta(dt1, dt2, delta): + """ + Useful for comparing two datetimes that may have a negligible difference + to be considered equal. + """ + delta = abs(delta) + difference = dt1 - dt2 + return -delta <= difference <= delta diff --git a/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__init__.py b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__init__.py new file mode 100644 index 0000000..34f11ad --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__init__.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +import warnings +import json + +from tarfile import TarFile +from pkgutil import get_data +from io import BytesIO + +from dateutil.tz import tzfile as _tzfile + +__all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"] + +ZONEFILENAME = "dateutil-zoneinfo.tar.gz" +METADATA_FN = 'METADATA' + + +class tzfile(_tzfile): + def __reduce__(self): + return (gettz, (self._filename,)) + + +def getzoneinfofile_stream(): + try: + return BytesIO(get_data(__name__, ZONEFILENAME)) + except IOError as e: # TODO switch to FileNotFoundError? + warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror)) + return None + + +class ZoneInfoFile(object): + def __init__(self, zonefile_stream=None): + if zonefile_stream is not None: + with TarFile.open(fileobj=zonefile_stream) as tf: + self.zones = {zf.name: tzfile(tf.extractfile(zf), filename=zf.name) + for zf in tf.getmembers() + if zf.isfile() and zf.name != METADATA_FN} + # deal with links: They'll point to their parent object. Less + # waste of memory + links = {zl.name: self.zones[zl.linkname] + for zl in tf.getmembers() if + zl.islnk() or zl.issym()} + self.zones.update(links) + try: + metadata_json = tf.extractfile(tf.getmember(METADATA_FN)) + metadata_str = metadata_json.read().decode('UTF-8') + self.metadata = json.loads(metadata_str) + except KeyError: + # no metadata in tar file + self.metadata = None + else: + self.zones = {} + self.metadata = None + + def get(self, name, default=None): + """ + Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method + for retrieving zones from the zone dictionary. + + :param name: + The name of the zone to retrieve. (Generally IANA zone names) + + :param default: + The value to return in the event of a missing key. + + .. versionadded:: 2.6.0 + + """ + return self.zones.get(name, default) + + +# The current API has gettz as a module function, although in fact it taps into +# a stateful class. So as a workaround for now, without changing the API, we +# will create a new "global" class instance the first time a user requests a +# timezone. Ugly, but adheres to the api. +# +# TODO: Remove after deprecation period. +_CLASS_ZONE_INSTANCE = [] + + +def get_zonefile_instance(new_instance=False): + """ + This is a convenience function which provides a :class:`ZoneInfoFile` + instance using the data provided by the ``dateutil`` package. By default, it + caches a single instance of the ZoneInfoFile object and returns that. + + :param new_instance: + If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and + used as the cached instance for the next call. Otherwise, new instances + are created only as necessary. + + :return: + Returns a :class:`ZoneInfoFile` object. + + .. versionadded:: 2.6 + """ + if new_instance: + zif = None + else: + zif = getattr(get_zonefile_instance, '_cached_instance', None) + + if zif is None: + zif = ZoneInfoFile(getzoneinfofile_stream()) + + get_zonefile_instance._cached_instance = zif + + return zif + + +def gettz(name): + """ + This retrieves a time zone from the local zoneinfo tarball that is packaged + with dateutil. + + :param name: + An IANA-style time zone name, as found in the zoneinfo file. + + :return: + Returns a :class:`dateutil.tz.tzfile` time zone object. + + .. warning:: + It is generally inadvisable to use this function, and it is only + provided for API compatibility with earlier versions. This is *not* + equivalent to ``dateutil.tz.gettz()``, which selects an appropriate + time zone based on the inputs, favoring system zoneinfo. This is ONLY + for accessing the dateutil-specific zoneinfo (which may be out of + date compared to the system zoneinfo). + + .. deprecated:: 2.6 + If you need to use a specific zoneinfofile over the system zoneinfo, + instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call + :func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead. + + Use :func:`get_zonefile_instance` to retrieve an instance of the + dateutil-provided zoneinfo. + """ + warnings.warn("zoneinfo.gettz() will be removed in future versions, " + "to use the dateutil-provided zoneinfo files, instantiate a " + "ZoneInfoFile object and use ZoneInfoFile.zones.get() " + "instead. See the documentation for details.", + DeprecationWarning) + + if len(_CLASS_ZONE_INSTANCE) == 0: + _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) + return _CLASS_ZONE_INSTANCE[0].zones.get(name) + + +def gettz_db_metadata(): + """ Get the zonefile metadata + + See `zonefile_metadata`_ + + :returns: + A dictionary with the database metadata + + .. deprecated:: 2.6 + See deprecation warning in :func:`zoneinfo.gettz`. To get metadata, + query the attribute ``zoneinfo.ZoneInfoFile.metadata``. + """ + warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future " + "versions, to use the dateutil-provided zoneinfo files, " + "ZoneInfoFile object and query the 'metadata' attribute " + "instead. See the documentation for details.", + DeprecationWarning) + + if len(_CLASS_ZONE_INSTANCE) == 0: + _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) + return _CLASS_ZONE_INSTANCE[0].metadata diff --git a/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fbb275955e71d99c3d377931fd79f321b515b97 GIT binary patch literal 5597 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/rebuild.cpython-37.pyc b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/__pycache__/rebuild.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e69a419cd45e24945d985ee378938fd98c4cdec GIT binary patch literal 2560 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 z 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 z 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

oF5%wc?0lVIdiCvTMwKQ}m1M4pzSU2C#ISwFq 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
oHJaZa%&cRgbKqQScY`o5It4F}rqGD>-kDeG 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/rebuild.py b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/rebuild.py new file mode 100644 index 0000000..684c658 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/dateutil/zoneinfo/rebuild.py @@ -0,0 +1,75 @@ +import logging +import os +import tempfile +import shutil +import json +from subprocess import check_call, check_output +from tarfile import TarFile + +from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME + + +def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None): + """Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar* + + filename is the timezone tarball from ``ftp.iana.org/tz``. + + """ + tmpdir = tempfile.mkdtemp() + zonedir = os.path.join(tmpdir, "zoneinfo") + moduledir = os.path.dirname(__file__) + try: + with TarFile.open(filename) as tf: + for name in zonegroups: + tf.extract(name, tmpdir) + filepaths = [os.path.join(tmpdir, n) for n in zonegroups] + + _run_zic(zonedir, filepaths) + + # write metadata file + with open(os.path.join(zonedir, METADATA_FN), 'w') as f: + json.dump(metadata, f, indent=4, sort_keys=True) + target = os.path.join(moduledir, ZONEFILENAME) + with TarFile.open(target, "w:%s" % format) as tf: + for entry in os.listdir(zonedir): + entrypath = os.path.join(zonedir, entry) + tf.add(entrypath, entry) + finally: + shutil.rmtree(tmpdir) + + +def _run_zic(zonedir, filepaths): + """Calls the ``zic`` compiler in a compatible way to get a "fat" binary. + + Recent versions of ``zic`` default to ``-b slim``, while older versions + don't even have the ``-b`` option (but default to "fat" binaries). The + current version of dateutil does not support Version 2+ TZif files, which + causes problems when used in conjunction with "slim" binaries, so this + function is used to ensure that we always get a "fat" binary. + """ + + try: + help_text = check_output(["zic", "--help"]) + except OSError as e: + _print_on_nosuchfile(e) + raise + + if b"-b " in help_text: + bloat_args = ["-b", "fat"] + else: + bloat_args = [] + + check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths) + + +def _print_on_nosuchfile(e): + """Print helpful troubleshooting message + + e is an exception raised by subprocess.check_call() + + """ + if e.errno == 2: + logging.error( + "Could not find zic. Perhaps you need to install " + "libc-bin or some other package that provides it, " + "or it's not in your PATH?") diff --git a/.venv/lib/python3.7/site-packages/easy_install.py b/.venv/lib/python3.7/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/easy_install.py @@ -0,0 +1,5 @@ +"""Run the EasyInstall command""" + +if __name__ == '__main__': + from setuptools.command.easy_install import main + main() diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/LICENSE b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/LICENSE new file mode 100644 index 0000000..7082a2d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2019 Nikolay Kim and Andrew Svetlov + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/METADATA b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/METADATA new file mode 100644 index 0000000..235aca1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/METADATA @@ -0,0 +1,150 @@ +Metadata-Version: 2.1 +Name: frozenlist +Version: 1.3.3 +Summary: A list-like structure which implements collections.abc.MutableSequence +Home-page: https://github.com/aio-libs/frozenlist +Maintainer: aiohttp team +Maintainer-email: team@aiohttp.org +License: Apache 2 +Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby +Project-URL: CI: Github Actions, https://github.com/aio-libs/frozenlist/actions +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/frozenlist +Project-URL: Docs: RTD, https://frozenlist.readthedocs.io +Project-URL: GitHub: issues, https://github.com/aio-libs/frozenlist/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/frozenlist +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE + +========== +frozenlist +========== + +.. image:: https://github.com/aio-libs/frozenlist/workflows/CI/badge.svg + :target: https://github.com/aio-libs/frozenlist/actions + :alt: GitHub status for master branch + +.. image:: https://codecov.io/gh/aio-libs/frozenlist/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/frozenlist + :alt: codecov.io status for master branch + +.. image:: https://badge.fury.io/py/frozenlist.svg + :target: https://pypi.org/project/frozenlist + :alt: Latest PyPI package version + +.. image:: https://readthedocs.org/projects/frozenlist/badge/?version=latest + :target: https://frozenlist.readthedocs.io/ + :alt: Latest Read The Docs + +.. image:: https://img.shields.io/discourse/topics?server=https%3A%2F%2Faio-libs.discourse.group%2F + :target: https://aio-libs.discourse.group/ + :alt: Discourse group for io-libs + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :target: https://gitter.im/aio-libs/Lobby + :alt: Chat on Gitter + +Introduction +============ + +``frozenlist.FrozenList`` is a list-like structure which implements +``collections.abc.MutableSequence``. The list is *mutable* until ``FrozenList.freeze`` +is called, after which list modifications raise ``RuntimeError``: + + +>>> from frozenlist import FrozenList +>>> fl = FrozenList([17, 42]) +>>> fl.append('spam') +>>> fl.append('Vikings') +>>> fl + +>>> fl.freeze() +>>> fl + +>>> fl.frozen +True +>>> fl.append("Monty") +Traceback (most recent call last): + File "", line 1, in + File "frozenlist/_frozenlist.pyx", line 97, in frozenlist._frozenlist.FrozenList.append + self._check_frozen() + File "frozenlist/_frozenlist.pyx", line 19, in frozenlist._frozenlist.FrozenList._check_frozen + raise RuntimeError("Cannot modify frozen list.") +RuntimeError: Cannot modify frozen list. + + +FrozenList is also hashable, but only when frozen. Otherwise it also throws a RuntimeError: + + +>>> fl = FrozenList([17, 42, 'spam']) +>>> hash(fl) +Traceback (most recent call last): + File "", line 1, in + File "frozenlist/_frozenlist.pyx", line 111, in frozenlist._frozenlist.FrozenList.__hash__ + raise RuntimeError("Cannot hash unfrozen list.") +RuntimeError: Cannot hash unfrozen list. +>>> fl.freeze() +>>> hash(fl) +3713081631934410656 +>>> dictionary = {fl: 'Vikings'} # frozen fl can be a dict key +>>> dictionary +{: 'Vikings'} + + +Installation +------------ + +:: + + $ pip install frozenlist + +The library requires Python 3.6 or newer. + + +Documentation +============= + +https://frozenlist.readthedocs.io/ + +Communication channels +====================== + +*aio-libs discourse group*: https://aio-libs.discourse.group + +Feel free to post your questions and ideas here. + +*gitter chat* https://gitter.im/aio-libs/Lobby + +Requirements +============ + +- Python >= 3.6 + +License +======= + +``frozenlist`` is offered under the Apache 2 license. + +Source code +=========== + +The project is hosted on GitHub_ + +Please file an issue in the `bug tracker +`_ if you have found a bug +or have some suggestions to improve the library. + +.. _GitHub: https://github.com/aio-libs/frozenlist diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/RECORD b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/RECORD new file mode 100644 index 0000000..1bce5d0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/RECORD @@ -0,0 +1,12 @@ +frozenlist-1.3.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +frozenlist-1.3.3.dist-info/LICENSE,sha256=b9UkPpLdf5jsacesN3co50kFcJ_1J6W_mNbQJjwE9bY,11332 +frozenlist-1.3.3.dist-info/METADATA,sha256=f8FI9mzqEFVV4IHXvWrRk8BuLIAwRWGJuYewaEidVQg,4693 +frozenlist-1.3.3.dist-info/RECORD,, +frozenlist-1.3.3.dist-info/WHEEL,sha256=x0i66VqxRbBKupkIfHJDo86EGC-49cTnqAuD6eBXSU0,104 +frozenlist-1.3.3.dist-info/top_level.txt,sha256=jivtxsPXA3nK3WBWW2LW5Mtu_GHt8UZA13NeCs2cKuA,11 +frozenlist/__init__.py,sha256=yf1hVJQUEyUwzTJau3i3SQeFDYYROwgNpJLMzHN58tM,2323 +frozenlist/__init__.pyi,sha256=vMEoES1xGegPtVXoCi9XydEeHsyuIq-KdeXwP5PdsaA,1470 +frozenlist/__pycache__/__init__.cpython-37.pyc,, +frozenlist/_frozenlist.cpython-37m-arm-linux-gnueabihf.so,sha256=1kh8mxMQdP2p1Qm22wTbTqh_ZaONzNnv-mTeVQwBQhc,149408 +frozenlist/_frozenlist.pyx,sha256=9V4Z1En6TZwgFD26d-sjxyhUzUm338H1Qiz4-i5ukv0,2983 +frozenlist/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/WHEEL new file mode 100644 index 0000000..75b7986 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.2) +Root-Is-Purelib: false +Tag: cp37-cp37m-linux_armv7l + diff --git a/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/top_level.txt new file mode 100644 index 0000000..52f13fc --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist-1.3.3.dist-info/top_level.txt @@ -0,0 +1 @@ +frozenlist diff --git a/.venv/lib/python3.7/site-packages/frozenlist/__init__.py b/.venv/lib/python3.7/site-packages/frozenlist/__init__.py new file mode 100644 index 0000000..4f172e7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist/__init__.py @@ -0,0 +1,96 @@ +import os +import sys +import types +from collections.abc import MutableSequence +from functools import total_ordering +from typing import Tuple, Type + +__version__ = "1.3.3" + +__all__ = ("FrozenList", "PyFrozenList") # type: Tuple[str, ...] + + +NO_EXTENSIONS = bool(os.environ.get("FROZENLIST_NO_EXTENSIONS")) # type: bool + + +@total_ordering +class FrozenList(MutableSequence): + + __slots__ = ("_frozen", "_items") + + if sys.version_info >= (3, 9): + __class_getitem__ = classmethod(types.GenericAlias) + else: + + @classmethod + def __class_getitem__(cls: Type["FrozenList"]) -> Type["FrozenList"]: + return cls + + def __init__(self, items=None): + self._frozen = False + if items is not None: + items = list(items) + else: + items = [] + self._items = items + + @property + def frozen(self): + return self._frozen + + def freeze(self): + self._frozen = True + + def __getitem__(self, index): + return self._items[index] + + def __setitem__(self, index, value): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + self._items[index] = value + + def __delitem__(self, index): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + del self._items[index] + + def __len__(self): + return self._items.__len__() + + def __iter__(self): + return self._items.__iter__() + + def __reversed__(self): + return self._items.__reversed__() + + def __eq__(self, other): + return list(self) == other + + def __le__(self, other): + return list(self) <= other + + def insert(self, pos, item): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + self._items.insert(pos, item) + + def __repr__(self): + return f"" + + def __hash__(self): + if self._frozen: + return hash(tuple(self)) + else: + raise RuntimeError("Cannot hash unfrozen list.") + + +PyFrozenList = FrozenList + + +try: + from ._frozenlist import FrozenList as CFrozenList # type: ignore + + if not NO_EXTENSIONS: # pragma: no cover + FrozenList = CFrozenList # type: ignore +except ImportError: # pragma: no cover + pass diff --git a/.venv/lib/python3.7/site-packages/frozenlist/__init__.pyi b/.venv/lib/python3.7/site-packages/frozenlist/__init__.pyi new file mode 100644 index 0000000..ae803ef --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist/__init__.pyi @@ -0,0 +1,47 @@ +from typing import ( + Generic, + Iterable, + Iterator, + List, + MutableSequence, + Optional, + TypeVar, + Union, + overload, +) + +_T = TypeVar("_T") +_Arg = Union[List[_T], Iterable[_T]] + +class FrozenList(MutableSequence[_T], Generic[_T]): + def __init__(self, items: Optional[_Arg[_T]] = None) -> None: ... + @property + def frozen(self) -> bool: ... + def freeze(self) -> None: ... + @overload + def __getitem__(self, i: int) -> _T: ... + @overload + def __getitem__(self, s: slice) -> FrozenList[_T]: ... + @overload + def __setitem__(self, i: int, o: _T) -> None: ... + @overload + def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... + @overload + def __delitem__(self, i: int) -> None: ... + @overload + def __delitem__(self, i: slice) -> None: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[_T]: ... + def __reversed__(self) -> Iterator[_T]: ... + def __eq__(self, other: object) -> bool: ... + def __le__(self, other: FrozenList[_T]) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __lt__(self, other: FrozenList[_T]) -> bool: ... + def __ge__(self, other: FrozenList[_T]) -> bool: ... + def __gt__(self, other: FrozenList[_T]) -> bool: ... + def insert(self, pos: int, item: _T) -> None: ... + def __repr__(self) -> str: ... + def __hash__(self) -> int: ... + +# types for C accelerators are the same +CFrozenList = PyFrozenList = FrozenList diff --git a/.venv/lib/python3.7/site-packages/frozenlist/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/frozenlist/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc9016c3924073c158ab786b39010dad1ccd7059 GIT binary patch literal 3272 zcmb7GTW=Fb6yDigJ8OHBIQI(y0<={vK_W`~P&H5rN?If^h(s#gmyz*I5-00jGrLBO zWggl@{S#0L`qqEYe^O~*`;@=Xr+#PFjxRW(>}u!Cb0MUP_tA^w{)FP}8^Swr4Y1v;0gw>t%J{_Q&du=hSmv4&#iM z7g?_$U1=PQznu_c@7OW(CS~?}LpUOLVu+lyk1fmLv@TcoVZ-yCiGWt!< zc*P%$VAeL|>|tKLVFtZF8G-o>vTYkB_Y`s(De)wQ} zhnFAo&1XBCm4Rc7VbfdfTz!3z3$ zVJsPGE37xButny?rd4rGj0xw25ojVO@+Ssn$3;Q7Cx$m6#>E8aq?i;%(4v?U)1Xsg zM$Cdvi#ah5IwKauBIvAG63d`-;(}NKofj9yCC~+NS*(ICiYwwO=#t0+%1=}l;scH` zzN_&_vb+|{dQ>t`Ev%fvS7_O)`caZqGH$A%$}mR{QTp!ViwKXlfnT!npJM z|9-O`*Bk4NTH{77h+rW9hX2K_Xz#0=we^&-4@2~KIj;q^nDe#9Q8LAO)vrVm-;*&( z$N3VmG|?DlYo%wqwf8obt9lo0?0j0<&oB_IZE&Lv!yV?-V$9m`(^o98_l#HQV+}qJ zea!M!$x;*}iA_SP4kUIY{oN#^(dsFxCTXM7mHr||k&Zl;We&@mHfzlc$eU_88dI`O z+c-#31*Rkf$TY|>$83t?r^K&=%Tynqbaj9W?b29~cqtYgeRn>{O3Icjov~uAK~}Un z8g^nu3bonNnNlg7S}C9z2>J7{ZUx>m{PjMr^L+~TZK;yu(nFL!t>p?j#9B?nOu*8= zvbKq_*=8HaXWGuK<@=Q&2;~x}Lj^Z4nvP&>qnmRN`#gX#AFOY)A>M!tIYxK~d~Z(oHFIPf?#qDl(GIOBa=s?U+M8KxdcfHFi=L#_c6m&+|N?2;;$nZ`jYd_a~aa=KQpJdCN~ej{2&2R%e;*QDUBmJZ`1&KDAFA{} z1CEiwb}jilI+R)ujMpfiK-p_kSiff=uU&4raodQkG&v4qx?hR*SDQg9WhW)3 zm?k!@C7GD2EDiAJh^9-Cc5?oN>%=%XB2D)ZrLOo^xd7COJuhsCvRfIH( zET(4BBu+zx4LHV;nxi?gpjxEn0yT7t=+vYLK1H#su26H88gdmyrG=u)vColo9YmFZ zF1LtdMB5z8HuKE2Otx(09oKd&ycxVi(-(bx=9CI8086ly<`OfE)Ec_#CYofj8v4Gh z#?U%it30nNa)ujx))a3|`h$ z7$g>oE^mCG5Y|$tG5p6Xbm~UBB)!7@ov2lYm%;`E|CD+E(e(jsXiwdfsEEg}FN clt>P9@fJXg+w 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

(tmA|zb;7b(PW^J)DaRI(Y|OLz=Ce9y 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 (3, 9): + __class_getitem__ = classmethod(types.GenericAlias) + else: + @classmethod + def __class_getitem__(cls): + return cls + + cdef readonly bint frozen + cdef list _items + + def __init__(self, items=None): + self.frozen = False + if items is not None: + items = list(items) + else: + items = [] + self._items = items + + cdef object _check_frozen(self): + if self.frozen: + raise RuntimeError("Cannot modify frozen list.") + + cdef inline object _fast_len(self): + return len(self._items) + + def freeze(self): + self.frozen = True + + def __getitem__(self, index): + return self._items[index] + + def __setitem__(self, index, value): + self._check_frozen() + self._items[index] = value + + def __delitem__(self, index): + self._check_frozen() + del self._items[index] + + def __len__(self): + return self._fast_len() + + def __iter__(self): + return self._items.__iter__() + + def __reversed__(self): + return self._items.__reversed__() + + def __richcmp__(self, other, op): + if op == 0: # < + return list(self) < other + if op == 1: # <= + return list(self) <= other + if op == 2: # == + return list(self) == other + if op == 3: # != + return list(self) != other + if op == 4: # > + return list(self) > other + if op == 5: # => + return list(self) >= other + + def insert(self, pos, item): + self._check_frozen() + self._items.insert(pos, item) + + def __contains__(self, item): + return item in self._items + + def __iadd__(self, items): + self._check_frozen() + self._items += list(items) + return self + + def index(self, item): + return self._items.index(item) + + def remove(self, item): + self._check_frozen() + self._items.remove(item) + + def clear(self): + self._check_frozen() + self._items.clear() + + def extend(self, items): + self._check_frozen() + self._items += list(items) + + def reverse(self): + self._check_frozen() + self._items.reverse() + + def pop(self, index=-1): + self._check_frozen() + return self._items.pop(index) + + def append(self, item): + self._check_frozen() + return self._items.append(item) + + def count(self, item): + return self._items.count(item) + + def __repr__(self): + return ''.format(self.frozen, + self._items) + + def __hash__(self): + if self.frozen: + return hash(tuple(self._items)) + else: + raise RuntimeError("Cannot hash unfrozen list.") + + +MutableSequence.register(FrozenList) diff --git a/.venv/lib/python3.7/site-packages/frozenlist/py.typed b/.venv/lib/python3.7/site-packages/frozenlist/py.typed new file mode 100644 index 0000000..f5642f7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/frozenlist/py.typed @@ -0,0 +1 @@ +Marker diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/LICENSE.rst b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..37188b7 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/LICENSE.rst @@ -0,0 +1,27 @@ +SPDX-License-Identifier: BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/METADATA b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/METADATA new file mode 100644 index 0000000..f26d2a6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/METADATA @@ -0,0 +1,261 @@ +Metadata-Version: 2.1 +Name: gpiozero +Version: 1.6.2 +Summary: A simple interface to GPIO devices with Raspberry Pi. +Home-page: https://github.com/gpiozero/gpiozero +Author: Ben Nuttall +Author-email: ben@bennuttall.com +License: BSD-3-Clause +Keywords: raspberrypi,gpio +Platform: ALL +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: Developers +Classifier: Topic :: Education +Classifier: Topic :: System :: Hardware +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Dist: colorzero +Provides-Extra: doc +Requires-Dist: sphinx ; extra == 'doc' +Requires-Dist: sphinx-rtd-theme ; extra == 'doc' +Provides-Extra: test +Requires-Dist: pytest ; extra == 'test' +Requires-Dist: coverage ; extra == 'test' +Requires-Dist: mock ; extra == 'test' +Requires-Dist: RPi.GPIO ; extra == 'test' +Requires-Dist: pigpio ; extra == 'test' + +======== +gpiozero +======== + +A simple interface to GPIO devices with `Raspberry Pi`_, developed and maintained +by `Ben Nuttall`_ and `Dave Jones`_. + +.. _Raspberry Pi: https://www.raspberrypi.org/ +.. _Ben Nuttall: https://github.com/bennuttall +.. _Dave Jones: https://github.com/waveform80 + +About +===== + +Component interfaces are provided to allow a frictionless way to get started +with physical computing: + +.. code:: python + + from gpiozero import LED + from time import sleep + + led = LED(17) + + while True: + led.on() + sleep(1) + led.off() + sleep(1) + +With very little code, you can quickly get going connecting your components +together: + +.. code:: python + + from gpiozero import LED, Button + from signal import pause + + led = LED(17) + button = Button(3) + + button.when_pressed = led.on + button.when_released = led.off + + pause() + +You can advance to using the declarative paradigm along with provided +to describe the behaviour of devices and their interactions: + +.. code:: python + + from gpiozero import OutputDevice, MotionSensor, LightSensor + from gpiozero.tools import booleanized, all_values + from signal import pause + + garden = OutputDevice(17) + motion = MotionSensor(4) + light = LightSensor(5) + + garden.source = all_values(booleanized(light, 0, 0.1), motion) + + pause() + +See the chapter on `Source/Values`_ for more information. + +.. _Source/Values: https://gpiozero.readthedocs.io/en/stable/source_values.html + +The library includes interfaces to many simple everyday components, as well as +some more complex things like sensors, analogue-to-digital converters, full +colour LEDs, robotics kits and more. See the `Recipes`_ chapter of the +documentation for ideas on how to get started. + +.. _Recipes: https://gpiozero.readthedocs.io/en/stable/recipes.html + +Pin factories +============= + +GPIO Zero builds on a number of underlying pin libraries, including `RPi.GPIO`_ +and `pigpio`_, each with their own benefits. You can select a particular pin +library to be used, either for the whole script or per-device, according to your +needs. See the section on `changing the pin factory`_. + +.. _RPi.GPIO: https://pypi.org/project/RPi.GPIO +.. _pigpio: https://pypi.org/project/pigpio +.. _changing the pin factory: https://gpiozero.readthedocs.io/en/stable/api_pins.html#changing-the-pin-factory + +A "mock pin" interface is also provided for testing purposes. Read more about +this in the section on `mock pins`_. + +.. _mock pins: https://gpiozero.readthedocs.io/en/stable/api_pins.html#mock-pins + +Installation +============ + +GPIO Zero is installed by default in the Raspberry Pi OS desktop image, +available from `raspberrypi.org`_. To install on Raspberry Pi OS Lite or other +operating systems, including for PCs using remote GPIO, see the `Installing`_ +chapter. + +.. _raspberrypi.org: https://www.raspberrypi.org/software/ +.. _Installing: https://gpiozero.readthedocs.io/en/stable/installing.html + +Documentation +============= + +Comprehensive documentation is available at https://gpiozero.readthedocs.io/. +Please refer to the `Contributing`_ and `Development`_ chapters in the +documentation for information on contributing to the project. + +.. _Contributing: https://gpiozero.readthedocs.io/en/stable/contributing.html +.. _Development: https://gpiozero.readthedocs.io/en/stable/development.html + +Issues and questions +==================== + +If you have a feature request or bug report, please open an `issue on GitHub`_. +If you have a question or need help, this may be better suited to our `GitHub +discussion board`_, the `Raspberry Pi Stack Exchange`_ or the `Raspberry Pi +Forums`_. + +.. _issue on GitHub: https://github.com/gpiozero/gpiozero/issues/new +.. _GitHub discussion board: https://github.com/gpiozero/gpiozero/discussions +.. _Raspberry Pi Stack Exchange: https://raspberrypi.stackexchange.com/ +.. _Raspberry Pi Forums: https://www.raspberrypi.org/forums/ + +Python 2 support +================ + +.. warning:: + + GPIO Zero 1.6.x is the last to support Python 2. GPIO Zero 2.x will support + Python 3 only. + +Contributors +============ + +- `Alex Chan`_ +- `Alex Eames`_ +- `Andrew Scheller`_ +- `Barry Byford`_ +- `Carl Monk`_ +- `Claire Pollard`_ +- `Clare Macrae`_ +- `Dan Jackson`_ +- `Daniele Procida`_ +- `damosurfer`_ +- `David Glaude`_ +- `Delcio Torres`_ +- `Edward Betts`_ +- `Fatih Sarhan`_ +- `G.S.`_ +- `Ian Harcombe`_ +- `Jack Wearden`_ +- `Jeevan M R`_ +- `Josh Thorpe`_ +- `Kyle Morgan`_ +- `Linus Groh`_ +- `Mahallon`_ +- `Maksim Levental`_ +- `Martchus`_ +- `Martin O'Hanlon`_ +- `Mike Kazantsev`_ +- `Paulo Mateus`_ +- `Phil Howard`_ +- `Philippe Muller`_ +- `Rick Ansell`_ +- `Robert Erdin`_ +- `Russel Winder`_ +- `Ryan Walmsley`_ +- `Schelto van Doorn`_ +- `Sofiia Kosovan`_ +- `Steve Amor`_ +- `Stewart Adcock`_ +- `Thijs Triemstra`_ +- `Tim Golden`_ +- `Yisrael Dov Lebow`_ + +See the `contributors page`_ on GitHub for more info. + +.. _Alex Chan: https://github.com/gpiozero/gpiozero/commits?author=alexwlchan +.. _Alex Eames: https://github.com/gpiozero/gpiozero/commits?author=raspitv +.. _Andrew Scheller: https://github.com/gpiozero/gpiozero/commits?author=lurch +.. _Barry Byford: https://github.com/gpiozero/gpiozero/commits?author=ukBaz +.. _Carl Monk: https://github.com/gpiozero/gpiozero/commits?author=ForToffee +.. _Chris R: https://github.com/gpiozero/gpiozero/commits?author=chrisruk +.. _Claire Pollard: https://github.com/gpiozero/gpiozero/commits?author=tuftii +.. _Clare Macrae: https://github.com/gpiozero/gpiozero/commits?author=claremacrae +.. _Dan Jackson: https://github.com/gpiozero/gpiozero/commits?author=e28eta +.. _Daniele Procida: https://github.com/evildmp +.. _Dariusz Kowalczyk: https://github.com/gpiozero/gpiozero/commits?author=darton +.. _damosurfer: https://github.com/gpiozero/gpiozero/commits?author=damosurfer +.. _David Glaude: https://github.com/gpiozero/gpiozero/commits?author=dglaude +.. _Delcio Torres: https://github.com/gpiozero/gpiozero/commits?author=delciotorres +.. _Edward Betts: https://github.com/gpiozero/gpiozero/commits?author=edwardbetts +.. _Fatih Sarhan: https://github.com/gpiozero/gpiozero/commits?author=f9n +.. _G.S.: https://github.com/gpiozero/gpiozero/commits?author=gszy +.. _Ian Harcombe: https://github.com/gpiozero/gpiozero/commits?author=MrHarcombe +.. _Jack Wearden: https://github.com/gpiozero/gpiozero/commits?author=NotBobTheBuilder +.. _Jeevan M R: https://github.com/gpiozero/gpiozero/commits?author=jee1mr +.. _Josh Thorpe: https://github.com/gpiozero/gpiozero/commits?author=ThorpeJosh +.. _Kyle Morgan: https://github.com/gpiozero/gpiozero/commits?author=knmorgan +.. _Linus Groh: https://github.com/gpiozero/gpiozero/commits?author=linusg +.. _Mahallon: https://github.com/gpiozero/gpiozero/commits?author=Mahallon +.. _Maksim Levental: https://github.com/gpiozero/gpiozero/commits?author=makslevental +.. _Martchus: https://github.com/gpiozero/gpiozero/commits?author=Martchus +.. _Martin O'Hanlon: https://github.com/martinohanlon/commits?author=martinohanlon +.. _Mike Kazantsev: https://github.com/gpiozero/gpiozero/commits?author=mk-fg +.. _Paulo Mateus: https://github.com/gpiozero/gpiozero/commits?author=SrMouraSilva +.. _Phil Howard: https://github.com/gpiozero/gpiozero/commits?author=Gadgetoid +.. _Philippe Muller: https://github.com/gpiozero/gpiozero/commits?author=pmuller +.. _Rick Ansell: https://github.com/gpiozero/gpiozero/commits?author=ricksbt +.. _Robert Erdin: https://github.com/gpiozero/gpiozero/commits?author=roberterdin +.. _Russel Winder: https://github.com/russel +.. _Ryan Walmsley: https://github.com/gpiozero/gpiozero/commits?author=ryanteck +.. _Schelto van Doorn: https://github.com/gpiozero/gpiozero/commits?author=goloplo +.. _Sofiia Kosovan: https://github.com/gpiozero/gpiozero/commits?author=SofiiaKosovan +.. _Steve Amor: https://github.com/gpiozero/gpiozero/commits?author=SteveAmor +.. _Stewart Adcock: https://github.com/gpiozero/gpiozero/commits?author=stewartadcock +.. _Thijs Triemstra: https://github.com/gpiozero/gpiozero/commits?author=thijstriemstra +.. _Tim Golden: https://github.com/gpiozero/gpiozero/commits?author=tjguk +.. _Yisrael Dov Lebow: https://github.com/gpiozero/gpiozero/commits?author=yisraeldov + +.. _contributors page: https://github.com/gpiozero/gpiozero/graphs/contributors + + diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/RECORD b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/RECORD new file mode 100644 index 0000000..57e43e0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/RECORD @@ -0,0 +1,64 @@ +../../../bin/pinout,sha256=MG2kV8UUrvmbJUjD7rliCP6J8gRPgEMeFrSyiXO-j-g,238 +gpiozero-1.6.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +gpiozero-1.6.2.dist-info/LICENSE.rst,sha256=tv3Vh_PcOpuMxa2uAJGOP_qQmxCSvU3s9-ixsI-l0Ps,1474 +gpiozero-1.6.2.dist-info/METADATA,sha256=YHQBj216E4u0fQ3_L8AiAk9iBJh_wQANcYGjQQ_WooY,9595 +gpiozero-1.6.2.dist-info/RECORD,, +gpiozero-1.6.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 +gpiozero-1.6.2.dist-info/entry_points.txt,sha256=vr8Ohk0-ul8CrE8uHszL8jO8Dc9idwKIK6V6RBJZSRU,728 +gpiozero-1.6.2.dist-info/top_level.txt,sha256=eY0E5NV30JrC-UrQZGpXUe_tuWplAuScNI10Pm9_Tf0,21 +gpiozero/__init__.py,sha256=iTa348d1Db4zvVbnHZHCKJtB2Atbnuy_dT288aPmB2Q,2767 +gpiozero/__pycache__/__init__.cpython-37.pyc,, +gpiozero/__pycache__/boards.cpython-37.pyc,, +gpiozero/__pycache__/compat.cpython-37.pyc,, +gpiozero/__pycache__/devices.cpython-37.pyc,, +gpiozero/__pycache__/exc.cpython-37.pyc,, +gpiozero/__pycache__/fonts.cpython-37.pyc,, +gpiozero/__pycache__/input_devices.cpython-37.pyc,, +gpiozero/__pycache__/internal_devices.cpython-37.pyc,, +gpiozero/__pycache__/mixins.cpython-37.pyc,, +gpiozero/__pycache__/output_devices.cpython-37.pyc,, +gpiozero/__pycache__/spi_devices.cpython-37.pyc,, +gpiozero/__pycache__/threads.cpython-37.pyc,, +gpiozero/__pycache__/tones.cpython-37.pyc,, +gpiozero/__pycache__/tools.cpython-37.pyc,, +gpiozero/boards.py,sha256=GcajC3uxHuvEe9_4Btfmwo8j42YBRSxvNtDLMcYtBFo,107974 +gpiozero/compat.py,sha256=zmvg9OiR2m6K1DINaiAPFAoIJa8k2CvH0rVn5upnfrI,4695 +gpiozero/devices.py,sha256=qnM1kLyiVJTtv06RyCnQuDpGhF6CoWmWPj3kLH1rq3o,25144 +gpiozero/exc.py,sha256=LP2v0_8qS7hHFLi0S9T6dnS9ru2Ae4IoIeIwfjmBJHY,7691 +gpiozero/fonts.py,sha256=0V2X6GciBxy3wpkwqaBjgE1aSKqzX7QIHNfPuPeq5uQ,9408 +gpiozero/fonts/14seg.txt,sha256=VAzTbA13Wp5C_Nv8Yw8d0DOK181_-4tuZyTC5OjzENc,2711 +gpiozero/fonts/7seg.txt,sha256=oWrQeNWba7mglb0Vk_T9bHOMfSMeSDNNcPVH_zvWSKc,1112 +gpiozero/input_devices.py,sha256=voV_rzp-Q-q6wBvc-yV9SYobPgo6_1hU5DxBFPkT3Kk,55261 +gpiozero/internal_devices.py,sha256=dM711jEHvWrrTmhrWAz3wHbfVyCddp6KXRr05IaRz3E,27038 +gpiozero/mixins.py,sha256=nAphtpWO7Qvh1IZdzW5-bnZMYQYNB5HGRM5qAVbLMjs,21623 +gpiozero/output_devices.py,sha256=HPo7a4vlDRplTcWdczpFLk9GOtwsOsTd1XbAzVrAyeA,62676 +gpiozero/pins/__init__.py,sha256=L0151BYC2GY3AepCJx2sa27Gmu2mbZTm2RbqC8qeBRM,30675 +gpiozero/pins/__pycache__/__init__.cpython-37.pyc,, +gpiozero/pins/__pycache__/data.cpython-37.pyc,, +gpiozero/pins/__pycache__/lgpio.cpython-37.pyc,, +gpiozero/pins/__pycache__/local.cpython-37.pyc,, +gpiozero/pins/__pycache__/mock.cpython-37.pyc,, +gpiozero/pins/__pycache__/native.cpython-37.pyc,, +gpiozero/pins/__pycache__/pi.cpython-37.pyc,, +gpiozero/pins/__pycache__/pigpio.cpython-37.pyc,, +gpiozero/pins/__pycache__/rpigpio.cpython-37.pyc,, +gpiozero/pins/__pycache__/rpio.cpython-37.pyc,, +gpiozero/pins/__pycache__/spi.cpython-37.pyc,, +gpiozero/pins/data.py,sha256=KDRmG1LFeOPk1tVz0VKGRshLOAfbfgomCvHBwQx2cU8,77394 +gpiozero/pins/lgpio.py,sha256=wYJ19rwZNYs6xIuQZYhQ1WsZHnt2kPcYSx2BV7llVeM,12335 +gpiozero/pins/local.py,sha256=AUthjRyMTB0S-JCo4HDquCvfYLP4fD2OHyOO307TB4Y,10041 +gpiozero/pins/mock.py,sha256=QsS7c9vXyQu_wE59eQBqCBJzKiG7AwbfHbf5yNtIiwo,17562 +gpiozero/pins/native.py,sha256=ag7PNN02UdTQEN2uXg0t34_Ql81AIsW-5k7i1wySWw0,22067 +gpiozero/pins/pi.py,sha256=mitV_3DRrcFZfgHTlirUbdesGowS6M5XWzLBSRYx-xE,11425 +gpiozero/pins/pigpio.py,sha256=R304uBRqygOVvP6beirsGQxqN0aMRjFz2DStj27Mx1U,21998 +gpiozero/pins/rpigpio.py,sha256=InVTUIej-l9-WJg6nZvCbRSSYBk-HpeyYhDa8My5aRk,7417 +gpiozero/pins/rpio.py,sha256=YpAFDJaqTphmznw8lM3uOl_75uwIRbtWSjGHUSg4J-4,7260 +gpiozero/pins/spi.py,sha256=pkn2EBa8G91X0yRc7N7FMhb1GHUQN5N0FdKxiGig2h4,3564 +gpiozero/spi_devices.py,sha256=qc4GDtnPgR7Fad6Uueq1MxumcHh--Il_V5uzX6F5yCI,20572 +gpiozero/threads.py,sha256=zrIG-0J38a5C8wOmL9PZC6SALjEup9u-vwiENWm0k38,1763 +gpiozero/tones.py,sha256=61H49K56wMN9UME41te1Vcd_MN9G1EzBelSpHN4cvG0,8792 +gpiozero/tools.py,sha256=DUxbRs1v-ceFE1hsxjto6fq6gpWAXs71aPwZYIi_V-4,21640 +gpiozerocli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +gpiozerocli/__pycache__/__init__.cpython-37.pyc,, +gpiozerocli/__pycache__/pinout.cpython-37.pyc,, +gpiozerocli/pinout.py,sha256=WqeobLo_BTRKe-4bNkjDfxvx-6OgUdhJ_IauV1D3R0c,3839 diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/WHEEL new file mode 100644 index 0000000..ef99c6c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/entry_points.txt b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/entry_points.txt new file mode 100644 index 0000000..079cdbb --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/entry_points.txt @@ -0,0 +1,21 @@ +[console_scripts] +pinout = gpiozerocli.pinout:main + +[gpiozero_mock_pin_classes] +mockchargingpin = gpiozero.pins.mock:MockChargingPin +mockpin = gpiozero.pins.mock:MockPin +mockpwmpin = gpiozero.pins.mock:MockPWMPin +mocktriggerpin = gpiozero.pins.mock:MockTriggerPin + +[gpiozero_pin_factories] +NativePin = gpiozero.pins.native:NativeFactory +PiGPIOPin = gpiozero.pins.pigpio:PiGPIOFactory +RPIOPin = gpiozero.pins.rpio:RPIOFactory +RPiGPIOPin = gpiozero.pins.rpigpio:RPiGPIOFactory +lgpio = gpiozero.pins.lgpio:LGPIOFactory +mock = gpiozero.pins.mock:MockFactory +native = gpiozero.pins.native:NativeFactory +pigpio = gpiozero.pins.pigpio:PiGPIOFactory +rpigpio = gpiozero.pins.rpigpio:RPiGPIOFactory +rpio = gpiozero.pins.rpio:RPIOFactory + diff --git a/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/top_level.txt new file mode 100644 index 0000000..70f1406 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero-1.6.2.dist-info/top_level.txt @@ -0,0 +1,2 @@ +gpiozero +gpiozerocli diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__init__.py b/.venv/lib/python3.7/site-packages/gpiozero/__init__.py new file mode 100644 index 0000000..61b5e18 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/__init__.py @@ -0,0 +1,134 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2015-2021 Ben Nuttall +# Copyright (c) 2019 tuftii <3215045+tuftii@users.noreply.github.com> +# Copyright (c) 2019 Jeevan M R <14.jeevan@gmail.com> +# Copyright (c) 2019 ForToffee +# Copyright (c) 2018 Claire Pollard +# Copyright (c) 2016 pcopa +# Copyright (c) 2016 Ian Harcombe +# Copyright (c) 2016 Andrew Scheller +# Copyright (c) 2016 Andrew Scheller +# Copyright (c) 2015 Philip Howard +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) + +from .pins import ( + Factory, + Pin, + SPI, +) +from .pins.data import ( + PiBoardInfo, + HeaderInfo, + PinInfo, + pi_info, +) +# Yes, import * is naughty, but exc imports nothing else so there's no cross +# contamination here ... and besides, have you *seen* the list lately?! +from .exc import * +from .devices import ( + Device, + GPIODevice, + CompositeDevice, +) +from .mixins import ( + SharedMixin, + SourceMixin, + ValuesMixin, + EventsMixin, + event, + HoldMixin, +) +from .input_devices import ( + InputDevice, + DigitalInputDevice, + SmoothedInputDevice, + Button, + LineSensor, + MotionSensor, + LightSensor, + DistanceSensor, + RotaryEncoder, +) +from .spi_devices import ( + SPIDevice, + AnalogInputDevice, + MCP3001, + MCP3002, + MCP3004, + MCP3008, + MCP3201, + MCP3202, + MCP3204, + MCP3208, + MCP3301, + MCP3302, + MCP3304, +) +from .output_devices import ( + OutputDevice, + DigitalOutputDevice, + PWMOutputDevice, + PWMLED, + LED, + Buzzer, + Motor, + PhaseEnableMotor, + Servo, + AngularServo, + RGBLED, + TonalBuzzer, +) +from .boards import ( + CompositeOutputDevice, + ButtonBoard, + LEDCollection, + LEDBoard, + LEDBarGraph, + LEDCharDisplay, + LEDMultiCharDisplay, + LEDCharFont, + LedBorg, + PiHutXmasTree, + PiLiter, + PiLiterBarGraph, + TrafficLights, + PiTraffic, + PiStop, + StatusZero, + StatusBoard, + SnowPi, + TrafficLightsBuzzer, + FishDish, + TrafficHat, + TrafficpHat, + Robot, + RyanteckRobot, + CamJamKitRobot, + PhaseEnableRobot, + PololuDRV8835Robot, + Energenie, + PumpkinPi, + JamHat, + Pibrella, +) +from .internal_devices import ( + InternalDevice, + PolledInternalDevice, + PingServer, + CPUTemperature, + LoadAverage, + TimeOfDay, + DiskUsage, +) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ac0ff3709f2e7906cba4e121c6b0ade845f79bf GIT binary patch literal 2376 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 FzX1=M1PTBE literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/devices.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/devices.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..303ef7cd022f95f6a770162e7cfd21e06471cede GIT binary patch literal 19856 zcmbV!TWlQJnOMr&}}C896UBkF;j1vp65~ip`^~x$2ypk2jCC=Bx9q$U1@t#j3LQhuWOd#&@;^EfY8 zFMP}JCcUZ83~$OG+q0{$wdwT*)zQ(4P(#7y*F@g);o%ONBw#KjlEoT z0axa{W4Ln6UqFdP{GRuYr`ZktTBEhqQDIc{8qXR5 zZyC#rR#a-cE#C{fTTMTj_(*xa^1Zu_dbnst`TB<2Xyc^(eq7t5oh|?GF^L8)9;t;J z%6Gk>7Ho7wuk*Z(+9tm5HoJcCoyK;f9Zfvka8aB5SS&@8w_Wdkqy4^H4?AinD&O^= zHR}GIW+(8yX#P$I-3u@ZeHmq!(Xr_G;p@`L=)~b0`pIbOTlepMgoeJ;2!cj?Ju1h) z@3p@d_|Xi14K;mY*$o@d{H$y5yUpgRTYnPG9=?Wwm)2CL=eIowsrM_EMI#Q&J7LEO zH+;w6-ttwW<+nq(>1;LH&YB*wqZ^6^;H>&}w;T9QyW@25m>Mct?{u3Uia5=V>-pZ2 z^L|I+XAnBd54z1Txa2h20UBsJ5AHXXI4B1twi@eOjn0zu(D$8$$jwaeNo>VU0nE zLuiC%-`KPEt-jGW`&Qq6ncK~6KknQ6_Dkcg@#7DFWbNj63t_Hb2=jZEa{7hMLf~v) z@8>qhaDQQUEG+iN`n-259M@;N#eQ+KplMmF zYt^wLb6jCje$@^9pjyP08dWEP`(`u2$YPeM$le0ChzwsKbxIs{>{iX5i zx2}Y(tt(rNt;?|jTz={Yt6rw_#3p;0Q7CiH9!!l|G2>)+$Mu@3ev!0aHzcGzn+cbLL4#&gN3rzp! zL|lvQnJ?^G;f1|f{s~mL_&)r5AJRb$mtk6MrWf?=(HA3#@9C z3;gDqlu%#e{k&ZMAx?uC91L?7Q*W6i%Yq_I<$6xCKA`}0n3h^?>78Z=XTi-Sd314> zOCjj4iaP4`d>aZIO}!fgzM`ejy`q4s6WAHJ0o2efwS+6`G7nd9zyr|s#wzwD{lID7 zk+oM$+E#C};MjBDeS+~vHV@<4_69!IkJnIK8C*748H;%>gPg0@gQ)Q2xqO?x)Us%* zMN}5cNnK@Q*Lb+j17)MWiNgo@1m|!t>?yO9D?>JA$Y_po$`#Dn$%1*_o-NFoQ)chT zAz3XJBJ`bW8Rnn_yU_8vO`ex)wWnRTsqe@-l-8ojcv;tdidxT;OsDRx?iXe97W+k$ zS+vX3BBdd1OwI9q6d7fXJ(^;pn)C8r0pEGx6Ck6{3}CG>Z`>>4TG5;E%J?4FsHR#H zvpoTgoL1jJwe_SCezPn54k|c=Mjwz4i+=%2*4Q+kjH!jt@?gI=Z5o3$YaR{3NaVwU zSoSe4?U$BT_8X|7_u3m5f;XJb>ZV^09oSKBiJVr^4~I7wi|RF$R4lIE=7IC6-sM45 zhkcADYBgvEpM*ZxdUDV6M*bOLNvs9gf>7__<_Tq-seLRw>L z4Y@!qeD2^AlyT@A`^HPGWLd%3Ow2^-M7=nrS(~zT_?Yj1!lzk{aZFp@xIK?IhuUI$ z(iY|JnGl@i{t_m+LWZ@8h)%R#5B>VDuX z1l{@uZpq3|>mwFeTq>o%A8j-Or{#wm9nZm8!}EdFLf{)`q3*VcQfMtuai@)D(HfD) zjw2?+b98^w%APk+5Blr2cbouKUG~@3Fz;y4xfil}0N9qR8qFO55HtexBannY6o3?< zngiIB*5`&Y>UyWu;*f#He5uK61Ozw1D`bLUglMbLUI-Rhe_9_Q+3F6ur$L$S{eUoj z(CK2h7-a}(u!Y7u5Iq_}&jUbgbQ@1&68(_45CyefUvgmVoNgOE3evWAI^8!goH}Ny zjbV1TWTs%~fWm<_(07d}x6kI;GEQBRx&|C!%Tt81(|UsU5IibMHtptE5E zT7i|e-gT7=;rhIl*0t`cRd*eI>tJSy*q!Grj|qS&!ysjZ@<_69Wg>9c>R_rco6hZ> zw6=Pu9V#~nrFpFwi9&6u&NHY%;JCQrwgacL=J@TP3pZvRJ&LDSOCYU}!cLTaU~UMK z{cRVs-~%6vG+<94Vb@uuPOf%b+ieUG;)k%I4{00M-qLdhskHG- zu)zYDb(brq?R@y&U4h`JwvsIsuE?7=Z#vkgT26wz9qoEK7t^|vVyivphI3mwvT*IK z#S!4KrAW5eJFaXu{Dl43Z6{sOh5`87@;>5G} zyGv9iH-yf1Ol=gr!@`7IKre=x4n$02^JK{NMM`#7SF^*D8{<9qs9Jh-uNRPKH}jn z4=D!2EC_NG%ump`jZZ*#rD&EXi^q#s%Hzd+(H77vkJWK6{iBZXFL;bY0<}G}YI_!$ z4lp2^^&rF+uq_ZEUzT^n1gBH^w@Cg_L zU_@@e12$r#0nnxD8#@|P`D=hz=_8H0)CSLwOdfXdt*vIGPShn^CE$X#6vUZZe!a1V zo5T*X4-lqTRvJM~V>)eZl9|*vp`y!(60IZ_W9Jfvi_MyQ$)L50@kD}KVdMFNFXf*oI9g^fD0;}~7;r~I0$>{&-LHXu zq_w3uDmLBE^=7U6hP|6xTp~I4;1Q%dP!DCVLE1AQ^G-M5KpWtkWAiiNv;?Otu;a7RaOKaEaTb}WxsIG_RraoH; zO;V4cS+jVpZ`7=I0mLM}`=+`df{ViQ`IlhkPa3hSTZl=_vD7QfEk_drGv0ekFL3ym z+&F5rg+*r_puXECc`Rr&#z_u%j4n4j@q>jNS}aEPR%c6n7hP8maERt=u`-gzP4qk( zCtWW)WHg5Iq%y@>CQYGRO`POEOlnHZV``+;$GG)>@rh}}vQUK}4XuKi!#_C7(+7r9 zM``(^eEGS9PjDYwRY;=1+=VPRt$moxm*%e7huk6WzuNwDc+okbcz+6t*W9&s?)I(y zJPqng3s>yj90&xvpM#Oj{|qE>2$Hv-+XKh8TR<%Z@ON8baUTp~II(9kR?;s##6*YX zm|+|P!+2IoOnM+8!m0k)UQAE0bj%u#eKIDj;p>l$r>}o(gwtM;^hNvUq&J=v)c+wd zebV@HJ$q=t=o`(M-J)089p66FFYX`dkN3@&7O3j-ZmD0|pM42_^dVZ`c9OgMM_)o0 z50^k+z>5w*k@E6le$lFqDb4%$&L_s@Ud{*D zBSZ3o+9?F_caGPKAS?kQ!CmHfrjGOCaV-$6XdRKN!JGx~tfKMvw(I^D`Brs;1#OI8 zk)4kwx1OwnFOCVG=m_J2#C&R}CXPAk=is9}Y_G2tC#pvh(*es0Hy=Y(=TQ-$N%l}w z1eqz+rVe08z@nfDPO(7h79LSPJCI*jo$gjNrmNe@pqJ(|AEAs5TM&E`Cq~gS3kBGe z+^i69Q{Y>RU{`5Za=3C4VTodnd~3N-#FbgxpU0Y_Mr8EJ8l4G`zv0Zan*2Idb_K)kaC2nZA< zPO}hJ8ghVf5;`x#OMpl85*zUR2{)3J2;ej9vog}Ew{<}=7*7JG(m^K8>Q=M<1aR~p zc2_S8vIVptch-64D+R&{LnQbG=i{qZBkPugKHFW!`pA@GwfaHkgFX^{UbM8glNSjc zQ1NKGmh>m6Q4D{`NtH<}_U04C9WFAYv+0};JNNFj!Ff&md)E=ONO*J*cKt5AhiKYZ>3v|bgMbxnB8pwmkH z50X3xQv;?9pjQxz>nW7Ge2rrM+O}cGK+X#Q;Mud5)n8pY0s1p88Rf{io`>q z5@3)G8FZbNobR=pjVExJ2CrsnaM5i(cXxt|nDbZM^2OasZLX>*{Ak2))oZv=X(@lyyg=+E8;eo*|>4bX9v%5S9OyvO`%iMb6 z;{S$^1UZXG08_2L_%$4odi^!#5GC&fzLmMb4mQc`83WY z?FZ*GIG5BPoF5ThU>2%&CYrvJtR5{~_pf0iWYXW;W~>CZbC|MSavmgxfegF0#d@L8 zL4vd2f)CpOp_VL1sZF#+!Wq8v!Ml&(w0&@S6;=}gfmVmX0GO{(F*KlXPj%ohll^51 z&v30$n>>PYq#d;PO@ogrwEszCQzx8(%R8`|bzjkIglU)=1h9jA8WfH_BdI#^j%exc zXQk514DGbwRuQozp(s>|<`A%!Z81b(fX=B@N5iRy0o;^G3mxDlhjbp0ALV7u}i}zBj!nJD$ zeqT?1bGBtB;;2tWm?%eE7w1P8v5oN=SM9eL3nA$hjyWX zMG#YuKmp0pmyjdkODVX)+9IMFh|-N}4xmSH#PEIx{3)FSTmY&`$u)=Z(0Kh-NTND5 zDN#Wv8Gsn}W*L}5Iv)!szMqcg-da{$wyCmXx+xf0Eip+Z%gPdz585&=s?2aLK$a2* zB~p!}pu>{WV+0aNEom&C0bG~xuDUA-;k*mvbl7xVY;}Y1B13taze7b@TInF;I52Yo z9Spbw$c*?477641TN^G=V$ALa$TG$AdhE#zA`?kyt+YPa<-`3LnuYN_*fk6 z7vKqz{|AN)zw+|S7Vg&G`4v!kUiich!vgMrf0ZZm?MvGi!(ws;38E;sXP#g}=?r+q zaSxedbO>0e@Q8=x)425CpcRzV;|gcNM;e<)H|OS!aMB~BG{R%yd>?J?nRlfW z`fKfR#5OVr-_cyfZ))!srn=fM>>nos{R{Ky)sKx&<4i*^pUCb4i&`Rd<=EK5o_UaSF}>UL#x4Z1iKPlbm&>Ly@H3A?-}v#=E(l|ipx?*9o?3C- zdtB>v?SdDFKds1Gx*C~{%ta9T>DS}$to!8H)y=<5T$P;B``UrMG^ORU{KxdUL%m}R za-erFgdUE2HyDw%R2L;9^BJ5KA>74#kwD~g-1xUye^7w5{^IEQ(&FC+>MXBF9N{R>xcah) zb(9x3KC+vBTOzGG)sC|vVS&XloyTyK7t#Mf0rLJNP<4I)g)OS;_|9LUV{2 zFz0tBG-zKQ8arI|h)0~%oFMa(D|(%Uh*c!KyUx~4a&>#Cr#FXip3b97@I2UN@PC{( z#S)V8Drt)`aU@bXpqk8Hj8n&JwO>*wOf595B6vWG15DuQ!)ls7F*-qW0X0ZkCLQj~z{lSv4PoN>Yth%26H zH;er{4oFfPtP*Bz)KCs5T5|1k%ESizElzg!69Sh3woSY&v};PJO^*D1!axX*6Pr^W zLV5C?Hf@H8Bd}xV!hKzIFLE}O3n^% zJ}DUyvwzW}5&2k5)P>yCvgC57c`bQFfFnH{)!!?MKWN+_^)^D zV0R_4EbTBQLhB_R=6=i&INp&0lF^_`I+YgZ`1ql9m4G_{kBnwBfjg;4@1Y2KOh}=A z#)H_~%;*wQ{I5i=fH;dIJL-)9I8f4m#>z*|m!w$z&!k?%>K%M>ProSQr9+|w_&KB( zy}wR9hDUHwDtu$HvhqphX9i0d&_RHTp824o3->ss1?c3YwF$II(wOQAUmANpI@a_G zUk4RR(&TVe5^xYNk$o6o#!dAPUo9s>ssEkIX{>kZp!~DJ4aq9i7QUv%H8iL%KNlr- z86`~n`0f{qZeUMIqDAz+eIzocwHzj1mtqnq4&|}CJOzDlfRIW2&a|$?DP-6|Mmfyq z#0l9*nM6EFJOhWAT*<2m>=-7qbt$baPWIZ-Z6n3ZcU3~=B)l*mK{Q3~!P|(5o>W^p zDx0-b*uTYEW02^J)|!p_WS78NTR1q^qLQPR8ujEAOO4I`zf^^ahi#2in+}MpjDwPu zcF^?qK1l_db}pS364w+KqM~?R%Q>fM+jC48W@e$z2n0nS0&RqhBBr%zV;LlA_UDl8 z7H;gE(}BcH?AUp1)RiE_5&Nx#b@GW6jY98a+R?j`e!i4)$BRct29oGasLyyH;?$v| z&w2I}9{wp05=5eP)BX&NsCIfN>n{u}(JcR%6T){Xi*M%4@@vKMa-n>(X!Bn=Uo4b! z<#7a=Sh9{!`o~?1f59^x27^rAG4aKjHaecYp{3u?ibG6H8%2o8kKfTkNN8N1Vd7{J zA*P~!^BmVFaDK#_{S5w0wd@`B<`9CKlw%b4BoGyi^Z1- z9XBDWP}53EzRB)@D;2DL;cO9Ek{-ph9B-v6`v|?1`q`P3Th)q8-U4c#z7e8drLN$W zoXQG{U)C{k!1I-~I+`r3#D-1<(ghHX0!f-si*ZbsJn{+$fOP1}N;VaeqLh7<)Dy<-&D#BXV%R9Mq6HfU&-vZu3N^ioPt*yx=BTyprSIF zDtQ}w(^@n5QZLCMQc&=)n6$Tm-kf4B}74Id3NwgWKX>XN(}DcMg_8YzjA z?h=pgu%@tvuVco` z5j2GZ(2UWmVfY`gH{y-p1#TgTvq^`N=bQy>4Y%)nCr;l&y^HCv)4Ew|!e~v5haywuR1tva9Td;-}*TJ2HWYj_9JBp2m3{b~#>=9|*hDEB_k1nSD_6uT~XmrW{~-Aw$+ z0u^G8mUD_-;wD@y=gg^T;M}pY{x?z1DVC_?BY&LgbPM_i_z^EZRF^t9FA;HPb-L(;d#ATc{oqmoK(|tXpLszAwI!X95$e9 z_`hI41fjCCe63>-AupWI?Ai!yaXUHDxBoQv^u*Kh)0}9e2m!P`DV1swh!6j%5@2Kn zKh+)&7t;f!gHRF}Yk=IXn*>l|hzl^p%-Zdp#|s(qPE`7zBMo?e$z#}Pzso9RM;d3+ zc8ys+)k&TLMI$W&^)K5&JnIPJ|FtLnAFE^l)k2H^OI4sIStZ{9jBEgN$)eXg*b&|!E>uT( z5F~nxXR@^&=b0qm7pMeosN+4WynKp>Z}1=!9PmtF2&FB8h@fEWP%m(?nObEsEWV?Y y>u(AaC)0VNkOMAdFo^&7KlhZavN@BxS}xnU!p!Y6joJRpKQgY*JSff-bN?T=3jt&R literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/exc.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/exc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ceefeb1919c5e2e837fcc79a2a881c8b1e4d6fac GIT binary patch literal 13563 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 F{{WqA)U5yj literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/fonts.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/fonts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ced052afb1faa44b899d17f1f6cf5d54d95986a4 GIT binary patch literal 9444 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 JRC`ow{x5>4Gsge` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/input_devices.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/input_devices.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bfece335d60e1646bc82c353374f1785909cdb0 GIT binary patch literal 47233 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/internal_devices.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/internal_devices.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b216523a4bbc20839fe389a121052fa284b16e9 GIT binary patch literal 26607 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/spi_devices.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/__pycache__/spi_devices.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b953321d4a882d15f067d0f349e60ce90ac712ff GIT binary patch literal 19344 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/boards.py b/.venv/lib/python3.7/site-packages/gpiozero/boards.py new file mode 100644 index 0000000..0a1748c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/boards.py @@ -0,0 +1,2927 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2015-2021 Ben Nuttall +# Copyright (c) 2020 Ryan Walmsley +# Copyright (c) 2020 Jack Wearden +# Copyright (c) 2019 tuftii <3215045+tuftii@users.noreply.github.com> +# Copyright (c) 2019 ForToffee +# Copyright (c) 2016-2019 Andrew Scheller +# Copyright (c) 2018 SteveAmor +# Copyright (c) 2018 Rick Ansell +# Copyright (c) 2018 Claire Pollard +# Copyright (c) 2016 Ian Harcombe +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +try: + from itertools import izip as zip +except ImportError: + pass + +from time import sleep +from itertools import repeat, cycle, chain, tee +from threading import Lock +from collections import OrderedDict, Counter, namedtuple +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping + +from .exc import ( + DeviceClosed, + PinInvalidPin, + GPIOPinMissing, + EnergenieSocketMissing, + EnergenieBadSocket, + OutputDeviceBadValue, + CompositeDeviceBadDevice, + BadWaitTime, + ) +from .input_devices import Button +from .output_devices import ( + OutputDevice, + LED, + PWMLED, + RGBLED, + Buzzer, + Motor, + PhaseEnableMotor, + TonalBuzzer, + ) +from .threads import GPIOThread +from .devices import Device, CompositeDevice +from .mixins import SharedMixin, SourceMixin, HoldMixin +from .fonts import load_font_7seg, load_font_14seg + + +def pairwise(it): + a, b = tee(it) + next(b, None) + return zip(a, b) + + +class CompositeOutputDevice(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` with :meth:`on`, :meth:`off`, and + :meth:`toggle` methods for controlling subordinate output devices. Also + extends :attr:`value` to be writeable. + + :param Device \\*args: + The un-named devices that belong to the composite device. The + :attr:`~Device.value` attributes of these devices will be represented + within the composite device's tuple :attr:`value` in the order + specified here. + + :type _order: list or None + :param _order: + If specified, this is the order of named items specified by keyword + arguments (to ensure that the :attr:`value` tuple is constructed with a + specific order). All keyword arguments *must* be included in the + collection. If omitted, an alphabetically sorted order will be selected + for keyword arguments. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + :param Device \\*\\*kwargs: + The named devices that belong to the composite device. These devices + will be accessible as named attributes on the resulting device, and + their :attr:`value` attributes will be accessible as named elements of + the composite device's tuple :attr:`value`. + """ + + def on(self): + """ + Turn all the output devices on. + """ + for device in self: + if isinstance(device, (OutputDevice, CompositeOutputDevice)): + device.on() + + def off(self): + """ + Turn all the output devices off. + """ + for device in self: + if isinstance(device, (OutputDevice, CompositeOutputDevice)): + device.off() + + def toggle(self): + """ + Toggle all the output devices. For each device, if it's on, turn it + off; if it's off, turn it on. + """ + for device in self: + if isinstance(device, (OutputDevice, CompositeOutputDevice)): + device.toggle() + + @property + def value(self): + """ + A tuple containing a value for each subordinate device. This property + can also be set to update the state of all subordinate output devices. + """ + return super(CompositeOutputDevice, self).value + + @value.setter + def value(self, value): + for device, v in zip(self, value): + if isinstance(device, (OutputDevice, CompositeOutputDevice)): + device.value = v + # Simply ignore values for non-output devices + + +class ButtonBoard(HoldMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` and represents a generic button board or + collection of buttons. The :attr:`value` of the button board is a tuple + of all the buttons states. This can be used to control all the LEDs in a + :class:`LEDBoard` with a :class:`ButtonBoard`:: + + from gpiozero import LEDBoard, ButtonBoard + from signal import pause + + leds = LEDBoard(2, 3, 4, 5) + btns = ButtonBoard(6, 7, 8, 9) + leds.source = btns + + pause() + + Alternatively you could represent the number of pressed buttons with an + :class:`LEDBarGraph`:: + + from gpiozero import LEDBarGraph, ButtonBoard + from statistics import mean + from signal import pause + + graph = LEDBarGraph(2, 3, 4, 5) + bb = ButtonBoard(6, 7, 8, 9) + graph.source = (mean(values) for values in bb.values) + + pause() + + :type pins: int or str + :param \\*pins: + Specify the GPIO pins that the buttons of the board are attached to. + See :ref:`pin-numbering` for valid pin numbers. You can designate as + many pins as necessary. + + :type pull_up: bool or None + :param pull_up: + If :data:`True` (the default), the GPIO pins will be pulled high by + default. In this case, connect the other side of the buttons to + ground. If :data:`False`, the GPIO pins will be pulled low by default. + In this case, connect the other side of the buttons to 3V3. If + :data:`None`, the pin will be floating, so it must be externally pulled + up or down and the ``active_state`` parameter must be set accordingly. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :param float bounce_time: + If :data:`None` (the default), no software bounce compensation will be + performed. Otherwise, this is the length of time (in seconds) that the + buttons will ignore changes in state after an initial change. + + :param float hold_time: + The length of time (in seconds) to wait after any button is pushed, + until executing the :attr:`when_held` handler. Defaults to ``1``. + + :param bool hold_repeat: + If :data:`True`, the :attr:`when_held` handler will be repeatedly + executed as long as any buttons remain held, every *hold_time* seconds. + If :data:`False` (the default) the :attr:`when_held` handler will be + only be executed once per hold. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + :type named_pins: int or str + :param \\*\\*named_pins: + Specify GPIO pins that buttons of the board are attached to, + associating each button with a property name. You can designate as + many pins as necessary and use any names, provided they're not already + in use by something else. + """ + def __init__(self, *args, **kwargs): + pull_up = kwargs.pop('pull_up', True) + active_state = kwargs.pop('active_state', None) + bounce_time = kwargs.pop('bounce_time', None) + hold_time = kwargs.pop('hold_time', 1) + hold_repeat = kwargs.pop('hold_repeat', False) + pin_factory = kwargs.pop('pin_factory', None) + order = kwargs.pop('_order', None) + super(ButtonBoard, self).__init__( + *( + Button(pin, pull_up=pull_up, active_state=active_state, + bounce_time=bounce_time, hold_time=hold_time, + hold_repeat=hold_repeat) + for pin in args + ), + _order=order, + pin_factory=pin_factory, + **{ + name: Button(pin, pull_up=pull_up, active_state=active_state, + bounce_time=bounce_time, hold_time=hold_time, + hold_repeat=hold_repeat) + for name, pin in kwargs.items() + } + ) + if len(self) == 0: + raise GPIOPinMissing('No pins given') + def get_new_handler(device): + def fire_both_events(ticks, state): + device._fire_events(ticks, device._state_to_value(state)) + self._fire_events(ticks, self.is_active) + return fire_both_events + # _handlers only exists to ensure that we keep a reference to the + # generated fire_both_events handler for each Button (remember that + # pin.when_changed only keeps a weak reference to handlers) + self._handlers = tuple(get_new_handler(device) for device in self) + for button, handler in zip(self, self._handlers): + button.pin.when_changed = handler + self._when_changed = None + self._last_value = None + # Call _fire_events once to set initial state of events + self._fire_events(self.pin_factory.ticks(), self.is_active) + self.hold_time = hold_time + self.hold_repeat = hold_repeat + + @property + def pull_up(self): + """ + If :data:`True`, the device uses a pull-up resistor to set the GPIO pin + "high" by default. + """ + return self[0].pull_up + + @property + def when_changed(self): + return self._when_changed + + @when_changed.setter + def when_changed(self, value): + self._when_changed = self._wrap_callback(value) + + def _fire_changed(self): + if self.when_changed: + self.when_changed() + + def _fire_events(self, ticks, new_value): + super(ButtonBoard, self)._fire_events(ticks, new_value) + old_value, self._last_value = self._last_value, new_value + if old_value is None: + # Initial "indeterminate" value; don't do anything + pass + elif old_value != new_value: + self._fire_changed() + +ButtonBoard.is_pressed = ButtonBoard.is_active +ButtonBoard.pressed_time = ButtonBoard.active_time +ButtonBoard.when_pressed = ButtonBoard.when_activated +ButtonBoard.when_released = ButtonBoard.when_deactivated +ButtonBoard.wait_for_press = ButtonBoard.wait_for_active +ButtonBoard.wait_for_release = ButtonBoard.wait_for_inactive + + +class LEDCollection(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice`. Abstract base class for + :class:`LEDBoard` and :class:`LEDBarGraph`. + """ + def __init__(self, *args, **kwargs): + pwm = kwargs.pop('pwm', False) + active_high = kwargs.pop('active_high', True) + initial_value = kwargs.pop('initial_value', False) + pin_factory = kwargs.pop('pin_factory', None) + order = kwargs.pop('_order', None) + LEDClass = PWMLED if pwm else LED + super(LEDCollection, self).__init__( + *( + pin_or_collection + if isinstance(pin_or_collection, LEDCollection) else + LEDClass( + pin_or_collection, active_high, initial_value, + pin_factory=pin_factory + ) + for pin_or_collection in args + ), + _order=order, + pin_factory=pin_factory, + **{ + name: pin_or_collection + if isinstance(pin_or_collection, LEDCollection) else + LEDClass( + pin_or_collection, active_high, initial_value, + pin_factory=pin_factory + ) + for name, pin_or_collection in kwargs.items() + } + ) + if len(self) == 0: + raise GPIOPinMissing('No pins given') + leds = [] + for item in self: + if isinstance(item, LEDCollection): + for subitem in item.leds: + leds.append(subitem) + else: + leds.append(item) + self._leds = tuple(leds) + + @property + def leds(self): + """ + A flat tuple of all LEDs contained in this collection (and all + sub-collections). + """ + return self._leds + + @property + def active_high(self): + return self[0].active_high + + +LEDCollection.is_lit = LEDCollection.is_active + + +class LEDBoard(LEDCollection): + """ + Extends :class:`LEDCollection` and represents a generic LED board or + collection of LEDs. + + The following example turns on all the LEDs on a board containing 5 LEDs + attached to GPIO pins 2 through 6:: + + from gpiozero import LEDBoard + + leds = LEDBoard(2, 3, 4, 5, 6) + leds.on() + + :type pins: int or str or LEDCollection + :param \\*pins: + Specify the GPIO pins that the LEDs of the board are attached to. See + :ref:`pin-numbering` for valid pin numbers. You can designate as many + pins as necessary. You can also specify :class:`LEDBoard` instances to + create trees of LEDs. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set all the + associated pins to HIGH. If :data:`False`, the :meth:`on` method will + set all pins to LOW (the :meth:`off` method always does the opposite). + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + :type named_pins: int or str + :param \\*\\*named_pins: + Specify GPIO pins that LEDs of the board are attached to, associating + each LED with a property name. You can designate as many pins as + necessary and use any names, provided they're not already in use by + something else. You can also specify :class:`LEDBoard` instances to + create trees of LEDs. + """ + def __init__(self, *args, **kwargs): + self._blink_thread = None + self._blink_leds = [] + self._blink_lock = Lock() + super(LEDBoard, self).__init__(*args, **kwargs) + + def close(self): + try: + self._stop_blink() + except AttributeError: + pass + super(LEDBoard, self).close() + + def on(self, *args): + """ + If no arguments are specified, turn all the LEDs on. If arguments are + specified, they must be the indexes of the LEDs you wish to turn on. + For example:: + + from gpiozero import LEDBoard + + leds = LEDBoard(2, 3, 4, 5) + leds.on(0) # turn on the first LED (pin 2) + leds.on(-1) # turn on the last LED (pin 5) + leds.on(1, 2) # turn on the middle LEDs (pins 3 and 4) + leds.off() # turn off all LEDs + leds.on() # turn on all LEDs + + If :meth:`blink` is currently active, it will be stopped first. + + :param int args: + The index(es) of the LED(s) to turn on. If no indexes are specified + turn on all LEDs. + """ + self._stop_blink() + if args: + for index in args: + self[index].on() + else: + super(LEDBoard, self).on() + + def off(self, *args): + """ + If no arguments are specified, turn all the LEDs off. If arguments are + specified, they must be the indexes of the LEDs you wish to turn off. + For example:: + + from gpiozero import LEDBoard + + leds = LEDBoard(2, 3, 4, 5) + leds.on() # turn on all LEDs + leds.off(0) # turn off the first LED (pin 2) + leds.off(-1) # turn off the last LED (pin 5) + leds.off(1, 2) # turn off the middle LEDs (pins 3 and 4) + leds.on() # turn on all LEDs + + If :meth:`blink` is currently active, it will be stopped first. + + :param int args: + The index(es) of the LED(s) to turn off. If no indexes are + specified turn off all LEDs. + """ + self._stop_blink() + if args: + for index in args: + self[index].off() + else: + super(LEDBoard, self).off() + + def toggle(self, *args): + """ + If no arguments are specified, toggle the state of all LEDs. If + arguments are specified, they must be the indexes of the LEDs you wish + to toggle. For example:: + + from gpiozero import LEDBoard + + leds = LEDBoard(2, 3, 4, 5) + leds.toggle(0) # turn on the first LED (pin 2) + leds.toggle(-1) # turn on the last LED (pin 5) + leds.toggle() # turn the first and last LED off, and the + # middle pair on + + If :meth:`blink` is currently active, it will be stopped first. + + :param int args: + The index(es) of the LED(s) to toggle. If no indexes are specified + toggle the state of all LEDs. + """ + self._stop_blink() + if args: + for index in args: + self[index].toggle() + else: + super(LEDBoard, self).toggle() + + def blink( + self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0, + n=None, background=True): + """ + Make all the LEDs turn on and off repeatedly. + + :param float on_time: + Number of seconds on. Defaults to 1 second. + + :param float off_time: + Number of seconds off. Defaults to 1 second. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 0. Must be 0 if + ``pwm`` was :data:`False` when the class was constructed + (:exc:`ValueError` will be raised if not). + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 0. Must be 0 if + ``pwm`` was :data:`False` when the class was constructed + (:exc:`ValueError` will be raised if not). + + :type n: int or None + :param n: + Number of times to blink; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True`, start a background thread to continue blinking and + return immediately. If :data:`False`, only return when the blink is + finished (warning: the default value of *n* will result in this + method never returning). + """ + for led in self.leds: + if isinstance(led, LED): + if fade_in_time: + raise ValueError('fade_in_time must be 0 with non-PWM LEDs') + if fade_out_time: + raise ValueError('fade_out_time must be 0 with non-PWM LEDs') + self._stop_blink() + self._blink_thread = GPIOThread( + self._blink_device, + (on_time, off_time, fade_in_time, fade_out_time, n)) + self._blink_thread.start() + if not background: + self._blink_thread.join() + self._blink_thread = None + + def _stop_blink(self, led=None): + if led is None: + if self._blink_thread: + self._blink_thread.stop() + self._blink_thread = None + else: + with self._blink_lock: + self._blink_leds.remove(led) + + def pulse(self, fade_in_time=1, fade_out_time=1, n=None, background=True): + """ + Make all LEDs fade in and out repeatedly. Note that this method will + only work if the *pwm* parameter was :data:`True` at construction time. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 1. + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 1. + + :type n: int or None + :param n: + Number of times to blink; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue blinking and return immediately. If :data:`False`, only + return when the blink is finished (warning: the default value of + *n* will result in this method never returning). + """ + on_time = off_time = 0 + self.blink( + on_time, off_time, fade_in_time, fade_out_time, n, background) + + def _blink_device( + self, on_time, off_time, fade_in_time, fade_out_time, n, fps=25): + sequence = [] + if fade_in_time > 0: + sequence += [ + (i * (1 / fps) / fade_in_time, 1 / fps) + for i in range(int(fps * fade_in_time)) + ] + sequence.append((1, on_time)) + if fade_out_time > 0: + sequence += [ + (1 - (i * (1 / fps) / fade_out_time), 1 / fps) + for i in range(int(fps * fade_out_time)) + ] + sequence.append((0, off_time)) + if n is None: + sequence = cycle(sequence) + else: + sequence = chain.from_iterable(repeat(sequence, n)) + with self._blink_lock: + self._blink_leds = list(self.leds) + for led in self._blink_leds: + if led._controller not in (None, self): + led._controller._stop_blink(led) + led._controller = self + for value, delay in sequence: + with self._blink_lock: + if not self._blink_leds: + break + for led in self._blink_leds: + led._write(value) + if self._blink_thread.stopping.wait(delay): + break + + +class LEDBarGraph(LEDCollection): + """ + Extends :class:`LEDCollection` to control a line of LEDs representing a + bar graph. Positive values (0 to 1) light the LEDs from first to last. + Negative values (-1 to 0) light the LEDs from last to first. + + The following example demonstrates turning on the first two and last two + LEDs in a board containing five LEDs attached to GPIOs 2 through 6:: + + from gpiozero import LEDBarGraph + from time import sleep + + graph = LEDBarGraph(2, 3, 4, 5, 6) + graph.value = 2/5 # Light the first two LEDs only + sleep(1) + graph.value = -2/5 # Light the last two LEDs only + sleep(1) + graph.off() + + As with all other output devices, :attr:`source` and :attr:`values` are + supported:: + + from gpiozero import LEDBarGraph, MCP3008 + from signal import pause + + graph = LEDBarGraph(2, 3, 4, 5, 6, pwm=True) + pot = MCP3008(channel=0) + + graph.source = pot + + pause() + + :type pins: int or str + :param \\*pins: + Specify the GPIO pins that the LEDs of the bar graph are attached to. + See :ref:`pin-numbering` for valid pin numbers. You can designate as + many pins as necessary. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + This parameter can only be specified as a keyword parameter. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set all the + associated pins to HIGH. If :data:`False`, the :meth:`on` method will + set all pins to LOW (the :meth:`off` method always does the opposite). + This parameter can only be specified as a keyword parameter. + + :param float initial_value: + The initial :attr:`value` of the graph given as a float between -1 and + +1. Defaults to 0.0. This parameter can only be specified as a + keyword parameter. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, *pins, **kwargs): + # Don't allow graphs to contain collections + for pin in pins: + if isinstance(pin, Device): + raise CompositeDeviceBadDevice( + 'Only pins may be specified for LEDBarGraph') + pwm = kwargs.pop('pwm', False) + active_high = kwargs.pop('active_high', True) + initial_value = kwargs.pop('initial_value', 0.0) + pin_factory = kwargs.pop('pin_factory', None) + if kwargs: + raise TypeError( + 'unexpected keyword argument: %s' % kwargs.popitem()[0]) + super(LEDBarGraph, self).__init__( + *pins, pwm=pwm, active_high=active_high, pin_factory=pin_factory) + try: + self.value = initial_value + except: + self.close() + raise + + @property + def value(self): + """ + The value of the LED bar graph. When no LEDs are lit, the value is 0. + When all LEDs are lit, the value is 1. Values between 0 and 1 + light LEDs linearly from first to last. Values between 0 and -1 + light LEDs linearly from last to first. + + To light a particular number of LEDs, simply divide that number by + the number of LEDs. For example, if your graph contains 3 LEDs, the + following will light the first:: + + from gpiozero import LEDBarGraph + + graph = LEDBarGraph(12, 16, 19) + graph.value = 1/3 + + .. note:: + + Setting value to -1 will light all LEDs. However, querying it + subsequently will return 1 as both representations are the same in + hardware. The readable range of :attr:`value` is effectively + -1 < value <= 1. + """ + result = sum(led.value for led in self) + if self[0].value < self[-1].value: + result = -result + return result / len(self) + + @value.setter + def value(self, value): + if not -1 <= value <= 1: + raise OutputDeviceBadValue( + 'LEDBarGraph value must be between -1 and 1') + count = len(self) + leds = self + if value < 0: + leds = reversed(leds) + value = -value + if isinstance(self[0], PWMLED): + calc_value = lambda index: min(1, max(0, count * value - index)) + else: + calc_value = lambda index: value >= ((index + 1) / count) + for index, led in enumerate(leds): + led.value = calc_value(index) + + @property + def lit_count(self): + """ + The number of LEDs on the bar graph actually lit up. Note that just + like :attr:`value`, this can be negative if the LEDs are lit from last + to first. + """ + lit_value = self.value * len(self) + if not isinstance(self[0], PWMLED): + lit_value = int(lit_value) + return lit_value + + @lit_count.setter + def lit_count(self, value): + self.value = value / len(self) + + +class LEDCharFont(MutableMapping): + """ + Contains a mapping of values to tuples of LED states. + + This effectively acts as a "font" for :class:`LEDCharDisplay`, and two + default fonts (for 7-segment and 14-segment displays) are shipped with GPIO + Zero by default. You can construct your own font instance from a + :class:`dict` which maps values (usually single-character strings) to + a tuple of LED states:: + + from gpiozero import LEDCharDisplay, LEDCharFont + + my_font = LEDCharFont({ + ' ': (0, 0, 0, 0, 0, 0, 0), + 'D': (1, 1, 1, 1, 1, 1, 0), + 'A': (1, 1, 1, 0, 1, 1, 1), + 'd': (0, 1, 1, 1, 1, 0, 1), + 'a': (1, 1, 1, 1, 1, 0, 1), + }) + display = LEDCharDisplay(26, 13, 12, 22, 17, 19, 6, dp=5, font=my_font) + display.value = 'D' + + Font instances are mutable and can be changed while actively in use by + an instance of :class:`LEDCharDisplay`. However, changing the font will + *not* change the state of the LEDs in the display (though it may change + the :attr:`~LEDCharDisplay.value` of the display when next queried). + + .. note:: + + Your custom mapping should always include a value (typically space) + which represents all the LEDs off. This will usually be the default + value for an instance of :class:`LEDCharDisplay`. + + You may also wish to load fonts from a friendly text-based format. A simple + parser for such formats (supporting an arbitrary number of segments) is + provided by :func:`gpiozero.fonts.load_segment_font`. + """ + def __init__(self, font): + super(LEDCharFont, self).__init__() + self._map = OrderedDict([ + (char, tuple(int(bool(pin)) for pin in pins)) + for char, pins in font.items() + ]) + self._refresh_rmap() + + def __repr__(self): + return '{self.__class__.__name__}({{\n{content}\n}})'.format( + self=self, content='\n'.join( + ' {key!r}: {value!r},'.format(key=key, value=value) + for key, value in sorted(self.items()) + )) + + def _refresh_rmap(self): + # The reverse mapping is pre-calculated for speed of lookup. Given that + # the font mapping can be 1:n, we cannot guarantee the reverse is + # unique. In case the provided font is an ordered dictionary, we + # explicitly take only the first definition of each non-unique pin + # definition so that value lookups are predictable + rmap = {} + for char, pins in self._map.items(): + rmap.setdefault(pins, char) + self._rmap = rmap + + def __len__(self): + return len(self._map) + + def __iter__(self): + return iter(self._map) + + def __getitem__(self, char): + return self._map[char] + + def __setitem__(self, char, pins): + try: + # This is necessary to ensure that _rmap is correct in the case + # that we're overwriting an existing char->pins mapping + del self[char] + except KeyError: + pass + pins = tuple(int(bool(pin)) for pin in pins) + self._map[char] = pins + self._rmap.setdefault(pins, char) + + def __delitem__(self, char): + pins = self._map[char] + del self._map[char] + # If the reverse mapping of the char's pins maps to the char we need + # to find if it now maps to another char (given the n:1 mapping) + if self._rmap[pins] == char: + del self._rmap[pins] + for char, char_pins in self._map.items(): + if pins == char_pins: + self._rmap[pins] = char + break + + +class LEDCharDisplay(LEDCollection): + """ + Extends :class:`LEDCollection` for a multi-segment LED display. + + `Multi-segment LED displays`_ typically have 7 pins (labelled "a" through + "g") representing 7 LEDs layed out in a figure-of-8 fashion. Frequently, an + eigth pin labelled "dp" is included for a trailing decimal-point: + + .. code-block:: text + + a + â”â”â”â”â” + f ┃ ┃ b + ┃ g ┃ + â”â”â”â”â” + e ┃ ┃ c + ┃ ┃ + â”â”â”â”┠• dp + d + + Other common layouts are 9, 14, and 16 segment displays which include + additional segments permitting more accurate renditions of alphanumerics. + For example: + + .. code-block:: text + + a + â”â”â”â”â” + f ┃╲i┃j╱┃ b + ┃ ╲┃╱k┃ + gâ”â” â”â”h + e ┃ ╱┃╲n┃ c + ┃╱l┃m╲┃ + â”â”â”â”┠• dp + d + + Such displays have either a common anode, or common cathode pin. This class + defaults to the latter; when using a common anode display *active_high* + should be set to :data:`False`. + + Instances of this class can be used to display characters or control + individual LEDs on the display. For example:: + + from gpiozero import LEDCharDisplay + + char = LEDCharDisplay(4, 5, 6, 7, 8, 9, 10, active_high=False) + char.value = 'C' + + If the class is constructed with 7 or 14 segments, a default :attr:`font` + will be loaded, mapping some ASCII characters to typical layouts. In other + cases, the default mapping will simply assign " " (space) to all LEDs off. + You can assign your own mapping at construction time or after + instantiation. + + While the example above shows the display with a :class:`str` value, + theoretically the *font* can map any value that can be the key in a + :class:`dict`, so the value of the display can be likewise be any valid + key value (e.g. you could map integer digits to LED patterns). That said, + there is one exception to this: when *dp* is specified to enable the + decimal-point, the :attr:`value` must be a :class:`str` as the presence + or absence of a "." suffix indicates whether the *dp* LED is lit. + + :type pins: int or str + :param \\*pins: + Specify the GPIO pins that the multi-segment display is attached to. + Pins should be in the LED segment order A, B, C, D, E, F, G, and will + be named automatically by the class. If a decimal-point pin is + present, specify it separately as the *dp* parameter. + + :type dp: int or str + :param dp: + If a decimal-point segment is present, specify it as this named + parameter. + + :type font: dict or None + :param font: + A mapping of values (typically characters, but may also be numbers) to + tuples of LED states. A default mapping for ASCII characters is + provided for 7 and 14 segment displays. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set all the + associated pins to HIGH. If :data:`False`, the :meth:`on` method will + set all pins to LOW (the :meth:`off` method always does the opposite). + + :param initial_value: + The initial value to display. Defaults to space (" ") which typically + maps to all LEDs being inactive. If :data:`None`, each device will be + left in whatever state the pin is found in when configured for output + (warning: this can be on). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Multi-segment LED displays: https://en.wikipedia.org/wiki/Seven-segment_display + """ + def __init__(self, *pins, **kwargs): + dp = kwargs.pop('dp', None) + font = kwargs.pop('font', None) + pwm = kwargs.pop('pwm', False) + active_high = kwargs.pop('active_high', True) + initial_value = kwargs.pop('initial_value', " ") + pin_factory = kwargs.pop('pin_factory', None) + if kwargs: + raise TypeError( + 'unexpected keyword argument: %s' % kwargs.popiem()[0]) + if not 1 < len(pins) <= 26: + raise PinInvalidPin( + 'Must have between 2 and 26 LEDs in LEDCharDisplay') + for pin in pins: + if isinstance(pin, LEDCollection): + raise PinInvalidPin( + 'Cannot use LEDCollection in LEDCharDisplay') + + if font is None: + if len(pins) in (7, 14): + # Only import pkg_resources here as merely importing it is + # slooooow! + from pkg_resources import resource_stream + font = { + 7: lambda: load_font_7seg( + resource_stream(__name__, 'fonts/7seg.txt')), + 14: lambda: load_font_14seg( + resource_stream(__name__, 'fonts/14seg.txt')), + }[len(pins)]() + else: + # Construct a default dict containing a definition for " " + font = {" ": (0,) * len(pins)} + self._font = LEDCharFont(font) + + pins = {chr(ord('a') + i): pin for i, pin in enumerate(pins)} + order = sorted(pins.keys()) + if dp is not None: + pins['dp'] = dp + order.append('dp') + super(LEDCharDisplay, self).__init__( + pwm=pwm, active_high=active_high, initial_value=None, + _order=order, pin_factory=pin_factory, **pins) + if initial_value is not None: + self.value = initial_value + + @property + def font(self): + """ + An :class:`LEDCharFont` mapping characters to tuples of LED states. + The font is mutable after construction. You can assign a tuple of LED + states to a character to modify the font, delete an existing character + in the font, or assign a mapping of characters to tuples to replace the + entire font. + + Note that modifying the :attr:`font` never alters the underlying LED + states. Only assignment to :attr:`value`, or calling the inherited + :class:`LEDCollection` methods (:meth:`on`, :meth:`off`, etc.) modifies + LED states. However, modifying the font may alter the character + returned by querying :attr:`value`. + """ + return self._font + + @font.setter + def font(self, value): + self._font = LEDCharFont(value) + + @property + def value(self): + """ + The character the display should show. This is mapped by the current + :attr:`font` to a tuple of LED states which is applied to the + underlying LED objects when this attribute is set. + + When queried, the current LED states are looked up in the font to + determine the character shown. If the current LED states do not + correspond to any character in the :attr:`font`, the value is + :data:`None`. + + It is possible for multiple characters in the font to map to the same + LED states (e.g. S and 5). In this case, if the font was constructed + from an ordered mapping (which is the default), then the first matching + mapping will always be returned. This also implies that the value + queried need not match the value set. + """ + state = super(LEDCharDisplay, self).value + if hasattr(self, 'dp'): + state, dp = state[:-1], state[-1] + else: + dp = False + try: + result = self._font._rmap[state] + except KeyError: + # Raising exceptions on lookup is problematic; in case the LED + # state is not representable we simply return None (although + # technically that is a valid item we can map :) + return None + else: + if dp: + return result + '.' + else: + return result + + @value.setter + def value(self, value): + for led, v in zip(self, self._parse_state(value)): + led.value = v + + def _parse_state(self, value): + if hasattr(self, 'dp'): + if len(value) > 1 and value.endswith('.'): + value = value[:-1] + dp = 1 + else: + dp = 0 + return self._font[value] + (dp,) + else: + return self._font[value] + + +class LEDMultiCharDisplay(CompositeOutputDevice): + """ + Wraps :class:`LEDCharDisplay` for multi-character `multiplexed`_ LED + character displays. + + The class is constructed with a *char* which is an instance of the + :class:`LEDCharDisplay` class, capable of controlling the LEDs in one + character of the display, and an additional set of *pins* that represent + the common cathode (or anode) of each character. + + .. warning:: + + You should not attempt to connect the common cathode (or anode) off + each character directly to a GPIO. Rather, use a set of transistors (or + some other suitable component capable of handling the current of all + the segment LEDs simultaneously) to connect the common cathode to + ground (or the common anode to the supply) and control those + transistors from the GPIOs specified under *pins*. + + The *active_high* parameter defaults to :data:`True`. Note that it only + applies to the specified *pins*, which are assumed to be controlling a set + of transistors (hence the default). The specified *char* will use its own + *active_high* parameter. Finally, *initial_value* defaults to a tuple of + :attr:`~LEDCharDisplay.value` attribute of the specified display multiplied + by the number of *pins* provided. + + When the :attr:`value` is set such that one or more characters in the + display differ in value, a background thread is implicitly started to + rotate the active character, relying on `persistence of vision`_ to display + the complete value. + + .. _multiplexed: https://en.wikipedia.org/wiki/Multiplexed_display + .. _persistence of vision: https://en.wikipedia.org/wiki/Persistence_of_vision + """ + def __init__(self, char, *pins, **kwargs): + active_high = kwargs.pop('active_high', True) + initial_value = kwargs.pop('initial_value', None) + pin_factory = kwargs.pop('pin_factory', None) + if kwargs: + raise TypeError( + 'unexpected keyword argument: %s' % kwargs.popiem()[0]) + if not isinstance(char, LEDCharDisplay): + raise ValueError('char must be an LEDCharDisplay') + if initial_value is None: + initial_value = (char.value,) * len(pins) + if pin_factory is None: + pin_factory = char.pin_factory + self._plex_thread = None + self._plex_delay = 0.005 + plex = CompositeOutputDevice(*( + OutputDevice( + pin, active_high=active_high, initial_value=None, + pin_factory=pin_factory) + for pin in pins + )) + super(LEDMultiCharDisplay, self).__init__( + plex=plex, char=char, pin_factory=pin_factory) + self.value = initial_value + + def close(self): + try: + self._stop_plex() + except AttributeError: + pass + super(LEDMultiCharDisplay, self).close() + + def _stop_plex(self): + if self._plex_thread: + self._plex_thread.stop() + self._plex_thread = None + + @property + def plex_delay(self): + """ + The delay (measured in seconds) in the loop used to switch each + character in the multiplexed display on. Defaults to 0.005 seconds + which is generally sufficient to provide a "stable" (non-flickery) + display. + """ + return self._plex_delay + + @plex_delay.setter + def plex_delay(self, value): + if value < 0: + raise BadWaitTime('plex_delay must be 0 or greater') + self._plex_delay = float(value) + + @property + def value(self): + """ + The sequence of values to display. + + This can be any sequence containing keys from the + :attr:`~LEDCharDisplay.font` of the associated character display. For + example, if the value consists only of single-character strings, it's + valid to assign a string to this property (as a string is simply a + sequence of individual character keys):: + + from gpiozero import LEDCharDisplay, LEDMultiCharDisplay + + c = LEDCharDisplay(4, 5, 6, 7, 8, 9, 10) + d = LEDMultiCharDisplay(c, 19, 20, 21, 22) + d.value = 'LEDS' + + However, things get more complicated if a decimal point is in use as + then this class needs to know explicitly where to break the value for + use on each character of the display. This can be handled by simply + assigning a sequence of strings thus:: + + from gpiozero import LEDCharDisplay, LEDMultiCharDisplay + + c = LEDCharDisplay(4, 5, 6, 7, 8, 9, 10) + d = LEDMultiCharDisplay(c, 19, 20, 21, 22) + d.value = ('L.', 'E', 'D', 'S') + + This is how the value will always be represented when queried (as a + tuple of individual values) as it neatly handles dealing with + heterogeneous types and the aforementioned decimal point issue. + + .. note:: + + The value also controls whether a background thread is in use to + multiplex the display. When all positions in the value are equal + the background thread is disabled and all characters are + simultaneously enabled. + """ + return self._value + + @value.setter + def value(self, value): + if len(value) > len(self.plex): + raise ValueError( + 'length of value must not exceed the number of characters in ' + 'the display') + elif len(value) < len(self.plex): + # Right-align the short value on the display + value = (' ',) * (len(self.plex) - len(value)) + tuple(value) + else: + value = tuple(value) + + # Get the list of tuples of states that the character LEDs will pass + # through. Prune any entirely blank state (which we can skip by never + # activating the plex for them) but remember which plex index each + # (non-blank) state is associated with + states = {} + for index, char in enumerate(value): + state = self.char._parse_state(char) + if any(state): + states.setdefault(state, set()).add(index) + # Calculate the transitions between states for an ordering of chars + # based on activated LEDs. This a vague attempt at minimizing the + # number of LEDs that need flipping between chars; to do this + # "properly" is O(n!) which gets silly quickly so ... fudge it + order = sorted(states) + if len(order) > 1: + transitions = [ + [(self.plex[index], 0) for index in states[old]] + + [ + (led, new_value) + for led, old_value, new_value in zip(self.char, old, new) + if old_value ^ new_value + ] + + [(self.plex[index], 1) for index in states[new]] + for old, new in pairwise(order + [order[0]]) + ] + else: + transitions = [] + + # Stop any current display thread and disable the display + self._stop_plex() + self.plex.off() + + # If there's any characters to display, set the character LEDs to the + # state of the first character in the display order. If there's + # transitions to display, activate the plex thread; otherwise, just + # switch on each plex with a char to display + if order: + for led, state in zip(self.char, order[0]): + led.value = state + if transitions: + self._plex_thread = GPIOThread(self._show_chars, (transitions,)) + self._plex_thread.start() + else: + for index in states[order[0]]: + self.plex[index].on() + self._value = value + + def _show_chars(self, transitions): + for transition in cycle(transitions): + for device, value in transition: + device.value = value + if self._plex_thread.stopping.wait(self._plex_delay): + break + + +class PiHutXmasTree(LEDBoard): + """ + Extends :class:`LEDBoard` for `The Pi Hut's Xmas board`_: a 3D Christmas + tree board with 24 red LEDs and a white LED as a star on top. + + The 24 red LEDs can be accessed through the attributes led0, led1, led2, + and so on. The white star LED is accessed through the :attr:`star` + attribute. Alternatively, as with all descendents of :class:`LEDBoard`, + you can treat the instance as a sequence of LEDs (the first element is the + :attr:`star`). + + The Xmas Tree board pins are fixed and therefore there's no need to specify + them when constructing this class. The following example turns all the LEDs + on one at a time:: + + from gpiozero import PiHutXmasTree + from time import sleep + + tree = PiHutXmasTree() + + for light in tree: + light.on() + sleep(1) + + The following example turns the star LED on and sets all the red LEDs to + flicker randomly:: + + from gpiozero import PiHutXmasTree + from gpiozero.tools import random_values + from signal import pause + + tree = PiHutXmasTree(pwm=True) + + tree.star.on() + + for led in tree[1:]: + led.source_delay = 0.1 + led.source = random_values() + + pause() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _The Pi Hut's Xmas board: https://thepihut.com/xmas + + .. attribute:: star + + Returns the :class:`LED` or :class:`PWMLED` representing the white + star on top of the tree. + + .. attribute:: led0, led1, led2, ... + + Returns the :class:`LED` or :class:`PWMLED` representing one of the red + LEDs. There are actually 24 of these properties named led0, led1, and + so on but for the sake of brevity we represent all 24 under this + section. + """ + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + pins_dict = OrderedDict(star=2) + pins = (4, 15, 13, 21, 25, 8, 5, 10, 16, 17, 27, 26, + 24, 9, 12, 6, 20, 19, 14, 18, 11, 7, 23, 22) + for i, pin in enumerate(pins): + pins_dict['led%d' % (i+1)] = pin + super(PiHutXmasTree, self).__init__( + pwm=pwm, initial_value=initial_value, + _order=pins_dict.keys(), + pin_factory=pin_factory, + **pins_dict + ) + + +class LedBorg(RGBLED): + """ + Extends :class:`RGBLED` for the `PiBorg LedBorg`_: an add-on board + containing a very bright RGB LED. + + The LedBorg pins are fixed and therefore there's no need to specify them + when constructing this class. The following example turns the LedBorg + purple:: + + from gpiozero import LedBorg + + led = LedBorg() + led.color = (1, 0, 1) + + :type initial_value: ~colorzero.Color or tuple + :param initial_value: + The initial color for the LedBorg. Defaults to black ``(0, 0, 0)``. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMLED` instances for + each component of the LedBorg. If :data:`False`, construct regular + :class:`LED` instances, which prevents smooth color graduations. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _PiBorg LedBorg: https://www.piborg.org/ledborg + """ + + def __init__(self, initial_value=(0, 0, 0), pwm=True, pin_factory=None): + super(LedBorg, self).__init__( + red='BOARD11', green='BOARD13', blue='BOARD15', + pwm=pwm, initial_value=initial_value, pin_factory=pin_factory + ) + + +class PiLiter(LEDBoard): + """ + Extends :class:`LEDBoard` for the `Ciseco Pi-LITEr`_: a strip of 8 very + bright LEDs. + + The Pi-LITEr pins are fixed and therefore there's no need to specify them + when constructing this class. The following example turns on all the LEDs + of the Pi-LITEr:: + + from gpiozero import PiLiter + + lite = PiLiter() + lite.on() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each LED will be left in whatever state the pin is found + in when configured for output (warning: this can be on). If + :data:`True`, the each LED will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/ + """ + + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + pins = ('BOARD7', 'BOARD11', 'BOARD13', 'BOARD12', + 'BOARD15', 'BOARD16', 'BOARD18', 'BOARD22') + super(PiLiter, self).__init__( + *pins, pwm=pwm, initial_value=initial_value, pin_factory=pin_factory + ) + + +class PiLiterBarGraph(LEDBarGraph): + """ + Extends :class:`LEDBarGraph` to treat the `Ciseco Pi-LITEr`_ as an + 8-segment bar graph. + + The Pi-LITEr pins are fixed and therefore there's no need to specify them + when constructing this class. The following example sets the graph value + to 0.5:: + + from gpiozero import PiLiterBarGraph + + graph = PiLiterBarGraph() + graph.value = 0.5 + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances for each pin. If + :data:`False` (the default), construct regular :class:`LED` instances. + + :param float initial_value: + The initial :attr:`value` of the graph given as a float between -1 and + +1. Defaults to ``0.0``. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/ + """ + + def __init__(self, pwm=False, initial_value=0.0, pin_factory=None): + pins = ('BOARD7', 'BOARD11', 'BOARD13', 'BOARD12', + 'BOARD15', 'BOARD16', 'BOARD18', 'BOARD22') + super(PiLiterBarGraph, self).__init__( + *pins, pwm=pwm, initial_value=initial_value, pin_factory=pin_factory + ) + + +class TrafficLights(LEDBoard): + """ + Extends :class:`LEDBoard` for devices containing red, yellow, and green + LEDs. + + The following example initializes a device connected to GPIO pins 2, 3, + and 4, then lights the amber (yellow) LED attached to GPIO 3:: + + from gpiozero import TrafficLights + + traffic = TrafficLights(2, 3, 4) + traffic.amber.on() + + :type red: int or str + :param red: + The GPIO pin that the red LED is attached to. See :ref:`pin-numbering` + for valid pin numbers. + + :type amber: int or str or None + :param amber: + The GPIO pin that the amber LED is attached to. See + :ref:`pin-numbering` for valid pin numbers. + + :type yellow: int or str or None + :param yellow: + The GPIO pin that the yellow LED is attached to. This is merely an + alias for the ``amber`` parameter; you can't specify both ``amber`` and + ``yellow``. See :ref:`pin-numbering` for valid pin numbers. + + :type green: int or str + :param green: + The GPIO pin that the green LED is attached to. See + :ref:`pin-numbering` for valid pin numbers. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. attribute:: red + + The red :class:`LED` or :class:`PWMLED`. + + .. attribute:: amber + + The amber :class:`LED` or :class:`PWMLED`. Note that this attribute + will not be present when the instance is constructed with the + *yellow* keyword parameter. + + .. attribute:: yellow + + The yellow :class:`LED` or :class:`PWMLED`. Note that this attribute + will only be present when the instance is constructed with the + *yellow* keyword parameter. + + .. attribute:: green + + The green :class:`LED` or :class:`PWMLED`. + """ + def __init__(self, red=None, amber=None, green=None, + pwm=False, initial_value=False, yellow=None, + pin_factory=None): + if amber is not None and yellow is not None: + raise OutputDeviceBadValue( + 'Only one of amber or yellow can be specified') + devices = OrderedDict((('red', red), )) + self._display_yellow = amber is None and yellow is not None + if self._display_yellow: + devices['yellow'] = yellow + else: + devices['amber'] = amber + devices['green'] = green + if not all(p is not None for p in devices.values()): + raise GPIOPinMissing('%s pins must be provided' % + ', '.join(devices.keys())) + super(TrafficLights, self).__init__( + pwm=pwm, initial_value=initial_value, + _order=devices.keys(), pin_factory=pin_factory, + **devices) + + def __getattr__(self, name): + if name == 'amber' and self._display_yellow: + name = 'yellow' + elif name == 'yellow' and not self._display_yellow: + name = 'amber' + return super(TrafficLights, self).__getattr__(name) + + +class PiTraffic(TrafficLights): + """ + Extends :class:`TrafficLights` for the `Low Voltage Labs PI-TRAFFIC`_ + vertical traffic lights board when attached to GPIO pins 9, 10, and 11. + + There's no need to specify the pins if the PI-TRAFFIC is connected to the + default pins (9, 10, 11). The following example turns on the amber LED on + the PI-TRAFFIC:: + + from gpiozero import PiTraffic + + traffic = PiTraffic() + traffic.amber.on() + + To use the PI-TRAFFIC board when attached to a non-standard set of pins, + simply use the parent class, :class:`TrafficLights`. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type initial_value: bool or None + :param bool initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Low Voltage Labs PI-TRAFFIC: http://lowvoltagelabs.com/products/pi-traffic/ + """ + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + super(PiTraffic, self).__init__( + 'BOARD21', 'BOARD19', 'BOARD23', + pwm=pwm, initial_value=initial_value, pin_factory=pin_factory + ) + + +class PiStop(TrafficLights): + """ + Extends :class:`TrafficLights` for the `PiHardware Pi-Stop`_: a vertical + traffic lights board. + + The following example turns on the amber LED on a Pi-Stop connected to + location ``A+``:: + + from gpiozero import PiStop + + traffic = PiStop('A+') + traffic.amber.on() + + :param str location: + The `location`_ on the GPIO header to which the Pi-Stop is connected. + Must be one of: ``A``, ``A+``, ``B``, ``B+``, ``C``, ``D``. + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type initial_value: bool or None + :param bool initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _PiHardware Pi-Stop: https://pihw.wordpress.com/meltwaters-pi-hardware-kits/pi-stop/ + .. _location: https://github.com/PiHw/Pi-Stop/blob/master/markdown_source/markdown/Discover-PiStop.md + """ + LOCATIONS = { + 'A': ('BOARD26', 'BOARD24', 'BOARD22'), + 'A+': ('BOARD40', 'BOARD38', 'BOARD36'), + 'B': ('BOARD19', 'BOARD21', 'BOARD23'), + 'B+': ('BOARD33', 'BOARD35', 'BOARD37'), + 'C': ('BOARD12', 'BOARD10', 'BOARD8'), + 'D': ('BOARD3', 'BOARD5', 'BOARD7'), + } + + def __init__( + self, location=None, pwm=False, initial_value=False, + pin_factory=None): + gpios = self.LOCATIONS.get(location, None) + if gpios is None: + raise ValueError('location must be one of: %s' % + ', '.join(sorted(self.LOCATIONS.keys()))) + super(PiStop, self).__init__( + *gpios, pwm=pwm, initial_value=initial_value, + pin_factory=pin_factory) + + +class StatusZero(LEDBoard): + """ + Extends :class:`LEDBoard` for The Pi Hut's `STATUS Zero`_: a Pi Zero sized + add-on board with three sets of red/green LEDs to provide a status + indicator. + + The following example designates the first strip the label "wifi" and the + second "raining", and turns them green and red respectfully:: + + from gpiozero import StatusZero + + status = StatusZero('wifi', 'raining') + status.wifi.green.on() + status.raining.red.on() + + Each designated label will contain two :class:`LED` objects named "red" + and "green". + + :param str \\*labels: + Specify the names of the labels you wish to designate the strips to. + You can list up to three labels. If no labels are given, three strips + will be initialised with names 'one', 'two', and 'three'. If some, but + not all strips are given labels, any remaining strips will not be + initialised. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _STATUS Zero: https://thepihut.com/statuszero + + .. attribute:: your-label-here, your-label-here, ... + + This entry represents one of the three labelled attributes supported on + the STATUS Zero board. It is an :class:`LEDBoard` which contains: + + .. attribute:: red + + The :class:`LED` or :class:`PWMLED` representing the red LED + next to the label. + + .. attribute:: green + + The :class:`LED` or :class:`PWMLED` representing the green LED + next to the label. + """ + default_labels = ('one', 'two', 'three') + + def __init__(self, *labels, **kwargs): + pins = ( + ('BOARD11', 'BOARD7'), + ('BOARD15', 'BOARD13'), + ('BOARD21', 'BOARD19'), + ) + pin_factory = kwargs.pop('pin_factory', None) + if len(labels) == 0: + labels = self.default_labels + elif len(labels) > len(pins): + raise ValueError("StatusZero doesn't support more than three labels") + dup, count = Counter(labels).most_common(1)[0] + if count > 1: + raise ValueError("Duplicate label %s" % dup) + super(StatusZero, self).__init__( + _order=labels, pin_factory=pin_factory, **{ + label: LEDBoard( + red=red, green=green, _order=('red', 'green'), + pin_factory=pin_factory, **kwargs + ) + for (green, red), label in zip(pins, labels) + } + ) + + +class StatusBoard(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` for The Pi Hut's `STATUS`_ board: a + HAT sized add-on board with five sets of red/green LEDs and buttons to + provide a status indicator with additional input. + + The following example designates the first strip the label "wifi" and the + second "raining", turns the wifi green and then activates the button to + toggle its lights when pressed:: + + from gpiozero import StatusBoard + + status = StatusBoard('wifi', 'raining') + status.wifi.lights.green.on() + status.wifi.button.when_pressed = status.wifi.lights.toggle + + Each designated label will contain a "lights" :class:`LEDBoard` containing + two :class:`LED` objects named "red" and "green", and a :class:`Button` + object named "button". + + :param str \\*labels: + Specify the names of the labels you wish to designate the strips to. + You can list up to five labels. If no labels are given, five strips + will be initialised with names 'one' to 'five'. If some, but not all + strips are given labels, any remaining strips will not be initialised. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _STATUS: https://thepihut.com/status + + .. attribute:: your-label-here, your-label-here, ... + + This entry represents one of the five labelled attributes supported on + the STATUS board. It is an :class:`CompositeOutputDevice` which + contains: + + .. attribute:: lights + + A :class:`LEDBoard` representing the lights next to the label. It + contains: + + .. attribute:: red + + The :class:`LED` or :class:`PWMLED` representing the red LED + next to the label. + + .. attribute:: green + + The :class:`LED` or :class:`PWMLED` representing the green LED + next to the label. + + .. attribute:: button + + A :class:`Button` representing the button next to the label. + """ + default_labels = ('one', 'two', 'three', 'four', 'five') + + def __init__(self, *labels, **kwargs): + pins = ( + ('BOARD11', 'BOARD7', 'BOARD8'), + ('BOARD15', 'BOARD13', 'BOARD35'), + ('BOARD21', 'BOARD19', 'BOARD10'), + ('BOARD29', 'BOARD23', 'BOARD37'), + ('BOARD33', 'BOARD31', 'BOARD12'), + ) + pin_factory = kwargs.pop('pin_factory', None) + if len(labels) == 0: + labels = self.default_labels + elif len(labels) > len(pins): + raise ValueError("StatusBoard doesn't support more than five labels") + dup, count = Counter(labels).most_common(1)[0] + if count > 1: + raise ValueError("Duplicate label %s" % dup) + super(StatusBoard, self).__init__( + _order=labels, pin_factory=pin_factory, **{ + label: CompositeOutputDevice( + button=Button(button, pin_factory=pin_factory), + lights=LEDBoard( + red=red, green=green, _order=('red', 'green'), + pin_factory=pin_factory, **kwargs + ), _order=('button', 'lights'), pin_factory=pin_factory + ) + for (green, red, button), label in zip(pins, labels) + } + ) + + +class SnowPi(LEDBoard): + """ + Extends :class:`LEDBoard` for the `Ryanteck SnowPi`_ board. + + The SnowPi pins are fixed and therefore there's no need to specify them + when constructing this class. The following example turns on the eyes, sets + the nose pulsing, and the arms blinking:: + + from gpiozero import SnowPi + + snowman = SnowPi(pwm=True) + snowman.eyes.on() + snowman.nose.pulse() + snowman.arms.blink() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type initial_value: bool or None + :param bool initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Ryanteck SnowPi: https://ryanteck.uk/raspberry-pi/114-snowpi-the-gpio-snowman-for-raspberry-pi-0635648608303.html + + .. attribute:: arms + + A :class:`LEDBoard` representing the arms of the snow man. It contains + the following attributes: + + .. attribute:: left, right + + Two :class:`LEDBoard` objects representing the left and right arms + of the snow-man. They contain: + + .. attribute:: top, middle, bottom + + The :class:`LED` or :class:`PWMLED` down the snow-man's arms. + + .. attribute:: eyes + + A :class:`LEDBoard` representing the eyes of the snow-man. It contains: + + .. attribute:: left, right + + The :class:`LED` or :class:`PWMLED` for the snow-man's eyes. + + .. attribute:: nose + + The :class:`LED` or :class:`PWMLED` for the snow-man's nose. + """ + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + super(SnowPi, self).__init__( + arms=LEDBoard( + left=LEDBoard( + top='BOARD11', middle='BOARD12', bottom='BOARD15', + pwm=pwm, initial_value=initial_value, + _order=('top', 'middle', 'bottom'), + pin_factory=pin_factory), + right=LEDBoard( + top='BOARD26', middle='BOARD24', bottom='BOARD21', + pwm=pwm, initial_value=initial_value, + _order=('top', 'middle', 'bottom'), + pin_factory=pin_factory), + _order=('left', 'right'), + pin_factory=pin_factory + ), + eyes=LEDBoard( + left='BOARD16', right='BOARD18', + pwm=pwm, initial_value=initial_value, + _order=('left', 'right'), + pin_factory=pin_factory + ), + nose='BOARD22', + pwm=pwm, initial_value=initial_value, + _order=('eyes', 'nose', 'arms'), + pin_factory=pin_factory + ) + + +class TrafficLightsBuzzer(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` and is a generic class for HATs with + traffic lights, a button and a buzzer. + + :param TrafficLights lights: + An instance of :class:`TrafficLights` representing the traffic lights + of the HAT. + + :param Buzzer buzzer: + An instance of :class:`Buzzer` representing the buzzer on the HAT. + + :param Button button: + An instance of :class:`Button` representing the button on the HAT. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. attribute:: lights + + The :class:`TrafficLights` instance passed as the *lights* parameter. + + .. attribute:: buzzer + + The :class:`Buzzer` instance passed as the *buzzer* parameter. + + .. attribute:: button + + The :class:`Button` instance passed as the *button* parameter. + """ + def __init__(self, lights, buzzer, button, pin_factory=None): + super(TrafficLightsBuzzer, self).__init__( + lights=lights, buzzer=buzzer, button=button, + _order=('lights', 'buzzer', 'button'), + pin_factory=pin_factory + ) + + +class FishDish(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` for the `Pi Supply FishDish`_: traffic + light LEDs, a button and a buzzer. + + The FishDish pins are fixed and therefore there's no need to specify them + when constructing this class. The following example waits for the button + to be pressed on the FishDish, then turns on all the LEDs:: + + from gpiozero import FishDish + + fish = FishDish() + fish.button.wait_for_press() + fish.lights.on() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Pi Supply FishDish: https://www.pi-supply.com/product/fish-dish-raspberry-pi-led-buzzer-board/ + """ + def __init__(self, pwm=False, pin_factory=None): + super(FishDish, self).__init__( + lights=TrafficLights( + 'BOARD21', 'BOARD15', 'BOARD7', pwm=pwm, pin_factory=pin_factory + ), + buzzer=Buzzer('BOARD24', pin_factory=pin_factory), + button=Button('BOARD26', pull_up=False, pin_factory=pin_factory), + _order=('lights', 'buzzer', 'button'), + pin_factory=pin_factory + ) + + +class TrafficHat(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` for the `Pi Supply Traffic HAT`_: a + board with traffic light LEDs, a button and a buzzer. + + The Traffic HAT pins are fixed and therefore there's no need to specify + them when constructing this class. The following example waits for the + button to be pressed on the Traffic HAT, then turns on all the LEDs:: + + from gpiozero import TrafficHat + + hat = TrafficHat() + hat.button.wait_for_press() + hat.lights.on() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Pi Supply Traffic HAT: https://uk.pi-supply.com/products/traffic-hat-for-raspberry-pi + """ + def __init__(self, pwm=False, pin_factory=None): + super(TrafficHat, self).__init__( + lights=TrafficLights( + 'BOARD18', 'BOARD16', 'BOARD15', + pwm=pwm, pin_factory=pin_factory + ), + buzzer=Buzzer('BOARD29', pin_factory=pin_factory), + button=Button('BOARD22', pin_factory=pin_factory), + _order=('lights', 'buzzer', 'button'), + pin_factory=pin_factory + ) + + +class TrafficpHat(TrafficLights): + """ + Extends :class:`TrafficLights` for the `Pi Supply Traffic pHAT`_: a small + board with traffic light LEDs. + + The Traffic pHAT pins are fixed and therefore there's no need to specify + them when constructing this class. The following example then turns on all + the LEDs:: + + from gpiozero import TrafficpHat + phat = TrafficpHat() + phat.red.on() + phat.blink() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances. + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Pi Supply Traffic pHAT: http://pisupp.ly/trafficphat + """ + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + super(TrafficpHat, self).__init__( + red='BOARD22', amber='BOARD18', green='BOARD16', + pwm=pwm, initial_value=initial_value, pin_factory=pin_factory + ) + + +class Robot(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` to represent a generic dual-motor robot. + + This class is constructed with two tuples representing the forward and + backward pins of the left and right controllers respectively. For example, + if the left motor's controller is connected to GPIOs 4 and 14, while the + right motor's controller is connected to GPIOs 17 and 18 then the following + example will drive the robot forward:: + + from gpiozero import Robot + + robot = Robot(left=(4, 14), right=(17, 18)) + robot.forward() + + :param tuple left: + A tuple of two (or three) GPIO pins representing the forward and + backward inputs of the left motor's controller. Use three pins if your + motor controller requires an enable pin. + + :param tuple right: + A tuple of two (or three) GPIO pins representing the forward and + backward inputs of the right motor's controller. Use three pins if your + motor controller requires an enable pin. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller pins, allowing both direction and + variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. attribute:: left_motor + + The :class:`Motor` on the left of the robot. + + .. attribute:: right_motor + + The :class:`Motor` on the right of the robot. + """ + def __init__(self, left=None, right=None, pwm=True, pin_factory=None, *args): + # *args is a hack to ensure a useful message is shown when pins are + # supplied as sequential positional arguments e.g. 2, 3, 4, 5 + if not isinstance(left, tuple) or not isinstance(right, tuple): + raise GPIOPinMissing('left and right motor pins must be given as ' + 'tuples') + super(Robot, self).__init__( + left_motor=Motor(*left, pwm=pwm, pin_factory=pin_factory), + right_motor=Motor(*right, pwm=pwm, pin_factory=pin_factory), + _order=('left_motor', 'right_motor'), + pin_factory=pin_factory + ) + + @property + def value(self): + """ + Represents the motion of the robot as a tuple of (left_motor_speed, + right_motor_speed) with ``(-1, -1)`` representing full speed backwards, + ``(1, 1)`` representing full speed forwards, and ``(0, 0)`` + representing stopped. + """ + return super(Robot, self).value + + @value.setter + def value(self, value): + self.left_motor.value, self.right_motor.value = value + + def forward(self, speed=1, **kwargs): + """ + Drive the robot forward by running both motors forward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + + :param float curve_left: + The amount to curve left while moving forwards, by driving the + left motor at a slower speed. Maximum *curve_left* is 1, the + default is 0 (no curve). This parameter can only be specified as a + keyword parameter, and is mutually exclusive with *curve_right*. + + :param float curve_right: + The amount to curve right while moving forwards, by driving the + right motor at a slower speed. Maximum *curve_right* is 1, the + default is 0 (no curve). This parameter can only be specified as a + keyword parameter, and is mutually exclusive with *curve_left*. + """ + curve_left = kwargs.pop('curve_left', 0) + curve_right = kwargs.pop('curve_right', 0) + if kwargs: + raise TypeError('unexpected argument %s' % kwargs.popitem()[0]) + if not 0 <= curve_left <= 1: + raise ValueError('curve_left must be between 0 and 1') + if not 0 <= curve_right <= 1: + raise ValueError('curve_right must be between 0 and 1') + if curve_left != 0 and curve_right != 0: + raise ValueError("curve_left and curve_right can't be used at " + "the same time") + self.left_motor.forward(speed * (1 - curve_left)) + self.right_motor.forward(speed * (1 - curve_right)) + + def backward(self, speed=1, **kwargs): + """ + Drive the robot backward by running both motors backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + + :param float curve_left: + The amount to curve left while moving backwards, by driving the + left motor at a slower speed. Maximum *curve_left* is 1, the + default is 0 (no curve). This parameter can only be specified as a + keyword parameter, and is mutually exclusive with *curve_right*. + + :param float curve_right: + The amount to curve right while moving backwards, by driving the + right motor at a slower speed. Maximum *curve_right* is 1, the + default is 0 (no curve). This parameter can only be specified as a + keyword parameter, and is mutually exclusive with *curve_left*. + """ + curve_left = kwargs.pop('curve_left', 0) + curve_right = kwargs.pop('curve_right', 0) + if kwargs: + raise TypeError('unexpected argument %s' % kwargs.popitem()[0]) + if not 0 <= curve_left <= 1: + raise ValueError('curve_left must be between 0 and 1') + if not 0 <= curve_right <= 1: + raise ValueError('curve_right must be between 0 and 1') + if curve_left != 0 and curve_right != 0: + raise ValueError("curve_left and curve_right can't be used at " + "the same time") + self.left_motor.backward(speed * (1 - curve_left)) + self.right_motor.backward(speed * (1 - curve_right)) + + def left(self, speed=1): + """ + Make the robot turn left by running the right motor forward and left + motor backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.right_motor.forward(speed) + self.left_motor.backward(speed) + + def right(self, speed=1): + """ + Make the robot turn right by running the left motor forward and right + motor backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.left_motor.forward(speed) + self.right_motor.backward(speed) + + def reverse(self): + """ + Reverse the robot's current motor directions. If the robot is currently + running full speed forward, it will run full speed backward. If the + robot is turning left at half-speed, it will turn right at half-speed. + If the robot is currently stopped it will remain stopped. + """ + self.left_motor.reverse() + self.right_motor.reverse() + + def stop(self): + """ + Stop the robot. + """ + self.left_motor.stop() + self.right_motor.stop() + + +class RyanteckRobot(Robot): + """ + Extends :class:`Robot` for the `Ryanteck motor controller board`_. + + The Ryanteck MCB pins are fixed and therefore there's no need to specify + them when constructing this class. The following example drives the robot + forward:: + + from gpiozero import RyanteckRobot + + robot = RyanteckRobot() + robot.forward() + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller pins, allowing both direction and + variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Ryanteck motor controller board: https://uk.pi-supply.com/products/ryanteck-rtk-000-001-motor-controller-board-kit-raspberry-pi + """ + + def __init__(self, pwm=True, pin_factory=None): + super(RyanteckRobot, self).__init__( + left=('BOARD11', 'BOARD12'), right=('BOARD15', 'BOARD16'), + pwm=pwm, pin_factory=pin_factory + ) + + +class CamJamKitRobot(Robot): + """ + Extends :class:`Robot` for the `CamJam #3 EduKit`_ motor controller board. + + The CamJam robot controller pins are fixed and therefore there's no need + to specify them when constructing this class. The following example drives + the robot forward:: + + from gpiozero import CamJamKitRobot + + robot = CamJamKitRobot() + robot.forward() + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller pins, allowing both direction and + variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _CamJam #3 EduKit: http://camjam.me/?page_id=1035 + """ + def __init__(self, pwm=True, pin_factory=None): + super(CamJamKitRobot, self).__init__( + left=('BOARD21', 'BOARD19'), right=('BOARD26', 'BOARD24'), + pwm=pwm, pin_factory=pin_factory + ) + + +class PhaseEnableRobot(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` to represent a dual-motor robot based + around a Phase/Enable motor board. + + This class is constructed with two tuples representing the phase + (direction) and enable (speed) pins of the left and right controllers + respectively. For example, if the left motor's controller is connected to + GPIOs 12 and 5, while the right motor's controller is connected to GPIOs 13 + and 6 so the following example will drive the robot forward:: + + from gpiozero import PhaseEnableRobot + + robot = PhaseEnableRobot(left=(5, 12), right=(6, 13)) + robot.forward() + + :param tuple left: + A tuple of two GPIO pins representing the phase and enable inputs + of the left motor's controller. + + :param tuple right: + A tuple of two GPIO pins representing the phase and enable inputs + of the right motor's controller. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller's enable pins, allowing both + direction and variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. attribute:: left_motor + + The :class:`PhaseEnableMotor` on the left of the robot. + + .. attribute:: right_motor + + The :class:`PhaseEnableMotor` on the right of the robot. + """ + def __init__(self, left=None, right=None, pwm=True, pin_factory=None, *args): + # *args is a hack to ensure a useful message is shown when pins are + # supplied as sequential positional arguments e.g. 2, 3, 4, 5 + if not isinstance(left, tuple) or not isinstance(right, tuple): + raise GPIOPinMissing( + 'left and right motor pins must be given as tuples' + ) + super(PhaseEnableRobot, self).__init__( + left_motor=PhaseEnableMotor(*left, pwm=pwm, pin_factory=pin_factory), + right_motor=PhaseEnableMotor(*right, pwm=pwm, pin_factory=pin_factory), + _order=('left_motor', 'right_motor'), + pin_factory=pin_factory + ) + + @property + def value(self): + """ + Returns a tuple of two floating point values (-1 to 1) representing the + speeds of the robot's two motors (left and right). This property can + also be set to alter the speed of both motors. + """ + return super(PhaseEnableRobot, self).value + + @value.setter + def value(self, value): + self.left_motor.value, self.right_motor.value = value + + def forward(self, speed=1): + """ + Drive the robot forward by running both motors forward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.left_motor.forward(speed) + self.right_motor.forward(speed) + + def backward(self, speed=1): + """ + Drive the robot backward by running both motors backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.left_motor.backward(speed) + self.right_motor.backward(speed) + + def left(self, speed=1): + """ + Make the robot turn left by running the right motor forward and left + motor backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.right_motor.forward(speed) + self.left_motor.backward(speed) + + def right(self, speed=1): + """ + Make the robot turn right by running the left motor forward and right + motor backward. + + :param float speed: + Speed at which to drive the motors, as a value between 0 (stopped) + and 1 (full speed). The default is 1. + """ + self.left_motor.forward(speed) + self.right_motor.backward(speed) + + def reverse(self): + """ + Reverse the robot's current motor directions. If the robot is currently + running full speed forward, it will run full speed backward. If the + robot is turning left at half-speed, it will turn right at half-speed. + If the robot is currently stopped it will remain stopped. + """ + self.left_motor.value = -self.left_motor.value + self.right_motor.value = -self.right_motor.value + + def stop(self): + """ + Stop the robot. + """ + self.left_motor.stop() + self.right_motor.stop() + + +class PololuDRV8835Robot(PhaseEnableRobot): + """ + Extends :class:`PhaseEnableRobot` for the `Pololu DRV8835 Dual Motor Driver + Kit`_. + + The Pololu DRV8835 pins are fixed and therefore there's no need to specify + them when constructing this class. The following example drives the robot + forward:: + + from gpiozero import PololuDRV8835Robot + + robot = PololuDRV8835Robot() + robot.forward() + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller's enable pins, allowing both + direction and variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Pololu DRV8835 Dual Motor Driver Kit: https://www.pololu.com/product/2753 + """ + def __init__(self, pwm=True, pin_factory=None): + super(PololuDRV8835Robot, self).__init__( + left=('BOARD29', 'BOARD32'), right=('BOARD31', 'BOARD33'), + pwm=pwm, pin_factory=pin_factory + ) + + +class _EnergenieMaster(SharedMixin, CompositeOutputDevice): + def __init__(self, pin_factory=None): + self._lock = Lock() + super(_EnergenieMaster, self).__init__( + *( + OutputDevice(pin, pin_factory=pin_factory) + for pin in ('BOARD11', 'BOARD15', 'BOARD16', 'BOARD13') + ), + mode=OutputDevice('BOARD18', pin_factory=pin_factory), + enable=OutputDevice('BOARD22', pin_factory=pin_factory), + _order=('mode', 'enable'), pin_factory=pin_factory + ) + + def close(self): + if getattr(self, '_lock', None): + with self._lock: + super(_EnergenieMaster, self).close() + self._lock = None + + @classmethod + def _shared_key(cls, pin_factory): + # There's only one Energenie master + return None + + def transmit(self, socket, enable): + with self._lock: + try: + code = (8 * bool(enable)) + (8 - socket) + for bit in self[:4]: + bit.value = (code & 1) + code >>= 1 + sleep(0.1) + self.enable.on() + sleep(0.25) + finally: + self.enable.off() + + +class Energenie(SourceMixin, Device): + """ + Extends :class:`Device` to represent an `Energenie socket`_ controller. + + This class is constructed with a socket number and an optional initial + state (defaults to :data:`False`, meaning off). Instances of this class can + be used to switch peripherals on and off. For example:: + + from gpiozero import Energenie + + lamp = Energenie(1) + lamp.on() + + :param int socket: + Which socket this instance should control. This is an integer number + between 1 and 4. + + :type initial_value: bool or None + :param initial_value: + The initial state of the socket. As Energenie sockets provide no + means of reading their state, you may provide an initial state for + the socket, which will be set upon construction. This defaults to + :data:`False` which will switch the socket off. + Specifying :data:`None` will not set any initial state nor transmit any + control signal to the device. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Energenie socket: https://energenie4u.co.uk/index.php/catalogue/product/ENER002-2PI + """ + def __init__(self, socket=None, initial_value=False, pin_factory=None): + if socket is None: + raise EnergenieSocketMissing('socket number must be provided') + if not (1 <= socket <= 4): + raise EnergenieBadSocket('socket number must be between 1 and 4') + self._value = None + super(Energenie, self).__init__(pin_factory=pin_factory) + self._socket = socket + self._master = _EnergenieMaster(pin_factory=pin_factory) + if initial_value: + self.on() + elif initial_value is not None: + self.off() + + def close(self): + if getattr(self, '_master', None): + self._master.close() + self._master = None + + @property + def closed(self): + return self._master is None + + def __repr__(self): + try: + self._check_open() + return "" % self._socket + except DeviceClosed: + return "" + + @property + def socket(self): + """ + Returns the socket number. + """ + return self._socket + + @property + def value(self): + """ + Returns :data:`True` if the socket is on and :data:`False` if the + socket is off. Setting this property changes the state of the socket. + Returns :data:`None` only when constructed with :data:`initial_value` + set to :data:`None` and neither :data:`on()` nor :data:`off()` have + been called since construction. + """ + return self._value + + @value.setter + def value(self, value): + if value is None: + raise TypeError('value cannot be None') + value = bool(value) + self._master.transmit(self._socket, value) + self._value = value + + def on(self): + """ + Turns the socket on. + """ + self.value = True + + def off(self): + """ + Turns the socket off. + """ + self.value = False + + +class PumpkinPi(LEDBoard): + """ + Extends :class:`LEDBoard` for the `ModMyPi PumpkinPi`_ board. + + There are twelve LEDs connected up to individual pins, so for the PumpkinPi + the pins are fixed. For example:: + + from gpiozero import PumpkinPi + + pumpkin = PumpkinPi(pwm=True) + pumpkin.sides.pulse() + pumpkin.off() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED. If :data:`False` (the default), construct regular :class:`LED` + instances + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), all LEDs will be off initially. If + :data:`None`, each device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _ModMyPi PumpkinPi: https://www.modmypi.com/halloween-pumpkin-programmable-kit + + .. attribute:: sides + + A :class:`LEDBoard` representing the LEDs around the edge of the + pumpkin. It contains: + + .. attribute:: left, right + + Two :class:`LEDBoard` instances representing the LEDs on the left + and right sides of the pumpkin. They each contain: + + .. attribute:: top, midtop, middle, midbottom, bottom + + Each :class:`LED` or :class:`PWMLED` around the specified side + of the pumpkin. + + .. attribute:: eyes + + A :class:`LEDBoard` representing the eyes of the pumpkin. It contains: + + .. attribute:: left, right + + The :class:`LED` or :class:`PWMLED` for each of the pumpkin's eyes. + """ + def __init__(self, pwm=False, initial_value=False, pin_factory=None): + super(PumpkinPi, self).__init__( + sides=LEDBoard( + left=LEDBoard( + bottom='BOARD12', midbottom='BOARD11', middle='BOARD36', + midtop='BOARD33', top='BOARD18', + pwm=pwm, initial_value=initial_value, + _order=('bottom', 'midbottom', 'middle', 'midtop', 'top'), + pin_factory=pin_factory), + right=LEDBoard( + bottom='BOARD35', midbottom='BOARD38', middle='BOARD40', + midtop='BOARD15', top='BOARD16', + pwm=pwm, initial_value=initial_value, + _order=('bottom', 'midbottom', 'middle', 'midtop', 'top'), + pin_factory=pin_factory), + pwm=pwm, initial_value=initial_value, + _order=('left', 'right'), + pin_factory=pin_factory + ), + eyes=LEDBoard( + left='BOARD32', right='BOARD31', + pwm=pwm, initial_value=initial_value, + _order=('left', 'right'), + pin_factory=pin_factory + ), + pwm=pwm, initial_value=initial_value, + _order=('eyes', 'sides'), + pin_factory=pin_factory + ) + + +class JamHat(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` for the `ModMyPi JamHat`_ board. + + There are 6 LEDs, two buttons and a tonal buzzer. The pins are fixed. + Usage:: + + from gpiozero import JamHat + + hat = JamHat() + + hat.button_1.wait_for_press() + hat.lights_1.on() + hat.buzzer.play('C4') + hat.button_2.wait_for_press() + hat.off() + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED on the board. If :data:`False` (the default), construct regular + :class:`LED` instances. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _ModMyPi JamHat: https://thepihut.com/products/jam-hat + + .. attribute:: lights_1, lights_2 + + Two :class:`LEDBoard` instances representing the top (lights_1) and + bottom (lights_2) rows of LEDs on the JamHat. + + .. attribute:: red, yellow, green + + :class:`LED` or :class:`PWMLED` instances representing the red, + yellow, and green LEDs along the top row. + + .. attribute:: button_1, button_2 + + The left (button_1) and right (button_2) :class:`Button` objects on the + JamHat. + + .. attribute:: buzzer + + The :class:`TonalBuzzer` at the bottom right of the JamHat. + """ + def __init__(self, pwm=False, pin_factory=None): + super(JamHat, self).__init__( + lights_1=LEDBoard( + red='BOARD29', yellow='BOARD32', green='BOARD36', + pwm=pwm, _order=('red', 'yellow', 'green'), + pin_factory=pin_factory + ), + lights_2=LEDBoard( + red='BOARD31', yellow='BOARD33', green='BOARD11', + pwm=pwm, _order=('red', 'yellow', 'green'), + pin_factory=pin_factory), + button_1=Button('BOARD35', pull_up=False, pin_factory=pin_factory), + button_2=Button('BOARD12', pull_up=False, pin_factory=pin_factory), + buzzer=TonalBuzzer('BOARD38', pin_factory=pin_factory), + _order=('lights_1', 'lights_2', 'button_1', 'button_2', 'buzzer'), + pin_factory=pin_factory + ) + + def on(self): + """ + Turns all the LEDs on and makes the buzzer play its mid tone. + """ + self.buzzer.value = 0 + super(JamHat, self).on() + + def off(self): + """ + Turns all the LEDs off and stops the buzzer. + """ + self.buzzer.value = None + super(JamHat, self).off() + + +class Pibrella(CompositeOutputDevice): + """ + Extends :class:`CompositeOutputDevice` for the Cyntech/Pimoroni `Pibrella`_ + board. + + The Pibrella board comprises 3 LEDs, a button, a tonal buzzer, four general + purpose input channels, and four general purpose output channels (with LEDs). + + This class exposes the LEDs, button and buzzer. + + Usage:: + + from gpiozero import Pibrella + + pb = Pibrella() + + pb.button.wait_for_press() + pb.lights.on() + pb.buzzer.play('A4') + pb.off() + + The four input and output channels are exposed so you can create GPIO Zero + devices using these pins without looking up their respective pin numbers:: + + from gpiozero import Pibrella, LED, Button + + pb = Pibrella() + btn = Button(pb.inputs.a, pull_up=False) + led = LED(pb.outputs.e) + + btn.when_pressed = led.on + + :param bool pwm: + If :data:`True`, construct :class:`PWMLED` instances to represent each + LED on the board, otherwise if :data:`False` (the default), construct + regular :class:`LED` instances. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _Pibrella: http://www.pibrella.com/ + + .. attribute:: lights + + :class:`TrafficLights` instance representing the three LEDs + + .. attribute:: red, amber, green + + :class:`LED` or :class:`PWMLED` instances representing the red, + amber, and green LEDs + + .. attribute:: button + + The red :class:`Button` object on the Pibrella + + .. attribute:: buzzer + + A :class:`TonalBuzzer` object representing the buzzer + + .. attribute:: inputs + + A :func:`~collections.namedtuple` of the input pin numbers + + .. attribute:: a, b, c, d + + .. attribute:: outputs + + A :func:`~collections.namedtuple` of the output pin numbers + + .. attribute:: e, f, g, h + """ + def __init__(self, pwm=False, pin_factory=None): + super(Pibrella, self).__init__( + lights=TrafficLights( + red='BOARD13', amber='BOARD11', green='BOARD7', + pwm=pwm, pin_factory=pin_factory + ), + button=Button('BOARD23', pull_up=False, pin_factory=pin_factory), + buzzer=TonalBuzzer('BOARD12', pin_factory=pin_factory), + _order=('lights', 'button', 'buzzer'), + pin_factory=pin_factory + ) + InputPins = namedtuple('InputPins', ['a', 'b', 'c', 'd']) + OutputPins = namedtuple('OutputPins', ['e', 'f', 'g', 'h']) + self.inputs = InputPins( + a='BOARD21', b='BOARD26', c='BOARD24', d='BOARD19' + ) + self.outputs = OutputPins( + e='BOARD15', f='BOARD16', g='BOARD18', h='BOARD22' + ) + + def on(self): + """ + Turns all the LEDs on and makes the buzzer play its mid tone. + """ + self.buzzer.value = 0 + super(Pibrella, self).on() + + def off(self): + """ + Turns all the LEDs off and stops the buzzer. + """ + self.buzzer.value = None + super(Pibrella, self).off() diff --git a/.venv/lib/python3.7/site-packages/gpiozero/compat.py b/.venv/lib/python3.7/site-packages/gpiozero/compat.py new file mode 100644 index 0000000..4cf944e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/compat.py @@ -0,0 +1,168 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2019 Ben Nuttall +# Copyright (c) 2018 Rick Ansell +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import math +import cmath +import weakref +import operator +import functools + +# Handles pre 3.3 versions of Python without collections.abc +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping + +# Back-ported from python 3.5; see +# github.com/PythonCHB/close_pep/blob/master/is_close.py for original +# implementation +def isclose(a, b, rel_tol=1e-9, abs_tol=0.0): + if rel_tol < 0.0 or abs_tol < 0.0: + raise ValueError('error tolerances must be non-negative') + if a == b: # fast-path for exact equality + return True + if cmath.isinf(a) or cmath.isinf(b): + return False + diff = abs(b - a) + return ( + (diff <= abs(rel_tol * b)) or + (diff <= abs(rel_tol * a)) or + (diff <= abs_tol) + ) + + +# Backported from py3.4 +def mean(data): + if iter(data) is data: + data = list(data) + n = len(data) + if not n: + raise ValueError('cannot calculate mean of empty data') + return sum(data) / n + + +# Backported from py3.4 +def median(data): + data = sorted(data) + n = len(data) + if not n: + raise ValueError('cannot calculate median of empty data') + elif n % 2: + return data[n // 2] + else: + i = n // 2 + return (data[i - 1] + data[i]) / 2 + + +# Backported from py3.4 +def mean(data): + if iter(data) is data: + data = list(data) + n = len(data) + if n < 1: + raise ValueError('mean requires at least one data point') + return sum(data) / n + + +# Backported from py3.3 +def log2(x): + return math.log(x, 2) + + +# Copied from the MIT-licensed https://github.com/slezica/python-frozendict +class frozendict(Mapping): + def __init__(self, *args, **kwargs): + self.__dict = dict(*args, **kwargs) + self.__hash = None + + def __getitem__(self, key): + return self.__dict[key] + + def copy(self, **add_or_replace): + return frozendict(self, **add_or_replace) + + def __iter__(self): + return iter(self.__dict) + + def __len__(self): + return len(self.__dict) + + def __repr__(self): + return '' % repr(self.__dict) + + def __hash__(self): + if self.__hash is None: + hashes = map(hash, self.items()) + self.__hash = functools.reduce(operator.xor, hashes, 0) + return self.__hash + + +# Backported from py3.4 +class WeakMethod(weakref.ref): + """ + A custom `weakref.ref` subclass which simulates a weak reference to + a bound method, working around the lifetime problem of bound methods. + """ + + __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__" + + def __new__(cls, meth, callback=None): + try: + obj = meth.__self__ + func = meth.__func__ + except AttributeError: + raise TypeError("argument should be a bound method, not {0}" + .format(type(meth))) + def _cb(arg): + # The self-weakref trick is needed to avoid creating a reference + # cycle. + self = self_wr() + if self._alive: + self._alive = False + if callback is not None: + callback(self) + self = weakref.ref.__new__(cls, obj, _cb) + self._func_ref = weakref.ref(func, _cb) + self._meth_type = type(meth) + self._alive = True + self_wr = weakref.ref(self) + return self + + def __call__(self): + obj = super(WeakMethod, self).__call__() + func = self._func_ref() + if obj is None or func is None: + return None + return self._meth_type(func, obj) + + def __eq__(self, other): + if isinstance(other, WeakMethod): + if not self._alive or not other._alive: + return self is other + return weakref.ref.__eq__(self, other) and self._func_ref == other._func_ref + return False + + def __ne__(self, other): + if isinstance(other, WeakMethod): + if not self._alive or not other._alive: + return self is not other + return weakref.ref.__ne__(self, other) or self._func_ref != other._func_ref + return True + + __hash__ = weakref.ref.__hash__ diff --git a/.venv/lib/python3.7/site-packages/gpiozero/devices.py b/.venv/lib/python3.7/site-packages/gpiozero/devices.py new file mode 100644 index 0000000..07f45d9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/devices.py @@ -0,0 +1,628 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2015-2019 Ben Nuttall +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +nstr = str +str = type('') + +import os +import atexit +import weakref +import warnings +from collections import namedtuple, OrderedDict +from itertools import chain +from types import FunctionType + +from .threads import _threads_shutdown +from .mixins import ( + ValuesMixin, + SharedMixin, + ) +from .exc import ( + BadPinFactory, + DeviceClosed, + CompositeDeviceBadName, + CompositeDeviceBadOrder, + CompositeDeviceBadDevice, + GPIOPinMissing, + GPIOPinInUse, + GPIODeviceClosed, + NativePinFactoryFallback, + PinFactoryFallback, + ) +from .compat import frozendict + +native_fallback_message = ( +'Falling back to the experimental pin factory NativeFactory because no other ' +'pin factory could be loaded. For best results, install RPi.GPIO or pigpio. ' +'See https://gpiozero.readthedocs.io/en/stable/api_pins.html for more information.' +) + + +class GPIOMeta(type): + # NOTE Yes, this is a metaclass. Don't be scared - it's a simple one. + + def __new__(mcls, name, bases, cls_dict): + # Construct the class as normal + cls = super(GPIOMeta, mcls).__new__(mcls, name, bases, cls_dict) + # If there's a method in the class which has no docstring, search + # the base classes recursively for a docstring to copy + for attr_name, attr in cls_dict.items(): + if isinstance(attr, FunctionType) and not attr.__doc__: + for base_cls in cls.__mro__: + if hasattr(base_cls, attr_name): + base_fn = getattr(base_cls, attr_name) + if base_fn.__doc__: + attr.__doc__ = base_fn.__doc__ + break + return cls + + def __call__(cls, *args, **kwargs): + # Make sure cls has GPIOBase somewhere in its ancestry (otherwise + # setting __attrs__ below will be rather pointless) + assert issubclass(cls, GPIOBase) + if issubclass(cls, SharedMixin): + # If SharedMixin appears in the class' ancestry, convert the + # constructor arguments to a key and check whether an instance + # already exists. Only construct the instance if the key's new. + key = cls._shared_key(*args, **kwargs) + try: + self = cls._instances[key]() + self._refs += 1 + except (KeyError, AttributeError) as e: + self = super(GPIOMeta, cls).__call__(*args, **kwargs) + self._refs = 1 + # Replace the close method with one that merely decrements + # the refs counter and calls the original close method when + # it reaches zero + old_close = self.close + def close(): + self._refs = max(0, self._refs - 1) + if not self._refs: + try: + old_close() + finally: + try: + del cls._instances[key] + except KeyError: + # If the _refs go negative (too many closes) + # just ignore the resulting KeyError here - + # it's already gone + pass + self.close = close + cls._instances[key] = weakref.ref(self) + else: + # Construct the instance as normal + self = super(GPIOMeta, cls).__call__(*args, **kwargs) + # At this point __new__ and __init__ have all been run. We now fix the + # set of attributes on the class by dir'ing the instance and creating a + # frozenset of the result called __attrs__ (which is queried by + # GPIOBase.__setattr__). An exception is made for SharedMixin devices + # which can be constructed multiple times, returning the same instance + if not issubclass(cls, SharedMixin) or self._refs == 1: + self.__attrs__ = frozenset(dir(self)) + return self + + +# Cross-version compatible method of using a metaclass +class GPIOBase(GPIOMeta(nstr('GPIOBase'), (), {})): + def __setattr__(self, name, value): + # This overridden __setattr__ simply ensures that additional attributes + # cannot be set on the class after construction (it manages this in + # conjunction with the meta-class above). Traditionally, this is + # managed with __slots__; however, this doesn't work with Python's + # multiple inheritance system which we need to use in order to avoid + # repeating the "source" and "values" property code in myriad places + if hasattr(self, '__attrs__') and name not in self.__attrs__: + raise AttributeError( + "'%s' object has no attribute '%s'" % ( + self.__class__.__name__, name)) + return super(GPIOBase, self).__setattr__(name, value) + + def __del__(self): + # NOTE: Yes, we implicitly call close() on __del__(), and yes for you + # dear hacker-on-this-library, this means pain! + # + # It's entirely for the convenience of command line experimenters and + # newbies who want to re-gain those pins when stuff falls out of scope + # without managing their object lifetimes "properly" with "with" (but, + # hey, this is an educational library at heart so that's the way we + # roll). + # + # What does this mean for you? It means that in close() you cannot + # assume *anything*. If someone calls a constructor with a fundamental + # mistake like the wrong number of params, then your close() method is + # going to be called before __init__ ever ran so all those attributes + # you *think* exist, erm, don't. Basically if you refer to anything in + # "self" within your close method, be preprared to catch AttributeError + # on its access to avoid spurious warnings for the end user. + # + # "But we're exiting anyway; surely exceptions in __del__ get + # squashed?" Yes, but they still cause verbose warnings and remember + # that this is an educational library; keep it friendly! + self.close() + + def close(self): + """ + Shut down the device and release all associated resources (such as GPIO + pins). + + This method is idempotent (can be called on an already closed device + without any side-effects). It is primarily intended for interactive use + at the command line. It disables the device and releases its pin(s) for + use by another device. + + You can attempt to do this simply by deleting an object, but unless + you've cleaned up all references to the object this may not work (even + if you've cleaned up all references, there's still no guarantee the + garbage collector will actually delete the object at that point). By + contrast, the close method provides a means of ensuring that the object + is shut down. + + For example, if you have a breadboard with a buzzer connected to pin + 16, but then wish to attach an LED instead: + + >>> from gpiozero import * + >>> bz = Buzzer(16) + >>> bz.on() + >>> bz.off() + >>> bz.close() + >>> led = LED(16) + >>> led.blink() + + :class:`Device` descendents can also be used as context managers using + the :keyword:`with` statement. For example: + + >>> from gpiozero import * + >>> with Buzzer(16) as bz: + ... bz.on() + ... + >>> with LED(16) as led: + ... led.on() + ... + """ + # This is a placeholder which is simply here to ensure close() can be + # safely called from subclasses without worrying whether super-classes + # have it (which in turn is useful in conjunction with the mixin + # classes). + # + # P.S. See note in __del__ above. + pass + + @property + def closed(self): + """ + Returns :data:`True` if the device is closed (see the :meth:`close` + method). Once a device is closed you can no longer use any other + methods or properties to control or query the device. + """ + raise NotImplementedError + + def _check_open(self): + if self.closed: + raise DeviceClosed( + '%s is closed or uninitialized' % self.__class__.__name__) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_tb): + self.close() + + +class Device(ValuesMixin, GPIOBase): + """ + Represents a single device of any type; GPIO-based, SPI-based, I2C-based, + etc. This is the base class of the device hierarchy. It defines the basic + services applicable to all devices (specifically the :attr:`is_active` + property, the :attr:`value` property, and the :meth:`close` method). + + .. attribute:: pin_factory + + This attribute exists at both a class level (representing the default + pin factory used to construct devices when no *pin_factory* parameter + is specified), and at an instance level (representing the pin factory + that the device was constructed with). + + The pin factory provides various facilities to the device including + allocating pins, providing low level interfaces (e.g. SPI), and clock + facilities (querying and calculating elapsed times). + """ + pin_factory = None # instance of a Factory sub-class + + def __init__(self, **kwargs): + # Force pin_factory to be keyword-only, even in Python 2 + pin_factory = kwargs.pop('pin_factory', None) + if pin_factory is None: + if Device.pin_factory is None: + Device.pin_factory = Device._default_pin_factory() + self.pin_factory = Device.pin_factory + else: + self.pin_factory = pin_factory + if kwargs: + raise TypeError("Device.__init__() got unexpected keyword " + "argument '%s'" % kwargs.popitem()[0]) + super(Device, self).__init__() + + @staticmethod + def _default_pin_factory(): + # We prefer RPi.GPIO here as it supports PWM, and all Pi revisions. If + # no third-party libraries are available, however, we fall back to a + # pure Python implementation which supports platforms like PyPy + # + # NOTE: If the built-in pin factories are expanded, the dict must be + # updated along with the entry-points in setup.py. + default_factories = OrderedDict(( + ('rpigpio', 'gpiozero.pins.rpigpio:RPiGPIOFactory'), + ('lgpio', 'gpiozero.pins.lgpio:LGPIOFactory'), + ('rpio', 'gpiozero.pins.rpio:RPIOFactory'), + ('pigpio', 'gpiozero.pins.pigpio:PiGPIOFactory'), + ('native', 'gpiozero.pins.native:NativeFactory'), + )) + name = os.environ.get('GPIOZERO_PIN_FACTORY') + if name is None: + # If no factory is explicitly specified, try various names in + # "preferred" order. For speed, we select from the dictionary above + # rather than importing pkg_resources and using load_entry_point + for name, entry_point in default_factories.items(): + try: + mod_name, cls_name = entry_point.split(':', 1) + module = __import__(mod_name, fromlist=(cls_name,)) + pin_factory = getattr(module, cls_name)() + if name == 'native': + warnings.warn(NativePinFactoryFallback(native_fallback_message)) + return pin_factory + except Exception as e: + warnings.warn( + PinFactoryFallback( + 'Falling back from %s: %s' % (name, str(e)))) + raise BadPinFactory('Unable to load any default pin factory!') + elif name in default_factories: + # As above, this is a fast-path optimization to avoid loading + # pkg_resources (which it turns out was 80% of gpiozero's import + # time!) + mod_name, cls_name = default_factories[name].split(':', 1) + module = __import__(mod_name, fromlist=(cls_name,)) + return getattr(module, cls_name)() + else: + # Slow path: load pkg_resources and try and find the specified + # entry-point. Try with the name verbatim first. If that fails, + # attempt with the lower-cased name (this ensures compatibility + # names work but we're still case insensitive for all factories) + import pkg_resources + group = 'gpiozero_pin_factories' + for factory in pkg_resources.iter_entry_points(group, name): + return factory.load()() + for factory in pkg_resources.iter_entry_points(group, name.lower()): + return factory.load()() + raise BadPinFactory('Unable to find pin factory "%s"' % name) + + def __repr__(self): + try: + self._check_open() + return "" % (self.__class__.__name__) + except DeviceClosed: + return "" % (self.__class__.__name__) + + def _conflicts_with(self, other): + """ + Called by :meth:`Factory.reserve_pins` to test whether the *other* + :class:`Device` using a common pin conflicts with this device's intent + to use it. The default is :data:`True` indicating that all devices + conflict with common pins. Sub-classes may override this to permit + more nuanced replies. + """ + return True + + @property + def value(self): + """ + Returns a value representing the device's state. Frequently, this is a + boolean value, or a number between 0 and 1 but some devices use larger + ranges (e.g. -1 to +1) and composite devices usually use tuples to + return the states of all their subordinate components. + """ + raise NotImplementedError + + @property + def is_active(self): + """ + Returns :data:`True` if the device is currently active and + :data:`False` otherwise. This property is usually derived from + :attr:`value`. Unlike :attr:`value`, this is *always* a boolean. + """ + return bool(self.value) + + +class CompositeDevice(Device): + """ + Extends :class:`Device`. Represents a device composed of multiple devices + like simple HATs, H-bridge motor controllers, robots composed of multiple + motors, etc. + + The constructor accepts subordinate devices as positional or keyword + arguments. Positional arguments form unnamed devices accessed by treating + the composite device as a container, while keyword arguments are added to + the device as named (read-only) attributes. + + For example: + + .. code-block:: pycon + + >>> from gpiozero import * + >>> d = CompositeDevice(LED(2), LED(3), LED(4), btn=Button(17)) + >>> d[0] + + >>> d[1] + + >>> d[2] + + >>> d.btn + + >>> d.value + CompositeDeviceValue(device_0=False, device_1=False, device_2=False, btn=False) + + :param Device \\*args: + The un-named devices that belong to the composite device. The + :attr:`value` attributes of these devices will be represented within + the composite device's tuple :attr:`value` in the order specified here. + + :type _order: list or None + :param _order: + If specified, this is the order of named items specified by keyword + arguments (to ensure that the :attr:`value` tuple is constructed with a + specific order). All keyword arguments *must* be included in the + collection. If omitted, an alphabetically sorted order will be selected + for keyword arguments. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + :param Device \\*\\*kwargs: + The named devices that belong to the composite device. These devices + will be accessible as named attributes on the resulting device, and + their :attr:`value` attributes will be accessible as named elements of + the composite device's tuple :attr:`value`. + """ + def __init__(self, *args, **kwargs): + self._all = () + self._named = frozendict({}) + self._namedtuple = None + self._order = kwargs.pop('_order', None) + pin_factory = kwargs.pop('pin_factory', None) + try: + if self._order is None: + self._order = sorted(kwargs.keys()) + else: + for missing_name in set(kwargs.keys()) - set(self._order): + raise CompositeDeviceBadOrder( + '%s missing from _order' % missing_name) + self._order = tuple(self._order) + for name in set(self._order) & set(dir(self)): + raise CompositeDeviceBadName( + '%s is a reserved name' % name) + for dev in chain(args, kwargs.values()): + if not isinstance(dev, Device): + raise CompositeDeviceBadDevice( + "%s doesn't inherit from Device" % dev) + self._named = frozendict(kwargs) + self._namedtuple = namedtuple( + '%sValue' % self.__class__.__name__, chain( + ('device_%d' % i for i in range(len(args))), self._order)) + except: + for dev in chain(args, kwargs.values()): + if isinstance(dev, Device): + dev.close() + raise + self._all = args + tuple(kwargs[v] for v in self._order) + super(CompositeDevice, self).__init__(pin_factory=pin_factory) + + def __getattr__(self, name): + # if _named doesn't exist yet, pretend it's an empty dict + if name == '_named': + return frozendict({}) + try: + return self._named[name] + except KeyError: + raise AttributeError("no such attribute %s" % name) + + def __setattr__(self, name, value): + # make named components read-only properties + if name in self._named: + raise AttributeError("can't set attribute %s" % name) + return super(CompositeDevice, self).__setattr__(name, value) + + def __repr__(self): + try: + self._check_open() + named = len(self._named) + unnamed = len(self) - len(self._named) + if named > 0 and unnamed > 0: + return "" % ( + self.__class__.__name__, + len(self), ', '.join(self._order), + len(self) - len(self._named) + ) + elif named > 0: + return "" % ( + self.__class__.__name__, + len(self), + ', '.join(self._order) + ) + else: + return "" % ( + self.__class__.__name__, + len(self) + ) + except DeviceClosed: + return super(CompositeDevice, self).__repr__() + + def __len__(self): + return len(self._all) + + def __getitem__(self, index): + return self._all[index] + + def __iter__(self): + return iter(self._all) + + @property + def all(self): + # XXX Deprecate this in favour of using the instance as a container + return self._all + + def close(self): + if getattr(self, '_all', None): + for device in self._all: + device.close() + self._all = () + + @property + def closed(self): + return all(device.closed for device in self) + + @property + def namedtuple(self): + """ + The :func:`~collections.namedtuple` type constructed to represent the + value of the composite device. The :attr:`value` attribute returns + values of this type. + """ + return self._namedtuple + + @property + def value(self): + """ + A :func:`~collections.namedtuple` containing a value for each + subordinate device. Devices with names will be represented as named + elements. Unnamed devices will have a unique name generated for them, + and they will appear in the position they appeared in the constructor. + """ + return self.namedtuple(*(device.value for device in self)) + + @property + def is_active(self): + """ + Composite devices are considered "active" if any of their constituent + devices have a "truthy" value. + """ + return any(self.value) + + +class GPIODevice(Device): + """ + Extends :class:`Device`. Represents a generic GPIO device and provides + the services common to all single-pin GPIO devices (like ensuring two + GPIO devices do no share a :attr:`pin`). + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. If the pin is already in use by another device, + :exc:`GPIOPinInUse` will be raised. + """ + def __init__(self, pin=None, **kwargs): + super(GPIODevice, self).__init__(**kwargs) + # self._pin must be set before any possible exceptions can be raised + # because it's accessed in __del__. However, it mustn't be given the + # value of pin until we've verified that it isn't already allocated + self._pin = None + if pin is None: + raise GPIOPinMissing('No pin given') + # Check you can reserve *before* constructing the pin + self.pin_factory.reserve_pins(self, pin) + pin = self.pin_factory.pin(pin) + self._pin = pin + self._active_state = True + self._inactive_state = False + + def _state_to_value(self, state): + return int(state == self._active_state) + + def _read(self): + try: + return self._state_to_value(self.pin.state) + except (AttributeError, TypeError): + self._check_open() + raise + + def close(self): + super(GPIODevice, self).close() + if getattr(self, '_pin', None) is not None: + self.pin_factory.release_pins(self, self._pin.number) + self._pin.close() + self._pin = None + + @property + def closed(self): + try: + return self._pin is None + except AttributeError: + return True + + def _check_open(self): + try: + super(GPIODevice, self)._check_open() + except DeviceClosed as e: + # For backwards compatibility; GPIODeviceClosed is deprecated + raise GPIODeviceClosed(str(e)) + + @property + def pin(self): + """ + The :class:`Pin` that the device is connected to. This will be + :data:`None` if the device has been closed (see the + :meth:`~Device.close` method). When dealing with GPIO pins, query + ``pin.number`` to discover the GPIO pin (in BCM numbering) that the + device is connected to. + """ + return self._pin + + @property + def value(self): + return self._read() + + def __repr__(self): + try: + return "" % ( + self.__class__.__name__, self.pin, self.is_active) + except DeviceClosed: + return "" % self.__class__.__name__ + + +def _devices_shutdown(): + if Device.pin_factory is not None: + with Device.pin_factory._res_lock: + reserved_devices = { + dev + for ref_list in Device.pin_factory._reservations.values() + for ref in ref_list + for dev in (ref(),) + if dev is not None + } + for dev in reserved_devices: + dev.close() + Device.pin_factory.close() + Device.pin_factory = None + + +def _shutdown(): + _threads_shutdown() + _devices_shutdown() + +atexit.register(_shutdown) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/exc.py b/.venv/lib/python3.7/site-packages/gpiozero/exc.py new file mode 100644 index 0000000..2d038f1 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/exc.py @@ -0,0 +1,202 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2019-2020 Ben Nuttall +# Copyright (c) 2019 Kosovan Sofiia +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) +str = type('') + + +class GPIOZeroError(Exception): + "Base class for all exceptions in GPIO Zero" + +class DeviceClosed(GPIOZeroError): + "Error raised when an operation is attempted on a closed device" + +class BadEventHandler(GPIOZeroError, ValueError): + "Error raised when an event handler with an incompatible prototype is specified" + +class BadWaitTime(GPIOZeroError, ValueError): + "Error raised when an invalid wait time is specified" + +class BadQueueLen(GPIOZeroError, ValueError): + "Error raised when non-positive queue length is specified" + +class BadPinFactory(GPIOZeroError, ImportError): + "Error raised when an unknown pin factory name is specified" + +class ZombieThread(GPIOZeroError, RuntimeError): + "Error raised when a thread fails to die within a given timeout" + +class CompositeDeviceError(GPIOZeroError): + "Base class for errors specific to the CompositeDevice hierarchy" + +class CompositeDeviceBadName(CompositeDeviceError, ValueError): + "Error raised when a composite device is constructed with a reserved name" + +class CompositeDeviceBadOrder(CompositeDeviceError, ValueError): + "Error raised when a composite device is constructed with an incomplete order" + +class CompositeDeviceBadDevice(CompositeDeviceError, ValueError): + "Error raised when a composite device is constructed with an object that doesn't inherit from :class:`Device`" + +class EnergenieSocketMissing(CompositeDeviceError, ValueError): + "Error raised when socket number is not specified" + +class EnergenieBadSocket(CompositeDeviceError, ValueError): + "Error raised when an invalid socket number is passed to :class:`Energenie`" + +class SPIError(GPIOZeroError): + "Base class for errors related to the SPI implementation" + +class SPIBadArgs(SPIError, ValueError): + "Error raised when invalid arguments are given while constructing :class:`SPIDevice`" + +class SPIBadChannel(SPIError, ValueError): + "Error raised when an invalid channel is given to an :class:`AnalogInputDevice`" + +class SPIFixedClockMode(SPIError, AttributeError): + "Error raised when the SPI clock mode cannot be changed" + +class SPIInvalidClockMode(SPIError, ValueError): + "Error raised when an invalid clock mode is given to an SPI implementation" + +class SPIFixedBitOrder(SPIError, AttributeError): + "Error raised when the SPI bit-endianness cannot be changed" + +class SPIFixedSelect(SPIError, AttributeError): + "Error raised when the SPI select polarity cannot be changed" + +class SPIFixedWordSize(SPIError, AttributeError): + "Error raised when the number of bits per word cannot be changed" + +class SPIFixedRate(SPIError, AttributeError): + "Error raised when the baud-rate of the interface cannot be changed" + +class SPIInvalidWordSize(SPIError, ValueError): + "Error raised when an invalid (out of range) number of bits per word is specified" + +class GPIODeviceError(GPIOZeroError): + "Base class for errors specific to the GPIODevice hierarchy" + +class GPIODeviceClosed(GPIODeviceError, DeviceClosed): + "Deprecated descendent of :exc:`DeviceClosed`" + +class GPIOPinInUse(GPIODeviceError): + "Error raised when attempting to use a pin already in use by another device" + +class GPIOPinMissing(GPIODeviceError, ValueError): + "Error raised when a pin specification is not given" + +class InputDeviceError(GPIODeviceError): + "Base class for errors specific to the InputDevice hierarchy" + +class OutputDeviceError(GPIODeviceError): + "Base class for errors specified to the OutputDevice hierarchy" + +class OutputDeviceBadValue(OutputDeviceError, ValueError): + "Error raised when ``value`` is set to an invalid value" + +class PinError(GPIOZeroError): + "Base class for errors related to pin implementations" + +class PinInvalidFunction(PinError, ValueError): + "Error raised when attempting to change the function of a pin to an invalid value" + +class PinInvalidState(PinError, ValueError): + "Error raised when attempting to assign an invalid state to a pin" + +class PinInvalidPull(PinError, ValueError): + "Error raised when attempting to assign an invalid pull-up to a pin" + +class PinInvalidEdges(PinError, ValueError): + "Error raised when attempting to assign an invalid edge detection to a pin" + +class PinInvalidBounce(PinError, ValueError): + "Error raised when attempting to assign an invalid bounce time to a pin" + +class PinSetInput(PinError, AttributeError): + "Error raised when attempting to set a read-only pin" + +class PinFixedPull(PinError, AttributeError): + "Error raised when attempting to set the pull of a pin with fixed pull-up" + +class PinEdgeDetectUnsupported(PinError, AttributeError): + "Error raised when attempting to use edge detection on unsupported pins" + +class PinUnsupported(PinError, NotImplementedError): + "Error raised when attempting to obtain a pin interface on unsupported pins" + +class PinSPIUnsupported(PinError, NotImplementedError): + "Error raised when attempting to obtain an SPI interface on unsupported pins" + +class PinPWMError(PinError): + "Base class for errors related to PWM implementations" + +class PinPWMUnsupported(PinPWMError, AttributeError): + "Error raised when attempting to activate PWM on unsupported pins" + +class PinPWMFixedValue(PinPWMError, AttributeError): + "Error raised when attempting to initialize PWM on an input pin" + +class PinUnknownPi(PinError, RuntimeError): + "Error raised when gpiozero doesn't recognize a revision of the Pi" + +class PinMultiplePins(PinError, RuntimeError): + "Error raised when multiple pins support the requested function" + +class PinNoPins(PinError, RuntimeError): + "Error raised when no pins support the requested function" + +class PinInvalidPin(PinError, ValueError): + "Error raised when an invalid pin specification is provided" + +class GPIOZeroWarning(Warning): + "Base class for all warnings in GPIO Zero" + +class DistanceSensorNoEcho(GPIOZeroWarning): + "Warning raised when the distance sensor sees no echo at all" + +class SPIWarning(GPIOZeroWarning): + "Base class for warnings related to the SPI implementation" + +class SPISoftwareFallback(SPIWarning): + "Warning raised when falling back to the SPI software implementation" + +class PWMWarning(GPIOZeroWarning): + "Base class for PWM warnings" + +class PWMSoftwareFallback(PWMWarning): + "Warning raised when falling back to the PWM software implementation" + +class PinWarning(GPIOZeroWarning): + "Base class for warnings related to pin implementations" + +class PinFactoryFallback(PinWarning): + "Warning raised when a default pin factory fails to load and a fallback is tried" + +class NativePinFactoryFallback(PinWarning): + "Warning raised when all other default pin factories fail to load and NativeFactory is used" + +class PinNonPhysical(PinWarning): + "Warning raised when a non-physical pin is specified in a constructor" + +class ThresholdOutOfRange(GPIOZeroWarning): + "Warning raised when a threshold is out of range specified by min and max values" + +class CallbackSetToNone(GPIOZeroWarning): + "Warning raised when a callback is set to None when its previous value was None" + +class AmbiguousTone(GPIOZeroWarning): + "Warning raised when a Tone is constructed with an ambiguous number" diff --git a/.venv/lib/python3.7/site-packages/gpiozero/fonts.py b/.venv/lib/python3.7/site-packages/gpiozero/fonts.py new file mode 100644 index 0000000..f1ae8de --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/fonts.py @@ -0,0 +1,236 @@ +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, +) +str = type('') + +import io +from collections import Counter +try: + from itertools import izip as zip, izip_longest as zip_longest +except ImportError: + from itertools import zip_longest + + +def load_segment_font(filename_or_obj, width, height, pins): + """ + A generic function for parsing segment font definition files. + + If you're working with "standard" `7-segment`_ or `14-segment`_ displays + you *don't* want this function; see :func:`load_font_7seg` or + :func:`load_font_14seg` instead. However, if you are working with another + style of segmented display and wish to construct a parser for a custom + format, this is the function you want. + + The *filename_or_obj* parameter is simply the file-like object or filename + to load. This is typically passed in from the calling function. + + The *width* and *height* parameters give the width and height in characters + of each character definition. For example, these are 3 and 3 for 7-segment + displays. Finally, *pins* is a list of tuples that defines the position of + each pin definition in the character array, and the character that marks + that position "active". + + For example, for 7-segment displays this function is called as follows:: + + load_segment_font(filename_or_obj, width=3, height=3, pins=[ + (1, '_'), (5, '|'), (8, '|'), (7, '_'), + (6, '|'), (3, '|'), (4, '_')]) + + This dictates that each character will be defined by a 3x3 character grid + which will be converted into a nine-character string like so: + + .. code-block:: text + + 012 + 345 ==> '012345678' + 678 + + Position 0 is always assumed to be the character being defined. The *pins* + list then specifies: the first pin is the character at position 1 which + will be "on" when that character is "_". The second pin is the character + at position 5 which will be "on" when that character is "|", and so on. + + .. _7-segment: https://en.wikipedia.org/wiki/Seven-segment_display + .. _14-segment: https://en.wikipedia.org/wiki/Fourteen-segment_display + """ + assert 0 < len(pins) <= (width * height) - 1 + if isinstance(filename_or_obj, bytes): + filename_or_obj = filename_or_obj.decode('utf-8') + opened = isinstance(filename_or_obj, str) + if opened: + filename_or_obj = io.open(filename_or_obj, 'r') + try: + lines = filename_or_obj.read() + if isinstance(lines, bytes): + lines = lines.decode('utf-8') + lines = lines.splitlines() + finally: + if opened: + filename_or_obj.close() + + # Strip out comments and blank lines, but remember the original line + # numbers of each row for error reporting purposes + rows = [ + (index, line) for index, line in enumerate(lines, start=1) + # Strip comments and blank (or whitespace) lines + if line.strip() and not line.startswith('#') + ] + line_numbers = { + row_index: line_index + for row_index, (line_index, row) in enumerate(rows) + } + rows = [row for index, row in rows] + if len(rows) % height: + raise ValueError('number of definition lines is not divisible by ' + '{height}'.format(height=height)) + + # Strip out blank columns then transpose back to rows, and make sure + # everything is the right "shape" + for n in range(0, len(rows), height): + cols = [ + col for col in zip_longest(*rows[n:n + height], fillvalue=' ') + # Strip blank (or whitespace) columns + if ''.join(col).strip() + ] + rows[n:n + height] = list(zip(*cols)) + for row_index, row in enumerate(rows): + if len(row) % width: + raise ValueError( + 'length of definitions starting on line {line} is not ' + 'divisible by {width}'.format( + line=line_numbers[row_index], width=width)) + + # Split rows up into character definitions. After this, chars will be a + # list of strings each with width x height characters. The first character + # in each string will be the character being defined + chars = [ + ''.join( + char + for row in rows[y::height] + for char in row + )[x::width] + for y in range(height) + for x in range(width) + ] + chars = [''.join(char) for char in zip(*chars)] + + # Strip out blank entries (a consequence of zip_longest above) and check + # there're no repeat definitions + chars = [char for char in chars if char.strip()] + counts = Counter(char[0] for char in chars) + for char, count in counts.most_common(): + if count > 1: + raise ValueError( + 'multiple definitions for {char!r}'.format(char=char)) + + return { + char[0]: tuple(int(char[pos] == on) for pos, on in pins) + for char in chars + } + + +def load_font_7seg(filename_or_obj): + """ + Given a filename or a file-like object, parse it as an font definition for + a `7-segment display`_, returning a :class:`dict` suitable for use with + :class:`~gpiozero.LEDCharDisplay`. + + The file-format is a simple text-based format in which blank and #-prefixed + lines are ignored. All other lines are assumed to be groups of character + definitions which are cells of 3x3 characters laid out as follows: + + .. code-block:: text + + Ca + fgb + edc + + Where C is the character being defined, and a-g define the states of the + LEDs for that position. a, d, and g are on if they are "_". b, c, e, and + f are on if they are "|". Any other character in these positions is + considered off. For example, you might define the following characters: + + .. code-block:: text + + . 0_ 1. 2_ 3_ 4. 5_ 6_ 7_ 8_ 9_ + ... |.| ..| ._| ._| |_| |_. |_. ..| |_| |_| + ... |_| ..| |_. ._| ..| ._| |_| ..| |_| ._| + + In the example above, empty locations are marked with "." but could mostly + be left as spaces. However, the first item defines the space (" ") + character and needs *some* non-space characters in its definition as the + parser also strips empty columns (as typically occur between character + definitions). This is also why the definition for "1" must include + something to fill the middle column. + + .. _7-segment display: https://en.wikipedia.org/wiki/Seven-segment_display + """ + return load_segment_font(filename_or_obj, width=3, height=3, pins=[ + (1, '_'), (5, '|'), (8, '|'), (7, '_'), + (6, '|'), (3, '|'), (4, '_')]) + + +def load_font_14seg(filename_or_obj): + """ + Given a filename or a file-like object, parse it as a font definition for a + `14-segment display`_, returning a :class:`dict` suitable for use with + :class:`~gpiozero.LEDCharDisplay`. + + The file-format is a simple text-based format in which blank and #-prefixed + lines are ignored. All other lines are assumed to be groups of character + definitions which are cells of 5x5 characters laid out as follows: + + .. code-block:: text + + X.a.. + fijkb + .g.h. + elmnc + ..d.. + + Where X is the character being defined, and a-n define the states of the + LEDs for that position. a, d, g, and h are on if they are "-". b, c, e, f, + j, and m are on if they are "|". i and n are on if they are "\\". Finally, + k and l are on if they are "/". Any other character in these positions is + considered off. For example, you might define the following characters: + + .. code-block:: text + + .... 0--- 1.. 2--- 3--- 4 5--- 6--- 7---. 8--- 9--- + ..... | /| /| | | | | | | / | | | | + ..... | / | | --- -- ---| --- |--- | --- ---| + ..... |/ | | | | | | | | | | | | + ..... --- --- --- --- --- --- + + In the example above, several locations have extraneous characters. For + example, the "/" in the center of the "0" definition, or the "-" in the + middle of the "8". These locations are ignored, but filled in nonetheless + to make the shape more obvious. + + These extraneous locations could equally well be left as spaces. However, + the first item defines the space (" ") character and needs *some* non-space + characters in its definition as the parser also strips empty columns (as + typically occur between character definitions) and verifies that + definitions are 5 columns wide and 5 rows high. + + This also explains why place-holder characters (".") have been inserted at + the top of the definition of the "1" character. Otherwise the parser will + strip these empty columns and decide the definition is invalid (as the + result is only 3 columns wide). + + .. _14-segment display: https://en.wikipedia.org/wiki/Fourteen-segment_display + """ + return load_segment_font(filename_or_obj, width=5, height=5, pins=[ + (2, '-'), (9, '|'), (19, '|'), (22, '-'), + (15, '|'), (5, '|'), (11, '-'), (13, '-'), + (6, '\\'), (7, '|'), (8, '/'), (16, '/'), + (17, '|'), (18, '\\')]) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/fonts/14seg.txt b/.venv/lib/python3.7/site-packages/gpiozero/fonts/14seg.txt new file mode 100644 index 0000000..4098b0e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/fonts/14seg.txt @@ -0,0 +1,54 @@ +# This file defines the default alphabet for 14-segment displays. The format is +# fairly simple: the file is loaded as a whole and all blank and #-prefixed +# lines are stripped out. Then all blank columns are stripped out. Finally the +# remaining rows and columns are divided into 5x5 cells with the following +# format: +# +# X.a.. +# fijkb +# .g.h. +# elmnc +# ..d.. +# +# Where X is the character being defined, and a..n are the segments that are +# active. a, d, g, and h are considered active if they are "-". b, c, e, f, j, +# and m are considered active if they are "|". i and n are active when they +# are "\". Finally, k and l are active when they are "/". All other characters +# marked "." are ignored but may be set to anything for the purposes of making +# the character's shape more obvious. +# +# Note that blank columns are stripped, so when defining the space (" ") +# character you will need to use place-holder characters for unused positions. +# Furthermore, the parser checks that definitions are multiples of 5 wide and +# 5 high. If a character's definition has entirely empty rows or columns you +# may need more place-holder characters to satisfy this limitation. + + .... 0--- 1.. 2--- 3--- 4 5--- 6--- 7---. 8--- 9--- +..... | /| /| | | | | | | / | | | | +..... | / | | --- -- ---| --- |--- | --- ---| +..... |/ | | | | | | | | | | | | +..... --- --- --- --- --- --- + +A--- B--- C---. D--- E---. F---. G--- H I---. J K . L M +| | | | | | | | | | | | | | | / | |\ /| +|---| -| | | | |--- |--- | -- |---| | | |-- | | ' | +| | | | | | | | | | | | | | | | | \ | | | +' ' --- --- --- --- ' --- ' ' --- --- ' ' ---. ' ' + +N O--- P--- Q--- R--- S--- T---. U V . W X . Y . Z---. +|\ | | | | | | | | | | | | | | / | | \ / \ / / +| \ | | | |--- | | |-- --- | | | | / | . | X | / +| \| | | | | \| | \ | | | | |/ |/ \| / \ | / +' ' --- --- ' ' --- --- ' ' ' ' ' --- + +&---. $--- (---. )--- [---. ]--- %.... *.... +.... -.... /.... =.... \.... + \ / | | | | | | | / .\|/ . | . . / . .\ + -- --- | | | | . .--- .--- .--- . / .--- . \ +| \ | | | | | | ./ | ./|\ . | . ./ . . \ + --- --- --- --- --- --- . . . . . .--- . + +_.... '.... +. . | +. . +. . +.--- . diff --git a/.venv/lib/python3.7/site-packages/gpiozero/fonts/7seg.txt b/.venv/lib/python3.7/site-packages/gpiozero/fonts/7seg.txt new file mode 100644 index 0000000..9b7b188 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/fonts/7seg.txt @@ -0,0 +1,23 @@ +# This file defines the default alphabet for 7-segment displays. The format is +# fairly simple: the file is loaded as a whole and all blank and #-prefixed +# lines are stripped out. Then all blank columns are stripped out. Finally the +# remaining rows and columns are divided into 3x3 cells with the following +# format: +# +# Xa. +# fgb +# edc +# +# Where X is the character being defined, and a..g are the segments that are +# active. a, d, and g are considered active if they are "_" and inactive if +# they are anything else. b, c, e, and f are considered active if they are "|" +# and inactive if they are anything else. The top-right character (marked "." +# in the diagram above) is ignored. The result is fairly visually obvious :) + + . 0_ 1. 2_ 3_ 4. 5_ 6_ 7_ 8_ 9_ +... |.| ..| ._| ._| |_| |_. |_. ..| |_| |_| +... |_| ..| |_. ._| ..| ._| |_| ..| |_| ._| + +A_ B. C_ D. E_ F_ G_ H. I. J. L. N_ O. P_ Q_ R. S_ T. U. Y. +|_| |_. |.. ._| |_. |_. |.. |_| |.. ..| |.. |.| ._. |_| |_| ._. |_. |_. |.| |_| +|.| |_| |_. |_| |_. |.. |_| |.| |.. ._| |__ |.| |_| |.. ..| |.. ._| |_. |_| ._| diff --git a/.venv/lib/python3.7/site-packages/gpiozero/input_devices.py b/.venv/lib/python3.7/site-packages/gpiozero/input_devices.py new file mode 100644 index 0000000..a25be74 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/input_devices.py @@ -0,0 +1,1374 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2015-2021 Ben Nuttall +# Copyright (c) 2020 Robert Erdin +# Copyright (c) 2020 Dan Jackson +# Copyright (c) 2016-2020 Andrew Scheller +# Copyright (c) 2019 Kosovan Sofiia +# Copyright (c) 2018 Philippe Muller +# Copyright (c) 2016 Steveis +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) + +import warnings +from time import sleep, time +from threading import Event, Lock +from itertools import tee +try: + from statistics import median, mean +except ImportError: + from .compat import median, mean + +from .exc import InputDeviceError, DeviceClosed, DistanceSensorNoEcho, \ + PinInvalidState, PWMSoftwareFallback +from .devices import GPIODevice, CompositeDevice +from .mixins import GPIOQueue, EventsMixin, HoldMixin, event +try: + from .pins.pigpio import PiGPIOFactory +except ImportError: + PiGPIOFactory = None + + +class InputDevice(GPIODevice): + """ + Represents a generic GPIO input device. + + This class extends :class:`GPIODevice` to add facilities common to GPIO + input devices. The constructor adds the optional *pull_up* parameter to + specify how the pin should be pulled by the internal resistors. The + :attr:`is_active` property is adjusted accordingly so that :data:`True` + still means active regardless of the *pull_up* setting. + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + If :data:`True`, the pin will be pulled high with an internal resistor. + If :data:`False` (the default), the pin will be pulled low. If + :data:`None`, the pin will be floating. As gpiozero cannot + automatically guess the active state when not pulling the pin, the + *active_state* parameter must be passed. + + :type active_state: bool or None + :param active_state: + If :data:`True`, when the hardware pin state is ``HIGH``, the software + pin is ``HIGH``. If :data:`False`, the input polarity is reversed: when + the hardware pin state is ``HIGH``, the software pin state is ``LOW``. + Use this parameter to set the active state of the underlying pin when + configuring it as not pulled (when *pull_up* is :data:`None`). When + *pull_up* is :data:`True` or :data:`False`, the active state is + automatically set to the proper value. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, pin=None, pull_up=False, active_state=None, + pin_factory=None): + super(InputDevice, self).__init__(pin, pin_factory=pin_factory) + try: + self.pin.function = 'input' + pull = {None: 'floating', True: 'up', False: 'down'}[pull_up] + if self.pin.pull != pull: + self.pin.pull = pull + except: + self.close() + raise + + if pull_up is None: + if active_state is None: + raise PinInvalidState( + 'Pin %d is defined as floating, but "active_state" is not ' + 'defined' % self.pin.number) + self._active_state = bool(active_state) + else: + if active_state is not None: + raise PinInvalidState( + 'Pin %d is not floating, but "active_state" is not None' % + self.pin.number) + self._active_state = False if pull_up else True + self._inactive_state = not self._active_state + + @property + def pull_up(self): + """ + If :data:`True`, the device uses a pull-up resistor to set the GPIO pin + "high" by default. + """ + pull = self.pin.pull + if pull == 'floating': + return None + else: + return pull == 'up' + + def __repr__(self): + try: + return "" % ( + self.__class__.__name__, self.pin, self.pull_up, self.is_active) + except: + return super(InputDevice, self).__repr__() + + +class DigitalInputDevice(EventsMixin, InputDevice): + """ + Represents a generic input device with typical on/off behaviour. + + This class extends :class:`InputDevice` with machinery to fire the active + and inactive events for devices that operate in a typical digital manner: + straight forward on / off states with (reasonably) clean transitions + between the two. + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + See description under :class:`InputDevice` for more information. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :type bounce_time: float or None + :param bounce_time: + Specifies the length of time (in seconds) that the component will + ignore changes in state after an initial change. This defaults to + :data:`None` which indicates that no bounce compensation will be + performed. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, pull_up=False, active_state=None, bounce_time=None, + pin_factory=None): + super(DigitalInputDevice, self).__init__( + pin, pull_up=pull_up, active_state=active_state, + pin_factory=pin_factory) + try: + self.pin.bounce = bounce_time + self.pin.edges = 'both' + self.pin.when_changed = self._pin_changed + # Call _fire_events once to set initial state of events + self._fire_events(self.pin_factory.ticks(), self.is_active) + except: + self.close() + raise + + def _pin_changed(self, ticks, state): + # XXX This is a bit of a hack; _fire_events takes *is_active* rather + # than *value*. Here we're assuming no-one's overridden the default + # implementation of *is_active*. + self._fire_events(ticks, bool(self._state_to_value(state))) + + +class SmoothedInputDevice(EventsMixin, InputDevice): + """ + Represents a generic input device which takes its value from the average of + a queue of historical values. + + This class extends :class:`InputDevice` with a queue which is filled by a + background thread which continually polls the state of the underlying + device. The average (a configurable function) of the values in the queue is + compared to a threshold which is used to determine the state of the + :attr:`is_active` property. + + .. note:: + + The background queue is not automatically started upon construction. + This is to allow descendents to set up additional components before the + queue starts reading values. Effectively this is an abstract base + class. + + This class is intended for use with devices which either exhibit analog + behaviour (such as the charging time of a capacitor with an LDR), or those + which exhibit "twitchy" behaviour (such as certain motion sensors). + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + See description under :class:`InputDevice` for more information. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :param float threshold: + The value above which the device will be considered "on". + + :param int queue_len: + The length of the internal queue which is filled by the background + thread. + + :param float sample_wait: + The length of time to wait between retrieving the state of the + underlying device. Defaults to 0.0 indicating that values are retrieved + as fast as possible. + + :param bool partial: + If :data:`False` (the default), attempts to read the state of the + device (from the :attr:`is_active` property) will block until the queue + has filled. If :data:`True`, a value will be returned immediately, but + be aware that this value is likely to fluctuate excessively. + + :param average: + The function used to average the values in the internal queue. This + defaults to :func:`statistics.median` which is a good selection for + discarding outliers from jittery sensors. The function specified must + accept a sequence of numbers and return a single number. + + :type ignore: frozenset or None + :param ignore: + The set of values which the queue should ignore, if returned from + querying the device's value. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, pull_up=False, active_state=None, threshold=0.5, + queue_len=5, sample_wait=0.0, partial=False, average=median, + ignore=None, pin_factory=None): + self._queue = None + super(SmoothedInputDevice, self).__init__( + pin, pull_up=pull_up, active_state=active_state, + pin_factory=pin_factory) + try: + self._queue = GPIOQueue(self, queue_len, sample_wait, partial, + average, ignore) + self.threshold = float(threshold) + except: + self.close() + raise + + def close(self): + try: + self._queue.stop() + except AttributeError: + # If the queue isn't initialized (it's None), or _queue hasn't been + # set ignore the error because we're trying to close anyway + pass + except RuntimeError: + # Cannot join thread before it starts; we don't care about this + # because we're trying to close the thread anyway + pass + self._queue = None + super(SmoothedInputDevice, self).close() + + def __repr__(self): + try: + self._check_open() + except DeviceClosed: + return super(SmoothedInputDevice, self).__repr__() + else: + if self.partial or self._queue.full.is_set(): + return super(SmoothedInputDevice, self).__repr__() + else: + return "" % ( + self.__class__.__name__, self.pin, self.pull_up) + + @property + def queue_len(self): + """ + The length of the internal queue of values which is averaged to + determine the overall state of the device. This defaults to 5. + """ + self._check_open() + return self._queue.queue.maxlen + + @property + def partial(self): + """ + If :data:`False` (the default), attempts to read the + :attr:`~SmoothedInputDevice.value` or + :attr:`~SmoothedInputDevice.is_active` properties will block until the + queue has filled. + """ + self._check_open() + return self._queue.partial + + @property + def value(self): + """ + Returns the average of the values in the internal queue. This is + compared to :attr:`~SmoothedInputDevice.threshold` to determine whether + :attr:`is_active` is :data:`True`. + """ + self._check_open() + return self._queue.value + + @property + def threshold(self): + """ + If :attr:`~SmoothedInputDevice.value` exceeds this amount, then + :attr:`is_active` will return :data:`True`. + """ + return self._threshold + + @threshold.setter + def threshold(self, value): + if not (0.0 < value < 1.0): + raise InputDeviceError( + 'threshold must be between zero and one exclusive' + ) + self._threshold = float(value) + + @property + def is_active(self): + """ + Returns :data:`True` if the :attr:`~SmoothedInputDevice.value` + currently exceeds :attr:`~SmoothedInputDevice.threshold` and + :data:`False` otherwise. + """ + return self.value > self.threshold + + +class Button(HoldMixin, DigitalInputDevice): + """ + Extends :class:`DigitalInputDevice` and represents a simple push button + or switch. + + Connect one side of the button to a ground pin, and the other to any GPIO + pin. Alternatively, connect one side of the button to the 3V3 pin, and the + other to any GPIO pin, then set *pull_up* to :data:`False` in the + :class:`Button` constructor. + + The following example will print a line of text when the button is pushed:: + + from gpiozero import Button + + button = Button(4) + button.wait_for_press() + print("The button was pressed!") + + :type pin: int or str + :param pin: + The GPIO pin which the button is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + If :data:`True` (the default), the GPIO pin will be pulled high by + default. In this case, connect the other side of the button to ground. + If :data:`False`, the GPIO pin will be pulled low by default. In this + case, connect the other side of the button to 3V3. If :data:`None`, the + pin will be floating, so it must be externally pulled up or down and + the ``active_state`` parameter must be set accordingly. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :type bounce_time: float or None + :param bounce_time: + If :data:`None` (the default), no software bounce compensation will be + performed. Otherwise, this is the length of time (in seconds) that the + component will ignore changes in state after an initial change. + + :param float hold_time: + The length of time (in seconds) to wait after the button is pushed, + until executing the :attr:`when_held` handler. Defaults to ``1``. + + :param bool hold_repeat: + If :data:`True`, the :attr:`when_held` handler will be repeatedly + executed as long as the device remains active, every *hold_time* + seconds. If :data:`False` (the default) the :attr:`when_held` handler + will be only be executed once per hold. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, pull_up=True, active_state=None, bounce_time=None, + hold_time=1, hold_repeat=False, pin_factory=None): + super(Button, self).__init__( + pin, pull_up=pull_up, active_state=active_state, + bounce_time=bounce_time, pin_factory=pin_factory) + self.hold_time = hold_time + self.hold_repeat = hold_repeat + + @property + def value(self): + """ + Returns 1 if the button is currently pressed, and 0 if it is not. + """ + return super(Button, self).value + +Button.is_pressed = Button.is_active +Button.pressed_time = Button.active_time +Button.when_pressed = Button.when_activated +Button.when_released = Button.when_deactivated +Button.wait_for_press = Button.wait_for_active +Button.wait_for_release = Button.wait_for_inactive + + +class LineSensor(SmoothedInputDevice): + """ + Extends :class:`SmoothedInputDevice` and represents a single pin line + sensor like the TCRT5000 infra-red proximity sensor found in the `CamJam #3 + EduKit`_. + + A typical line sensor has a small circuit board with three pins: VCC, GND, + and OUT. VCC should be connected to a 3V3 pin, GND to one of the ground + pins, and finally OUT to the GPIO specified as the value of the *pin* + parameter in the constructor. + + The following code will print a line of text indicating when the sensor + detects a line, or stops detecting a line:: + + from gpiozero import LineSensor + from signal import pause + + sensor = LineSensor(4) + sensor.when_line = lambda: print('Line detected') + sensor.when_no_line = lambda: print('No line detected') + pause() + + :type pin: int or str + :param pin: + The GPIO pin which the sensor is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + See description under :class:`InputDevice` for more information. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :param int queue_len: + The length of the queue used to store values read from the sensor. This + defaults to 5. + + :param float sample_rate: + The number of values to read from the device (and append to the + internal queue) per second. Defaults to 100. + + :param float threshold: + Defaults to 0.5. When the average of all values in the internal queue + rises above this value, the sensor will be considered "active" by the + :attr:`~SmoothedInputDevice.is_active` property, and all appropriate + events will be fired. + + :param bool partial: + When :data:`False` (the default), the object will not return a value + for :attr:`~SmoothedInputDevice.is_active` until the internal queue has + filled with values. Only set this to :data:`True` if you require + values immediately after object construction. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _CamJam #3 EduKit: http://camjam.me/?page_id=1035 + """ + def __init__( + self, pin=None, pull_up=False, active_state=None, queue_len=5, + sample_rate=100, threshold=0.5, partial=False, pin_factory=None): + super(LineSensor, self).__init__( + pin, pull_up=pull_up, active_state=active_state, + threshold=threshold, queue_len=queue_len, + sample_wait=1 / sample_rate, partial=partial, + pin_factory=pin_factory) + self._queue.start() + + @property + def value(self): + """ + Returns a value representing the average of the queued values. This + is nearer 0 for black under the sensor, and nearer 1 for white under + the sensor. + """ + return super(LineSensor, self).value + + @property + def line_detected(self): + return not self.is_active + +LineSensor.when_line = LineSensor.when_deactivated +LineSensor.when_no_line = LineSensor.when_activated +LineSensor.wait_for_line = LineSensor.wait_for_inactive +LineSensor.wait_for_no_line = LineSensor.wait_for_active + + +class MotionSensor(SmoothedInputDevice): + """ + Extends :class:`SmoothedInputDevice` and represents a passive infra-red + (PIR) motion sensor like the sort found in the `CamJam #2 EduKit`_. + + .. _CamJam #2 EduKit: http://camjam.me/?page_id=623 + + A typical PIR device has a small circuit board with three pins: VCC, OUT, + and GND. VCC should be connected to a 5V pin, GND to one of the ground + pins, and finally OUT to the GPIO specified as the value of the *pin* + parameter in the constructor. + + The following code will print a line of text when motion is detected:: + + from gpiozero import MotionSensor + + pir = MotionSensor(4) + pir.wait_for_motion() + print("Motion detected!") + + :type pin: int or str + :param pin: + The GPIO pin which the sensor is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :type pull_up: bool or None + :param pull_up: + See description under :class:`InputDevice` for more information. + + :type active_state: bool or None + :param active_state: + See description under :class:`InputDevice` for more information. + + :param int queue_len: + The length of the queue used to store values read from the sensor. This + defaults to 1 which effectively disables the queue. If your motion + sensor is particularly "twitchy" you may wish to increase this value. + + :param float sample_rate: + The number of values to read from the device (and append to the + internal queue) per second. Defaults to 10. + + :param float threshold: + Defaults to 0.5. When the average of all values in the internal queue + rises above this value, the sensor will be considered "active" by the + :attr:`~SmoothedInputDevice.is_active` property, and all appropriate + events will be fired. + + :param bool partial: + When :data:`False` (the default), the object will not return a value + for :attr:`~SmoothedInputDevice.is_active` until the internal queue has + filled with values. Only set this to :data:`True` if you require + values immediately after object construction. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, pull_up=False, active_state=None, queue_len=1, + sample_rate=10, threshold=0.5, partial=False, pin_factory=None): + super(MotionSensor, self).__init__( + pin, pull_up=pull_up, active_state=active_state, + threshold=threshold, queue_len=queue_len, sample_wait=1 / + sample_rate, partial=partial, pin_factory=pin_factory, average=mean) + self._queue.start() + + @property + def value(self): + """ + With the default *queue_len* of 1, this is effectively boolean where 0 + means no motion detected and 1 means motion detected. If you specify + a *queue_len* greater than 1, this will be an averaged value where + values closer to 1 imply motion detection. + """ + return super(MotionSensor, self).value + +MotionSensor.motion_detected = MotionSensor.is_active +MotionSensor.when_motion = MotionSensor.when_activated +MotionSensor.when_no_motion = MotionSensor.when_deactivated +MotionSensor.wait_for_motion = MotionSensor.wait_for_active +MotionSensor.wait_for_no_motion = MotionSensor.wait_for_inactive + + +class LightSensor(SmoothedInputDevice): + """ + Extends :class:`SmoothedInputDevice` and represents a light dependent + resistor (LDR). + + Connect one leg of the LDR to the 3V3 pin; connect one leg of a 1µF + capacitor to a ground pin; connect the other leg of the LDR and the other + leg of the capacitor to the same GPIO pin. This class repeatedly discharges + the capacitor, then times the duration it takes to charge (which will vary + according to the light falling on the LDR). + + The following code will print a line of text when light is detected:: + + from gpiozero import LightSensor + + ldr = LightSensor(18) + ldr.wait_for_light() + print("Light detected!") + + :type pin: int or str + :param pin: + The GPIO pin which the sensor is attached to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param int queue_len: + The length of the queue used to store values read from the circuit. + This defaults to 5. + + :param float charge_time_limit: + If the capacitor in the circuit takes longer than this length of time + to charge, it is assumed to be dark. The default (0.01 seconds) is + appropriate for a 1µF capacitor coupled with the LDR from the + `CamJam #2 EduKit`_. You may need to adjust this value for different + valued capacitors or LDRs. + + :param float threshold: + Defaults to 0.1. When the average of all values in the internal queue + rises above this value, the area will be considered "light", and all + appropriate events will be fired. + + :param bool partial: + When :data:`False` (the default), the object will not return a value + for :attr:`~SmoothedInputDevice.is_active` until the internal queue has + filled with values. Only set this to :data:`True` if you require + values immediately after object construction. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _CamJam #2 EduKit: http://camjam.me/?page_id=623 + """ + def __init__( + self, pin=None, queue_len=5, charge_time_limit=0.01, + threshold=0.1, partial=False, pin_factory=None): + super(LightSensor, self).__init__( + pin, pull_up=False, threshold=threshold, queue_len=queue_len, + sample_wait=0.0, partial=partial, pin_factory=pin_factory) + try: + self._charge_time_limit = charge_time_limit + self._charge_time = None + self._charged = Event() + self.pin.edges = 'rising' + self.pin.bounce = None + self.pin.when_changed = self._cap_charged + self._queue.start() + except: + self.close() + raise + + @property + def charge_time_limit(self): + return self._charge_time_limit + + def _cap_charged(self, ticks, state): + self._charge_time = ticks + self._charged.set() + + def _read(self): + # Drain charge from the capacitor + self.pin.function = 'output' + self.pin.state = False + sleep(0.1) + self._charge_time = None + self._charged.clear() + # Time the charging of the capacitor + start = self.pin_factory.ticks() + self.pin.function = 'input' + self._charged.wait(self.charge_time_limit) + if self._charge_time is None: + return 0.0 + else: + return 1.0 - min(1.0, + (self.pin_factory.ticks_diff(self._charge_time, start) / + self.charge_time_limit)) + + @property + def value(self): + """ + Returns a value between 0 (dark) and 1 (light). + """ + return super(LightSensor, self).value + +LightSensor.light_detected = LightSensor.is_active +LightSensor.when_light = LightSensor.when_activated +LightSensor.when_dark = LightSensor.when_deactivated +LightSensor.wait_for_light = LightSensor.wait_for_active +LightSensor.wait_for_dark = LightSensor.wait_for_inactive + + +class DistanceSensor(SmoothedInputDevice): + """ + Extends :class:`SmoothedInputDevice` and represents an HC-SR04 ultrasonic + distance sensor, as found in the `CamJam #3 EduKit`_. + + The distance sensor requires two GPIO pins: one for the *trigger* (marked + TRIG on the sensor) and another for the *echo* (marked ECHO on the sensor). + However, a voltage divider is required to ensure the 5V from the ECHO pin + doesn't damage the Pi. Wire your sensor according to the following + instructions: + + 1. Connect the GND pin of the sensor to a ground pin on the Pi. + + 2. Connect the TRIG pin of the sensor a GPIO pin. + + 3. Connect one end of a 330Ω resistor to the ECHO pin of the sensor. + + 4. Connect one end of a 470Ω resistor to the GND pin of the sensor. + + 5. Connect the free ends of both resistors to another GPIO pin. This forms + the required `voltage divider`_. + + 6. Finally, connect the VCC pin of the sensor to a 5V pin on the Pi. + + Alternatively, the 3V3 tolerant HC-SR04P sensor (which does not require a + voltage divider) will work with this class. + + + .. note:: + + If you do not have the precise values of resistor specified above, + don't worry! What matters is the *ratio* of the resistors to each + other. + + You also don't need to be absolutely precise; the `voltage divider`_ + given above will actually output ~3V (rather than 3.3V). A simple 2:3 + ratio will give 3.333V which implies you can take three resistors of + equal value, use one of them instead of the 330Ω resistor, and two of + them in series instead of the 470Ω resistor. + + .. _voltage divider: https://en.wikipedia.org/wiki/Voltage_divider + + The following code will periodically report the distance measured by the + sensor in cm assuming the TRIG pin is connected to GPIO17, and the ECHO + pin to GPIO18:: + + from gpiozero import DistanceSensor + from time import sleep + + sensor = DistanceSensor(echo=18, trigger=17) + while True: + print('Distance: ', sensor.distance * 100) + sleep(1) + + .. note:: + + For improved accuracy, use the pigpio pin driver rather than the default + RPi.GPIO driver (pigpio uses DMA sampling for much more precise edge + timing). This is particularly relevant if you're using Pi 1 or Pi Zero. + See :ref:`changing-pin-factory` for further information. + + :type echo: int or str + :param echo: + The GPIO pin which the ECHO pin is connected to. See + :ref:`pin-numbering` for valid pin numbers. If this is :data:`None` a + :exc:`GPIODeviceError` will be raised. + + :type trigger: int or str + :param trigger: + The GPIO pin which the TRIG pin is connected to. See + :ref:`pin-numbering` for valid pin numbers. If this is :data:`None` a + :exc:`GPIODeviceError` will be raised. + + :param int queue_len: + The length of the queue used to store values read from the sensor. + This defaults to 9. + + :param float max_distance: + The :attr:`value` attribute reports a normalized value between 0 (too + close to measure) and 1 (maximum distance). This parameter specifies + the maximum distance expected in meters. This defaults to 1. + + :param float threshold_distance: + Defaults to 0.3. This is the distance (in meters) that will trigger the + ``in_range`` and ``out_of_range`` events when crossed. + + :param bool partial: + When :data:`False` (the default), the object will not return a value + for :attr:`~SmoothedInputDevice.is_active` until the internal queue has + filled with values. Only set this to :data:`True` if you require + values immediately after object construction. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _CamJam #3 EduKit: http://camjam.me/?page_id=1035 + """ + ECHO_LOCK = Lock() + + def __init__( + self, echo=None, trigger=None, queue_len=9, max_distance=1, + threshold_distance=0.3, partial=False, pin_factory=None): + self._trigger = None + super(DistanceSensor, self).__init__( + echo, pull_up=False, queue_len=queue_len, sample_wait=0.06, + partial=partial, ignore=frozenset({None}), pin_factory=pin_factory + ) + try: + if max_distance <= 0: + raise ValueError('invalid maximum distance (must be positive)') + self._max_distance = max_distance + self.threshold = threshold_distance / max_distance + self.speed_of_sound = 343.26 # m/s + self._trigger = GPIODevice(trigger, pin_factory=pin_factory) + self._echo = Event() + self._echo_rise = None + self._echo_fall = None + self._trigger.pin.function = 'output' + self._trigger.pin.state = False + self.pin.edges = 'both' + self.pin.bounce = None + self.pin.when_changed = self._echo_changed + self._queue.start() + except: + self.close() + raise + + if PiGPIOFactory is None or not isinstance(self.pin_factory, PiGPIOFactory): + warnings.warn(PWMSoftwareFallback( + 'For more accurate readings, use the pigpio pin factory.' + 'See https://gpiozero.readthedocs.io/en/stable/api_input.html#distancesensor-hc-sr04 for more info' + )) + + def close(self): + try: + self._trigger.close() + except AttributeError: + pass + self._trigger = None + super(DistanceSensor, self).close() + + @property + def max_distance(self): + """ + The maximum distance that the sensor will measure in meters. This value + is specified in the constructor and is used to provide the scaling for + the :attr:`~SmoothedInputDevice.value` attribute. When :attr:`distance` + is equal to :attr:`max_distance`, :attr:`~SmoothedInputDevice.value` + will be 1. + """ + return self._max_distance + + @max_distance.setter + def max_distance(self, value): + if value <= 0: + raise ValueError('invalid maximum distance (must be positive)') + t = self.threshold_distance + self._max_distance = value + self.threshold_distance = t + + @property + def threshold_distance(self): + """ + The distance, measured in meters, that will trigger the + :attr:`when_in_range` and :attr:`when_out_of_range` events when + crossed. This is simply a meter-scaled variant of the usual + :attr:`~SmoothedInputDevice.threshold` attribute. + """ + return self.threshold * self.max_distance + + @threshold_distance.setter + def threshold_distance(self, value): + self.threshold = value / self.max_distance + + @property + def distance(self): + """ + Returns the current distance measured by the sensor in meters. Note + that this property will have a value between 0 and + :attr:`max_distance`. + """ + return self.value * self._max_distance + + @property + def value(self): + """ + Returns a value between 0, indicating the reflector is either touching + the sensor or is sufficiently near that the sensor can't tell the + difference, and 1, indicating the reflector is at or beyond the + specified *max_distance*. + """ + return super(DistanceSensor, self).value + + @property + def trigger(self): + """ + Returns the :class:`Pin` that the sensor's trigger is connected to. + """ + return self._trigger.pin + + @property + def echo(self): + """ + Returns the :class:`Pin` that the sensor's echo is connected to. This + is simply an alias for the usual :attr:`~GPIODevice.pin` attribute. + """ + return self.pin + + def _echo_changed(self, ticks, level): + if level: + self._echo_rise = ticks + else: + self._echo_fall = ticks + self._echo.set() + + def _read(self): + # Wait up to 50ms for the echo pin to fall to low (the maximum echo + # pulse is 35ms so this gives some leeway); if it doesn't something is + # horribly wrong (most likely at the hardware level) + if self.pin.state: + if not self._echo.wait(0.05): + warnings.warn(DistanceSensorNoEcho('echo pin set high')) + return None + self._echo.clear() + self._echo_fall = None + self._echo_rise = None + # Obtain the class-level ECHO_LOCK to ensure multiple distance sensors + # don't listen for each other's "pings" + with DistanceSensor.ECHO_LOCK: + # Fire the trigger + self._trigger.pin.state = True + sleep(0.00001) + self._trigger.pin.state = False + # Wait up to 100ms for the echo pin to rise and fall (35ms is the + # maximum pulse time, but the pre-rise time is unspecified in the + # "datasheet"; 100ms seems sufficiently long to conclude something + # has failed) + if self._echo.wait(0.1): + if self._echo_fall is not None and self._echo_rise is not None: + distance = ( + self.pin_factory.ticks_diff( + self._echo_fall, self._echo_rise) * + self.speed_of_sound / 2.0) + return min(1.0, distance / self._max_distance) + else: + # If we only saw the falling edge it means we missed + # the echo because it was too fast + return None + else: + # The echo pin never rose or fell; something's gone horribly + # wrong + warnings.warn(DistanceSensorNoEcho('no echo received')) + return None + + @property + def in_range(self): + return not self.is_active + +DistanceSensor.when_out_of_range = DistanceSensor.when_activated +DistanceSensor.when_in_range = DistanceSensor.when_deactivated +DistanceSensor.wait_for_out_of_range = DistanceSensor.wait_for_active +DistanceSensor.wait_for_in_range = DistanceSensor.wait_for_inactive + + +class RotaryEncoder(EventsMixin, CompositeDevice): + """ + Represents a simple two-pin incremental `rotary encoder`_ device. + + These devices typically have three pins labelled "A", "B", and "C". Connect + A and B directly to two GPIO pins, and C ("common") to one of the ground + pins on your Pi. Then simply specify the A and B pins as the arguments when + constructing this classs. + + For example, if your encoder's A pin is connected to GPIO 21, and the B + pin to GPIO 20 (and presumably the C pin to a suitable GND pin), while an + LED (with a suitable 300Ω resistor) is connected to GPIO 5, the following + session will result in the brightness of the LED being controlled by + dialling the rotary encoder back and forth:: + + >>> from gpiozero import RotaryEncoder + >>> from gpiozero.tools import scaled_half + >>> rotor = RotaryEncoder(21, 20) + >>> led = PWMLED(5) + >>> led.source = scaled_half(rotor.values) + + :type a: int or str + :param a: + The GPIO pin connected to the "A" output of the rotary encoder. + + :type b: int or str + :param b: + The GPIO pin connected to the "B" output of the rotary encoder. + + :type bounce_time: float or None + :param bounce_time: + If :data:`None` (the default), no software bounce compensation will be + performed. Otherwise, this is the length of time (in seconds) that the + component will ignore changes in state after an initial change. + + :type max_steps: int + :param max_steps: + The number of steps clockwise the encoder takes to change the + :attr:`value` from 0 to 1, or counter-clockwise from 0 to -1. + If this is 0, then the encoder's :attr:`value` never changes, but you + can still read :attr:`steps` to determine the integer number of steps + the encoder has moved clockwise or counter clockwise. + + :type threshold_steps: tuple of int + :param threshold_steps: + A (min, max) tuple of steps between which the device will be considered + "active", inclusive. In other words, when :attr:`steps` is greater than + or equal to the *min* value, and less than or equal the *max* value, + the :attr:`active` property will be :data:`True` and the appropriate + events (:attr:`when_activated`, :attr:`when_deactivated`) will be + fired. Defaults to (0, 0). + + :type wrap: bool + :param wrap: + If :data:`True` and *max_steps* is non-zero, when the :attr:`steps` + reaches positive or negative *max_steps* it wraps around by negation. + Defaults to :data:`False`. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _rotary encoder: https://en.wikipedia.org/wiki/Rotary_encoder + """ + # The rotary encoder's two pins move through the following sequence when + # the encoder is rotated one step clockwise: + # + # ────┠┌─────┠┌──────── + # _ │ │ │ │ counter ┌───┠+ # A │ │ │ │ clockwise ┌─── │ 0 │ ───┠clockwise + # └─────┘ └─────┘ (CCW) │ └───┘ │ (CW) + # : : : : │ ┌───┠┌───┠│ + # ───────┠: ┌─────┠: ┌───── â–¾ │ 1 │ │ 2 │ â–¾ + # _ : │ : │ : │ : │ └───┘ └───┘ + # B : │ : │ : │ : │ │ ┌───┠│ + # : └─────┘ : └─────┘ └─── │ 3 │ ───┘ + # : : : : : : : : └───┘ + # 0 2 3 1 0 2 3 1 0 + # + # Treating the A pin as a "high" bit, and the B pin as a "low" bit, this + # means that the pins return the sequence 0, 2, 3, 1 for each step that the + # encoder takes clockwise. Conversely, the pins return the sequence 0, 1, + # 3, 2 for each step counter-clockwise. + # + # We can treat these values as edges to take in a simple state machine, + # which is represented in the dictionary below: + + TRANSITIONS = { + 'idle': ['idle', 'ccw1', 'cw1', 'idle'], + 'ccw1': ['idle', 'ccw1', 'ccw3', 'ccw2'], + 'ccw2': ['idle', 'ccw1', 'ccw3', 'ccw2'], + 'ccw3': ['-1', 'idle', 'ccw3', 'ccw2'], + 'cw1': ['idle', 'cw3', 'cw1', 'cw2'], + 'cw2': ['idle', 'cw3', 'cw1', 'cw2'], + 'cw3': ['+1', 'cw3', 'idle', 'cw2'], + } + + # The state machine here includes more than just the strictly necessary + # edges; it also permits "wiggle" between intermediary states so that the + # overall graph looks like this: + # + # ┌──────┠+ # │ │ + # ┌─────┤ idle ├────┠+ # │1 │ │ 2│ + # │ └──────┘ │ + # â–¾ â–´ â–´ â–¾ + # ┌────────┠│ │ ┌───────┠+ # │ │ 0│ │0 │ │ + # ┌───┤ ccw1 ├──┤ ├──┤ cw1 ├───┠+ # │2 │ │ │ │ │ │ 1│ + # │ └─┬──────┘ │ │ └─────┬─┘ │ + # │ 3│ â–´ │ │ â–´ │3 │ + # │ â–¾ │1 │ │ 2│ â–¾ │ + # │ ┌──────┴─┠│ │ ┌─┴─────┠│ + # │ │ │ 0│ │0 │ │ │ + # │ │ ccw2 ├──┤ ├──┤ cw2 │ │ + # │ │ │ │ │ │ │ │ + # │ └─┬──────┘ │ │ └─────┬─┘ │ + # │ 2│ â–´ │ │ â–´ │1 │ + # │ â–¾ │3 │ │ 3│ â–¾ │ + # │ ┌──────┴─┠│ │ ┌─┴─────┠│ + # │ │ │ │ │ │ │ │ + # └──▸│ ccw3 │ │ │ │ cw3 │◂──┘ + # │ │ │ │ │ │ + # └───┬────┘ │ │ └───┬───┘ + # 0│ │ │ │0 + # â–¾ │ │ â–¾ + # ┌────────┠│ │ ┌───────┠+ # │ │ │ │ │ │ + # │ -1 ├──┘ └──┤ +1 │ + # │ │ │ │ + # └────────┘ └───────┘ + # + # Note that, once we start down the clockwise (cw) or counter-clockwise + # (ccw) path, we don't allow the state to pick the alternate direction + # without passing through the idle state again. This seems to work well in + # practice with several encoders, even quite jiggly ones with no debounce + # hardware or software + + def __init__( + self, a, b, bounce_time=None, max_steps=16, threshold_steps=(0, 0), + wrap=False, pin_factory=None): + min_thresh, max_thresh = threshold_steps + if max_thresh < min_thresh: + raise ValueError('maximum threshold cannot be less than minimum') + self._steps = 0 + self._max_steps = int(max_steps) + self._threshold = (int(min_thresh), int(max_thresh)) + self._wrap = bool(wrap) + self._state = 'idle' + self._edge = 0 + self._when_rotated = None + self._when_rotated_cw = None + self._when_rotated_ccw = None + self._rotate_event = Event() + self._rotate_cw_event = Event() + self._rotate_ccw_event = Event() + super(RotaryEncoder, self).__init__( + a=InputDevice(a, pull_up=True, pin_factory=pin_factory), + b=InputDevice(b, pull_up=True, pin_factory=pin_factory), + _order=('a', 'b'), pin_factory=pin_factory) + self.a.pin.bounce_time = bounce_time + self.b.pin.bounce_time = bounce_time + self.a.pin.edges = 'both' + self.b.pin.edges = 'both' + self.a.pin.when_changed = self._a_changed + self.b.pin.when_changed = self._b_changed + # Call _fire_events once to set initial state of events + self._fire_events(self.pin_factory.ticks(), self.is_active) + + def __repr__(self): + try: + self._check_open() + return "" % ( + self.__class__.__name__, self.a.pin, self.b.pin) + except DeviceClosed: + return super(RotaryEncoder, self).__repr__() + + def _a_changed(self, ticks, state): + edge = (self.a._state_to_value(state) << 1) | (self._edge & 0x1) + self._change_state(ticks, edge) + + def _b_changed(self, ticks, state): + edge = (self._edge & 0x2) | self.b._state_to_value(state) + self._change_state(ticks, edge) + + def _change_state(self, ticks, edge): + self._edge = edge + new_state = RotaryEncoder.TRANSITIONS[self._state][edge] + if new_state == '+1': + self._steps = ( + self._steps + 1 + if not self._max_steps or self._steps < self._max_steps else + -self._max_steps if self._wrap else self._max_steps + ) + self._rotate_cw_event.set() + self._fire_rotated_cw() + self._rotate_cw_event.clear() + elif new_state == '-1': + self._steps = ( + self._steps - 1 + if not self._max_steps or self._steps > -self._max_steps else + self._max_steps if self._wrap else -self._max_steps + ) + self._rotate_ccw_event.set() + self._fire_rotated_ccw() + self._rotate_ccw_event.clear() + else: + self._state = new_state + return + self._rotate_event.set() + self._fire_rotated() + self._rotate_event.clear() + self._fire_events(ticks, self.is_active) + self._state = 'idle' + + def wait_for_rotate(self, timeout=None): + """ + Pause the script until the encoder is rotated at least one step in + either direction, or the timeout is reached. + + :type timeout: float or None + :param timeout: + Number of seconds to wait before proceeding. If this is + :data:`None` (the default), then wait indefinitely until the + encoder is rotated. + """ + return self._rotate_event.wait(timeout) + + def wait_for_rotate_clockwise(self, timeout=None): + """ + Pause the script until the encoder is rotated at least one step + clockwise, or the timeout is reached. + + :type timeout: float or None + :param timeout: + Number of seconds to wait before proceeding. If this is + :data:`None` (the default), then wait indefinitely until the + encoder is rotated clockwise. + """ + return self._rotate_cw_event.wait(timeout) + + def wait_for_rotate_counter_clockwise(self, timeout=None): + """ + Pause the script until the encoder is rotated at least one step + counter-clockwise, or the timeout is reached. + + :type timeout: float or None + :param timeout: + Number of seconds to wait before proceeding. If this is + :data:`None` (the default), then wait indefinitely until the + encoder is rotated counter-clockwise. + """ + return self._rotate_ccw_event.wait(timeout) + + when_rotated = event( + """ + The function to be run when the encoder is rotated in either direction. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that activated will be passed + as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + when_rotated_clockwise = event( + """ + The function to be run when the encoder is rotated clockwise. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that activated will be passed + as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + when_rotated_counter_clockwise = event( + """ + The function to be run when the encoder is rotated counter-clockwise. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that activated will be passed + as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + @property + def steps(self): + """ + The "steps" value of the encoder starts at 0. It increments by one for + every step the encoder is rotated clockwise, and decrements by one for + every step it is rotated counter-clockwise. The steps value is + limited by :attr:`max_steps`. It will not advance beyond positive or + negative :attr:`max_steps`, unless :attr:`wrap` is :data:`True` in + which case it will roll around by negation. If :attr:`max_steps` is + zero then steps are not limited at all, and will increase infinitely + in either direction, but :attr:`value` will return a constant zero. + + Note that, in contrast to most other input devices, because the rotary + encoder has no absolute position the :attr:`steps` attribute (and + :attr:`value` by corollary) is writable. + """ + return self._steps + + def _fire_rotated(self): + if self.when_rotated: + self.when_rotated() + + def _fire_rotated_cw(self): + if self.when_rotated_clockwise: + self.when_rotated_clockwise() + + def _fire_rotated_ccw(self): + if self.when_rotated_counter_clockwise: + self.when_rotated_counter_clockwise() + + @steps.setter + def steps(self, value): + value = int(value) + if self._max_steps: + value = max(-self._max_steps, min(self._max_steps, value)) + self._steps = value + + @property + def value(self): + """ + Represents the value of the rotary encoder as a value between -1 and 1. + The value is calculated by dividing the value of :attr:`steps` into the + range from negative :attr:`max_steps` to positive :attr:`max_steps`. + + Note that, in contrast to most other input devices, because the rotary + encoder has no absolute position the :attr:`value` attribute is + writable. + """ + try: + return self._steps / self._max_steps + except ZeroDivisionError: + return 0 + + @value.setter + def value(self, value): + self._steps = int(max(-1, min(1, float(value))) * self._max_steps) + + @property + def is_active(self): + return self._threshold[0] <= self._steps <= self._threshold[1] + + @property + def max_steps(self): + """ + The number of discrete steps the rotary encoder takes to move + :attr:`value` from 0 to 1 clockwise, or 0 to -1 counter-clockwise. In + another sense, this is also the total number of discrete states this + input can represent. + """ + return self._max_steps + + @property + def threshold_steps(self): + """ + The mininum and maximum number of steps between which :attr:`is_active` + will return :data:`True`. Defaults to (0, 0). + """ + return self._threshold + + @property + def wrap(self): + """ + If :data:`True`, when :attr:`value` reaches its limit (-1 or 1), it + "wraps around" to the opposite limit. When :data:`False`, the value + (and the corresponding :attr:`steps` attribute) simply don't advance + beyond their limits. + """ + return self._wrap diff --git a/.venv/lib/python3.7/site-packages/gpiozero/internal_devices.py b/.venv/lib/python3.7/site-packages/gpiozero/internal_devices.py new file mode 100644 index 0000000..a3ab387 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/internal_devices.py @@ -0,0 +1,750 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2017-2021 Ben Nuttall +# Copyright (c) 2019 Jeevan M R <14.jeevan@gmail.com> +# Copyright (c) 2019 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) +str = type('') + + +import os +import io +import subprocess +from datetime import datetime, time +import warnings + +from .devices import Device +from .mixins import EventsMixin, event +from .threads import GPIOThread +from .exc import ThresholdOutOfRange, DeviceClosed + + +class InternalDevice(EventsMixin, Device): + """ + Extends :class:`Device` to provide a basis for devices which have no + specific hardware representation. These are effectively pseudo-devices and + usually represent operating system services like the internal clock, file + systems or network facilities. + """ + def __init__(self, pin_factory=None): + self._closed = False + super(InternalDevice, self).__init__(pin_factory=pin_factory) + + def close(self): + self._closed = True + super(InternalDevice, self).close() + + @property + def closed(self): + return self._closed + + def __repr__(self): + try: + self._check_open() + return "" % self.__class__.__name__ + except DeviceClosed: + return "" % self.__class__.__name__ + + +class PolledInternalDevice(InternalDevice): + """ + Extends :class:`InternalDevice` to provide a background thread to poll + internal devices that lack any other mechanism to inform the instance of + changes. + """ + def __init__(self, event_delay=1.0, pin_factory=None): + self._event_thread = None + self._event_delay = event_delay + super(PolledInternalDevice, self).__init__(pin_factory=pin_factory) + + def close(self): + try: + self._start_stop_events(False) + except AttributeError: + pass # pragma: no cover + super(PolledInternalDevice, self).close() + + @property + def event_delay(self): + """ + The delay between sampling the device's value for the purposes of + firing events. + + Note that this only applies to events assigned to attributes like + :attr:`~EventsMixin.when_activated` and + :attr:`~EventsMixin.when_deactivated`. When using the + :attr:`~SourceMixin.source` and :attr:`~ValuesMixin.values` properties, + the sampling rate is controlled by the + :attr:`~SourceMixin.source_delay` property. + """ + return self._event_delay + + @event_delay.setter + def event_delay(self, value): + self._event_delay = float(value) + + def wait_for_active(self, timeout=None): + self._start_stop_events(True) + try: + return super(PolledInternalDevice, self).wait_for_active(timeout) + finally: + self._start_stop_events( + self.when_activated or self.when_deactivated) + + def wait_for_inactive(self, timeout=None): + self._start_stop_events(True) + try: + return super(PolledInternalDevice, self).wait_for_inactive(timeout) + finally: + self._start_stop_events( + self.when_activated or self.when_deactivated) + + def _watch_value(self): + while not self._event_thread.stopping.wait(self._event_delay): + self._fire_events(self.pin_factory.ticks(), self.is_active) + + def _start_stop_events(self, enabled): + if self._event_thread and not enabled: + self._event_thread.stop() + self._event_thread = None + elif not self._event_thread and enabled: + self._event_thread = GPIOThread(self._watch_value) + self._event_thread.start() + + +class PingServer(PolledInternalDevice): + """ + Extends :class:`PolledInternalDevice` to provide a device which is active + when a *host* (domain name or IP address) can be pinged. + + The following example lights an LED while ``google.com`` is reachable:: + + from gpiozero import PingServer, LED + from signal import pause + + google = PingServer('google.com') + led = LED(4) + + google.when_activated = led.on + google.when_deactivated = led.off + + pause() + + :param str host: + The hostname or IP address to attempt to ping. + + :type event_delay: float + :param event_delay: + The number of seconds between pings (defaults to 10 seconds). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, host, event_delay=10.0, pin_factory=None): + self._host = host + super(PingServer, self).__init__( + event_delay=event_delay, pin_factory=pin_factory) + self._fire_events(self.pin_factory.ticks(), self.is_active) + + def __repr__(self): + try: + self._check_open() + return '' % self.host + except DeviceClosed: + return super(PingServer, self).__repr__() + + @property + def host(self): + """ + The hostname or IP address to test whenever :attr:`value` is queried. + """ + return self._host + + @property + def value(self): + """ + Returns :data:`1` if the host returned a single ping, and :data:`0` + otherwise. + """ + # XXX This is doing a DNS lookup every time it's queried; should we + # call gethostbyname in the constructor and ping that instead (good + # for consistency, but what if the user *expects* the host to change + # address?) + with io.open(os.devnull, 'wb') as devnull: + try: + subprocess.check_call( + ['ping', '-c1', self.host], + stdout=devnull, stderr=devnull) + except subprocess.CalledProcessError: + return 0 + else: + return 1 + + when_activated = event( + """ + The function to run when the device changes state from inactive + (host unresponsive) to active (host responsive). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from inactive + (host responsive) to active (host unresponsive). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + +class CPUTemperature(PolledInternalDevice): + """ + Extends :class:`PolledInternalDevice` to provide a device which is active + when the CPU temperature exceeds the *threshold* value. + + The following example plots the CPU's temperature on an LED bar graph:: + + from gpiozero import LEDBarGraph, CPUTemperature + from signal import pause + + # Use minimums and maximums that are closer to "normal" usage so the + # bar graph is a bit more "lively" + cpu = CPUTemperature(min_temp=50, max_temp=90) + + print('Initial temperature: {}C'.format(cpu.temperature)) + + graph = LEDBarGraph(5, 6, 13, 19, 25, pwm=True) + graph.source = cpu + + pause() + + :param str sensor_file: + The file from which to read the temperature. This defaults to the + sysfs file :file:`/sys/class/thermal/thermal_zone0/temp`. Whatever + file is specified is expected to contain a single line containing the + temperature in milli-degrees celsius. + + :param float min_temp: + The temperature at which :attr:`value` will read 0.0. This defaults to + 0.0. + + :param float max_temp: + The temperature at which :attr:`value` will read 1.0. This defaults to + 100.0. + + :param float threshold: + The temperature above which the device will be considered "active". + (see :attr:`is_active`). This defaults to 80.0. + + :type event_delay: float + :param event_delay: + The number of seconds between file reads (defaults to 5 seconds). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, sensor_file='/sys/class/thermal/thermal_zone0/temp', + min_temp=0.0, max_temp=100.0, threshold=80.0, event_delay=5.0, + pin_factory=None): + self.sensor_file = sensor_file + super(CPUTemperature, self).__init__( + event_delay=event_delay, pin_factory=pin_factory) + try: + if min_temp >= max_temp: + raise ValueError('max_temp must be greater than min_temp') + self.min_temp = min_temp + self.max_temp = max_temp + if not min_temp <= threshold <= max_temp: + warnings.warn(ThresholdOutOfRange( + 'threshold is outside of the range (min_temp, max_temp)')) + self.threshold = threshold + self._fire_events(self.pin_factory.ticks(), self.is_active) + except: + self.close() + raise + + def __repr__(self): + try: + self._check_open() + return '' % self.temperature + except DeviceClosed: + return super(CPUTemperature, self).__repr__() + + @property + def temperature(self): + """ + Returns the current CPU temperature in degrees celsius. + """ + with io.open(self.sensor_file, 'r') as f: + return float(f.read().strip()) / 1000 + + @property + def value(self): + """ + Returns the current CPU temperature as a value between 0.0 + (representing the *min_temp* value) and 1.0 (representing the + *max_temp* value). These default to 0.0 and 100.0 respectively, hence + :attr:`value` is :attr:`temperature` divided by 100 by default. + """ + temp_range = self.max_temp - self.min_temp + return (self.temperature - self.min_temp) / temp_range + + @property + def is_active(self): + """ + Returns :data:`True` when the CPU :attr:`temperature` exceeds the + *threshold*. + """ + return self.temperature > self.threshold + + when_activated = event( + """ + The function to run when the device changes state from inactive to + active (temperature reaches *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from active to + inactive (temperature drops below *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + +class LoadAverage(PolledInternalDevice): + """ + Extends :class:`PolledInternalDevice` to provide a device which is active + when the CPU load average exceeds the *threshold* value. + + The following example plots the load average on an LED bar graph:: + + from gpiozero import LEDBarGraph, LoadAverage + from signal import pause + + la = LoadAverage(min_load_average=0, max_load_average=2) + graph = LEDBarGraph(5, 6, 13, 19, 25, pwm=True) + + graph.source = la + + pause() + + :param str load_average_file: + The file from which to read the load average. This defaults to the + proc file :file:`/proc/loadavg`. Whatever file is specified is expected + to contain three space-separated load averages at the beginning of the + file, representing 1 minute, 5 minute and 15 minute averages + respectively. + + :param float min_load_average: + The load average at which :attr:`value` will read 0.0. This defaults to + 0.0. + + :param float max_load_average: + The load average at which :attr:`value` will read 1.0. This defaults to + 1.0. + + :param float threshold: + The load average above which the device will be considered "active". + (see :attr:`is_active`). This defaults to 0.8. + + :param int minutes: + The number of minutes over which to average the load. Must be 1, 5 or + 15. This defaults to 5. + + :type event_delay: float + :param event_delay: + The number of seconds between file reads (defaults to 10 seconds). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, load_average_file='/proc/loadavg', min_load_average=0.0, + max_load_average=1.0, threshold=0.8, minutes=5, event_delay=10.0, + pin_factory=None): + if min_load_average >= max_load_average: + raise ValueError( + 'max_load_average must be greater than min_load_average') + self.load_average_file = load_average_file + self.min_load_average = min_load_average + self.max_load_average = max_load_average + if not min_load_average <= threshold <= max_load_average: + warnings.warn(ThresholdOutOfRange( + 'threshold is outside of the range (min_load_average, ' + 'max_load_average)')) + self.threshold = threshold + if minutes not in (1, 5, 15): + raise ValueError('minutes must be 1, 5 or 15') + self._load_average_file_column = { + 1: 0, + 5: 1, + 15: 2, + }[minutes] + super(LoadAverage, self).__init__( + event_delay=event_delay, pin_factory=pin_factory) + self._fire_events(self.pin_factory.ticks(), None) + + def __repr__(self): + try: + self._check_open() + return '' % self.load_average + except DeviceClosed: + return super(LoadAverage, self).__repr__() + + @property + def load_average(self): + """ + Returns the current load average. + """ + with io.open(self.load_average_file, 'r') as f: + print(repr(f)) + file_columns = f.read().strip().split() + return float(file_columns[self._load_average_file_column]) + + @property + def value(self): + """ + Returns the current load average as a value between 0.0 (representing + the *min_load_average* value) and 1.0 (representing the + *max_load_average* value). These default to 0.0 and 1.0 respectively. + """ + load_average_range = self.max_load_average - self.min_load_average + return (self.load_average - self.min_load_average) / load_average_range + + @property + def is_active(self): + """ + Returns :data:`True` when the :attr:`load_average` exceeds the + *threshold*. + """ + return self.load_average > self.threshold + + when_activated = event( + """ + The function to run when the device changes state from inactive to + active (load average reaches *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from active to + inactive (load average drops below *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + +class TimeOfDay(PolledInternalDevice): + """ + Extends :class:`PolledInternalDevice` to provide a device which is active + when the computer's clock indicates that the current time is between + *start_time* and *end_time* (inclusive) which are :class:`~datetime.time` + instances. + + The following example turns on a lamp attached to an :class:`Energenie` + plug between 07:00AM and 08:00AM:: + + from gpiozero import TimeOfDay, Energenie + from datetime import time + from signal import pause + + lamp = Energenie(1) + morning = TimeOfDay(time(7), time(8)) + + morning.when_activated = lamp.on + morning.when_deactivated = lamp.off + + pause() + + Note that *start_time* may be greater than *end_time*, indicating a time + period which crosses midnight. + + :param ~datetime.time start_time: + The time from which the device will be considered active. + + :param ~datetime.time end_time: + The time after which the device will be considered inactive. + + :param bool utc: + If :data:`True` (the default), a naive UTC time will be used for the + comparison rather than a local time-zone reading. + + :type event_delay: float + :param event_delay: + The number of seconds between file reads (defaults to 10 seconds). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, start_time, end_time, utc=True, event_delay=5.0, + pin_factory=None): + self._start_time = None + self._end_time = None + self._utc = True + super(TimeOfDay, self).__init__( + event_delay=event_delay, pin_factory=pin_factory) + try: + self._start_time = self._validate_time(start_time) + self._end_time = self._validate_time(end_time) + if self.start_time == self.end_time: + raise ValueError('end_time cannot equal start_time') + self._utc = utc + self._fire_events(self.pin_factory.ticks(), self.is_active) + except: + self.close() + raise + + def __repr__(self): + try: + self._check_open() + return '' % ( + self.start_time, self.end_time, ('local', 'UTC')[self.utc]) + except DeviceClosed: + return super(TimeOfDay, self).__repr__() + + def _validate_time(self, value): + if isinstance(value, datetime): + value = value.time() + if not isinstance(value, time): + raise ValueError( + 'start_time and end_time must be a datetime, or time instance') + return value + + @property + def start_time(self): + """ + The time of day after which the device will be considered active. + """ + return self._start_time + + @property + def end_time(self): + """ + The time of day after which the device will be considered inactive. + """ + return self._end_time + + @property + def utc(self): + """ + If :data:`True`, use a naive UTC time reading for comparison instead of + a local timezone reading. + """ + return self._utc + + @property + def value(self): + """ + Returns :data:`1` when the system clock reads between :attr:`start_time` + and :attr:`end_time`, and :data:`0` otherwise. If :attr:`start_time` is + greater than :attr:`end_time` (indicating a period that crosses + midnight), then this returns :data:`1` when the current time is + greater than :attr:`start_time` or less than :attr:`end_time`. + """ + now = datetime.utcnow().time() if self.utc else datetime.now().time() + if self.start_time < self.end_time: + return int(self.start_time <= now <= self.end_time) + else: + return int(not self.end_time < now < self.start_time) + + when_activated = event( + """ + The function to run when the device changes state from inactive to + active (time reaches *start_time*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from active to + inactive (time reaches *end_time*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + +class DiskUsage(PolledInternalDevice): + """ + Extends :class:`PolledInternalDevice` to provide a device which is active + when the disk space used exceeds the *threshold* value. + + The following example plots the disk usage on an LED bar graph:: + + from gpiozero import LEDBarGraph, DiskUsage + from signal import pause + + disk = DiskUsage() + + print('Current disk usage: {}%'.format(disk.usage)) + + graph = LEDBarGraph(5, 6, 13, 19, 25, pwm=True) + graph.source = disk + + pause() + + :param str filesystem: + A path within the filesystem for which the disk usage needs to be + computed. This defaults to :file:`/`, which is the root filesystem. + + :param float threshold: + The disk usage percentage above which the device will be considered + "active" (see :attr:`is_active`). This defaults to 90.0. + + :type event_delay: float + :param event_delay: + The number of seconds between file reads (defaults to 30 seconds). + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, filesystem='/', threshold=90.0, event_delay=30.0, + pin_factory=None): + super(DiskUsage, self).__init__( + event_delay=event_delay, pin_factory=pin_factory) + os.statvfs(filesystem) + if not 0 <= threshold <= 100: + warnings.warn(ThresholdOutOfRange( + 'threshold is outside of the range (0, 100)')) + self.filesystem = filesystem + self.threshold = threshold + self._fire_events(self.pin_factory.ticks(), None) + + def __repr__(self): + try: + self._check_open() + return '' % self.usage + except DeviceClosed: + return super(DiskUsage, self).__repr__() + + @property + def usage(self): + """ + Returns the current disk usage in percentage. + """ + return self.value * 100 + + @property + def value(self): + """ + Returns the current disk usage as a value between 0.0 and 1.0 by + dividing :attr:`usage` by 100. + """ + # This slightly convoluted calculation is equivalent to df's "Use%"; + # it calculates the percentage of FS usage as a proportion of the + # space available to *non-root users*. Technically this means it can + # exceed 100% (when FS is filled to the point that only root can write + # to it), hence the clamp. + vfs = os.statvfs(self.filesystem) + used = vfs.f_blocks - vfs.f_bfree + total = used + vfs.f_bavail + return min(1.0, used / total) + + @property + def is_active(self): + """ + Returns :data:`True` when the disk :attr:`usage` exceeds the + *threshold*. + """ + return self.usage > self.threshold + + when_activated = event( + """ + The function to run when the device changes state from inactive to + active (disk usage reaches *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from active to + inactive (disk usage drops below *threshold*). + + This can be set to a function which accepts no (mandatory) + parameters, or a Python function which accepts a single mandatory + parameter (with as many optional parameters as you like). If the + function accepts a single mandatory parameter, the device that + activated it will be passed as that parameter. + + Set this property to ``None`` (the default) to disable the event. + """) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/mixins.py b/.venv/lib/python3.7/site-packages/gpiozero/mixins.py new file mode 100644 index 0000000..6ad9e50 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/mixins.py @@ -0,0 +1,604 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2018-2021 Ben Nuttall +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +nstr = str +str = type('') + +import inspect +import weakref +from functools import wraps, partial +from threading import Event +from collections import deque +try: + from statistics import median +except ImportError: + from .compat import median +import warnings + +from .threads import GPIOThread +from .exc import ( + BadEventHandler, + BadWaitTime, + BadQueueLen, + DeviceClosed, + CallbackSetToNone, + ) + +callback_warning = ( + 'The callback was set to None. This may have been unintentional ' + 'e.g. btn.when_pressed = pressed() instead of btn.when_pressed = pressed' +) + +class ValuesMixin(object): + """ + Adds a :attr:`values` property to the class which returns an infinite + generator of readings from the :attr:`~Device.value` property. There is + rarely a need to use this mixin directly as all base classes in GPIO Zero + include it. + + .. note:: + + Use this mixin *first* in the parent class list. + """ + + @property + def values(self): + """ + An infinite iterator of values read from :attr:`value`. + """ + while True: + try: + yield self.value + except DeviceClosed: + break + + +class SourceMixin(object): + """ + Adds a :attr:`source` property to the class which, given an iterable or a + :class:`ValuesMixin` descendent, sets :attr:`~Device.value` to each member + of that iterable until it is exhausted. This mixin is generally included in + novel output devices to allow their state to be driven from another device. + + .. note:: + + Use this mixin *first* in the parent class list. + """ + + def __init__(self, *args, **kwargs): + self._source = None + self._source_thread = None + self._source_delay = 0.01 + super(SourceMixin, self).__init__(*args, **kwargs) + + def close(self): + self.source = None + super(SourceMixin, self).close() + + def _copy_values(self, source): + for v in source: + self.value = v + if self._source_thread.stopping.wait(self._source_delay): + break + + @property + def source_delay(self): + """ + The delay (measured in seconds) in the loop used to read values from + :attr:`source`. Defaults to 0.01 seconds which is generally sufficient + to keep CPU usage to a minimum while providing adequate responsiveness. + """ + return self._source_delay + + @source_delay.setter + def source_delay(self, value): + if value < 0: + raise BadWaitTime('source_delay must be 0 or greater') + self._source_delay = float(value) + + @property + def source(self): + """ + The iterable to use as a source of values for :attr:`value`. + """ + return self._source + + @source.setter + def source(self, value): + if getattr(self, '_source_thread', None): + self._source_thread.stop() + self._source_thread = None + if isinstance(value, ValuesMixin): + value = value.values + self._source = value + if value is not None: + self._source_thread = GPIOThread(self._copy_values, (value,)) + self._source_thread.start() + + +class SharedMixin(object): + """ + This mixin marks a class as "shared". In this case, the meta-class + (GPIOMeta) will use :meth:`_shared_key` to convert the constructor + arguments to an immutable key, and will check whether any existing + instances match that key. If they do, they will be returned by the + constructor instead of a new instance. An internal reference counter is + used to determine how many times an instance has been "constructed" in this + way. + + When :meth:`~Device.close` is called, an internal reference counter will be + decremented and the instance will only close when it reaches zero. + """ + _instances = {} + + def __del__(self): + self._refs = 0 + super(SharedMixin, self).__del__() + + @classmethod + def _shared_key(cls, *args, **kwargs): + """ + This is called with the constructor arguments to generate a unique + key (which must be storable in a :class:`dict` and, thus, immutable + and hashable) representing the instance that can be shared. This must + be overridden by descendents. + + The default simply assumes all positional arguments are immutable and + returns this as the key but this is almost never the "right" thing to + do and almost all descendents should override this method. + """ + # XXX Future 2.x version should change this to raise NotImplementedError + return args + + +class event(object): + """ + A descriptor representing a callable event on a class descending from + :class:`EventsMixin`. + + Instances of this class are very similar to a :class:`property` but also + deal with notifying the owning class when events are assigned (or + unassigned) and wrapping callbacks implicitly as appropriate. + """ + def __init__(self, doc=None): + self.handlers = {} + self.__doc__ = doc + + def __get__(self, instance, owner=None): + if instance is None: + return self + else: + return self.handlers.get(id(instance)) + + def __set__(self, instance, value): + if value is None: + try: + del self.handlers[id(instance)] + except KeyError: + warnings.warn(CallbackSetToNone(callback_warning)) + else: + self.handlers[id(instance)] = instance._wrap_callback(value) + enabled = any( + obj.handlers.get(id(instance)) + for name in dir(type(instance)) + for obj in (getattr(type(instance), name),) + if isinstance(obj, event) + ) + instance._start_stop_events(enabled) + + +class EventsMixin(object): + """ + Adds edge-detected :meth:`when_activated` and :meth:`when_deactivated` + events to a device based on changes to the :attr:`~Device.is_active` + property common to all devices. Also adds :meth:`wait_for_active` and + :meth:`wait_for_inactive` methods for level-waiting. + + .. note:: + + Note that this mixin provides no means of actually firing its events; + call :meth:`_fire_events` in sub-classes when device state changes to + trigger the events. This should also be called once at the end of + initialization to set initial states. + """ + def __init__(self, *args, **kwargs): + super(EventsMixin, self).__init__(*args, **kwargs) + self._active_event = Event() + self._inactive_event = Event() + self._last_active = None + self._last_changed = self.pin_factory.ticks() + + def _all_events(self): + """ + Generator function which yields all :class:`event` instances defined + against this class. + """ + for name in dir(type(self)): + obj = getattr(type(self), name) + if isinstance(obj, event): + yield obj + + def close(self): + for ev in self._all_events(): + try: + del ev.handlers[id(self)] + except KeyError: + pass + super(EventsMixin, self).close() + + def wait_for_active(self, timeout=None): + """ + Pause the script until the device is activated, or the timeout is + reached. + + :type timeout: float or None + :param timeout: + Number of seconds to wait before proceeding. If this is + :data:`None` (the default), then wait indefinitely until the device + is active. + """ + return self._active_event.wait(timeout) + + def wait_for_inactive(self, timeout=None): + """ + Pause the script until the device is deactivated, or the timeout is + reached. + + :type timeout: float or None + :param timeout: + Number of seconds to wait before proceeding. If this is + :data:`None` (the default), then wait indefinitely until the device + is inactive. + """ + return self._inactive_event.wait(timeout) + + when_activated = event( + """ + The function to run when the device changes state from inactive to + active. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that activated it will be passed + as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + when_deactivated = event( + """ + The function to run when the device changes state from active to + inactive. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that deactivated it will be + passed as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + @property + def active_time(self): + """ + The length of time (in seconds) that the device has been active for. + When the device is inactive, this is :data:`None`. + """ + if self._active_event.is_set(): + return self.pin_factory.ticks_diff(self.pin_factory.ticks(), + self._last_changed) + else: + return None + + @property + def inactive_time(self): + """ + The length of time (in seconds) that the device has been inactive for. + When the device is active, this is :data:`None`. + """ + if self._inactive_event.is_set(): + return self.pin_factory.ticks_diff(self.pin_factory.ticks(), + self._last_changed) + else: + return None + + def _wrap_callback(self, fn): + # XXX In 2.x, move this to the event class above + if not callable(fn): + raise BadEventHandler('value must be None or a callable') + # If fn is wrapped with partial (i.e. partial, partialmethod, or wraps + # has been used to produce it) we need to dig out the "real" function + # that's been wrapped along with all the mandatory positional args + # used in the wrapper so we can test the binding + args = () + wrapped_fn = fn + while isinstance(wrapped_fn, partial): + args = wrapped_fn.args + args + wrapped_fn = wrapped_fn.func + if inspect.isbuiltin(wrapped_fn): + # We can't introspect the prototype of builtins. In this case we + # assume that the builtin has no (mandatory) parameters; this is + # the most reasonable assumption on the basis that pre-existing + # builtins have no knowledge of gpiozero, and the sole parameter + # we would pass is a gpiozero object + return fn + else: + # Try binding ourselves to the argspec of the provided callable. + # If this works, assume the function is capable of accepting no + # parameters + try: + inspect.getcallargs(wrapped_fn, *args) + return fn + except TypeError: + try: + # If the above fails, try binding with a single parameter + # (ourselves). If this works, wrap the specified callback + inspect.getcallargs(wrapped_fn, *(args + (self,))) + @wraps(fn) + def wrapper(): + return fn(self) + return wrapper + except TypeError: + raise BadEventHandler( + 'value must be a callable which accepts up to one ' + 'mandatory parameter') + + def _fire_activated(self): + # These methods are largely here to be overridden by descendents + if self.when_activated: + self.when_activated() + + def _fire_deactivated(self): + # These methods are largely here to be overridden by descendents + if self.when_deactivated: + self.when_deactivated() + + def _fire_events(self, ticks, new_active): + """ + This method should be called by descendents whenever the + :attr:`~Device.is_active` property is likely to have changed (for + example, in response to a pin's :attr:`~gpiozero.Pin.state` changing). + + The *ticks* parameter must be set to the time when the change occurred; + this can usually be obtained from the pin factory's + :meth:`gpiozero.Factory.ticks` method but some pin implementations will + implicitly provide the ticks when an event occurs as part of their + reporting mechanism. + + The *new_active* parameter must be set to the device's + :attr:`~Device.is_active` value at the time indicated by *ticks* (which + is not necessarily the value of :attr:`~Device.is_active` right now, if + the pin factory provides means of reporting a pin's historical state). + """ + old_active, self._last_active = self._last_active, new_active + if old_active is None: + # Initial "indeterminate" state; set events but don't fire + # callbacks as there's not necessarily an edge + if new_active: + self._active_event.set() + else: + self._inactive_event.set() + elif old_active != new_active: + self._last_changed = ticks + if new_active: + self._inactive_event.clear() + self._active_event.set() + self._fire_activated() + else: + self._active_event.clear() + self._inactive_event.set() + self._fire_deactivated() + + def _start_stop_events(self, enabled): + """ + This is a stub method that only exists to be overridden by descendents. + It is called when :class:`event` properties are assigned (including + when set to :data:`None) to permit the owning instance to activate or + deactivate monitoring facilities. + + For example, if a descendent requires a background thread to monitor a + device, it would be preferable to only run the thread if event handlers + are present to respond to it. + + The *enabled* parameter is :data:`False` when all :class:`event` + properties on the owning class are :data:`None`, and :data:`True` + otherwise. + """ + pass + + +class HoldMixin(EventsMixin): + """ + Extends :class:`EventsMixin` to add the :attr:`when_held` event and the + machinery to fire that event repeatedly (when :attr:`hold_repeat` is + :data:`True`) at internals defined by :attr:`hold_time`. + """ + def __init__(self, *args, **kwargs): + self._hold_thread = None + super(HoldMixin, self).__init__(*args, **kwargs) + self._when_held = None + self._held_from = None + self._hold_time = 1 + self._hold_repeat = False + self._hold_thread = HoldThread(self) + + def close(self): + if self._hold_thread is not None: + self._hold_thread.stop() + self._hold_thread = None + super(HoldMixin, self).close() + + def _fire_activated(self): + super(HoldMixin, self)._fire_activated() + self._hold_thread.holding.set() + + def _fire_deactivated(self): + self._held_from = None + super(HoldMixin, self)._fire_deactivated() + + def _fire_held(self): + if self.when_held: + self.when_held() + + when_held = event( + """ + The function to run when the device has remained active for + :attr:`hold_time` seconds. + + This can be set to a function which accepts no (mandatory) parameters, + or a Python function which accepts a single mandatory parameter (with + as many optional parameters as you like). If the function accepts a + single mandatory parameter, the device that activated will be passed + as that parameter. + + Set this property to :data:`None` (the default) to disable the event. + """) + + @property + def hold_time(self): + """ + The length of time (in seconds) to wait after the device is activated, + until executing the :attr:`when_held` handler. If :attr:`hold_repeat` + is True, this is also the length of time between invocations of + :attr:`when_held`. + """ + return self._hold_time + + @hold_time.setter + def hold_time(self, value): + if value < 0: + raise BadWaitTime('hold_time must be 0 or greater') + self._hold_time = float(value) + + @property + def hold_repeat(self): + """ + If :data:`True`, :attr:`when_held` will be executed repeatedly with + :attr:`hold_time` seconds between each invocation. + """ + return self._hold_repeat + + @hold_repeat.setter + def hold_repeat(self, value): + self._hold_repeat = bool(value) + + @property + def is_held(self): + """ + When :data:`True`, the device has been active for at least + :attr:`hold_time` seconds. + """ + return self._held_from is not None + + @property + def held_time(self): + """ + The length of time (in seconds) that the device has been held for. + This is counted from the first execution of the :attr:`when_held` event + rather than when the device activated, in contrast to + :attr:`~EventsMixin.active_time`. If the device is not currently held, + this is :data:`None`. + """ + if self._held_from is not None: + return self.pin_factory.ticks_diff(self.pin_factory.ticks(), + self._held_from) + else: + return None + + +class HoldThread(GPIOThread): + """ + Extends :class:`GPIOThread`. Provides a background thread that repeatedly + fires the :attr:`HoldMixin.when_held` event as long as the owning + device is active. + """ + def __init__(self, parent): + super(HoldThread, self).__init__( + target=self.held, args=(weakref.proxy(parent),)) + self.holding = Event() + self.start() + + def held(self, parent): + try: + while not self.stopping.is_set(): + if self.holding.wait(0.1): + self.holding.clear() + while not ( + self.stopping.is_set() or + parent._inactive_event.wait(parent.hold_time) + ): + if parent._held_from is None: + parent._held_from = parent.pin_factory.ticks() + parent._fire_held() + if not parent.hold_repeat: + break + except ReferenceError: + # Parent is dead; time to die! + pass + + +class GPIOQueue(GPIOThread): + """ + Extends :class:`GPIOThread`. Provides a background thread that monitors a + device's values and provides a running *average* (defaults to median) of + those values. If the *parent* device includes the :class:`EventsMixin` in + its ancestry, the thread automatically calls + :meth:`~EventsMixin._fire_events`. + """ + def __init__( + self, parent, queue_len=5, sample_wait=0.0, partial=False, + average=median, ignore=None): + assert callable(average) + if queue_len < 1: + raise BadQueueLen('queue_len must be at least one') + if sample_wait < 0: + raise BadWaitTime('sample_wait must be 0 or greater') + if ignore is None: + ignore = set() + super(GPIOQueue, self).__init__(target=self.fill) + self.queue = deque(maxlen=queue_len) + self.partial = bool(partial) + self.sample_wait = float(sample_wait) + self.full = Event() + self.parent = weakref.proxy(parent) + self.average = average + self.ignore = ignore + + @property + def value(self): + if not self.partial: + self.full.wait() + try: + return self.average(self.queue) + except (ZeroDivisionError, ValueError): + # No data == inactive value + return 0.0 + + def fill(self): + try: + while not self.stopping.wait(self.sample_wait): + value = self.parent._read() + if value not in self.ignore: + self.queue.append(value) + if not self.full.is_set() and len(self.queue) >= self.queue.maxlen: + self.full.set() + if (self.partial or self.full.is_set()) and isinstance(self.parent, EventsMixin): + self.parent._fire_events(self.parent.pin_factory.ticks(), self.parent.is_active) + except ReferenceError: + # Parent is dead; time to die! + pass diff --git a/.venv/lib/python3.7/site-packages/gpiozero/output_devices.py b/.venv/lib/python3.7/site-packages/gpiozero/output_devices.py new file mode 100644 index 0000000..5f4f63a --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/output_devices.py @@ -0,0 +1,1808 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2015-2020 Ben Nuttall +# Copyright (c) 2019 tuftii <3215045+tuftii@users.noreply.github.com> +# Copyright (c) 2019 tuftii +# Copyright (c) 2019 Yisrael Dov Lebow đŸ» +# Copyright (c) 2019 Kosovan Sofiia +# Copyright (c) 2016-2019 Andrew Scheller +# Copyright (c) 2016 Ian Harcombe +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) +str = type('') + +from threading import Lock +from itertools import repeat, cycle, chain +from colorzero import Color +from collections import OrderedDict +try: + from math import log2 +except ImportError: + from .compat import log2 +import warnings + +from .exc import ( + OutputDeviceBadValue, + GPIOPinMissing, + PWMSoftwareFallback, + DeviceClosed, +) +from .devices import GPIODevice, Device, CompositeDevice +from .mixins import SourceMixin +from .threads import GPIOThread +from .tones import Tone +try: + from .pins.pigpio import PiGPIOFactory +except ImportError: + PiGPIOFactory = None + +class OutputDevice(SourceMixin, GPIODevice): + """ + Represents a generic GPIO output device. + + This class extends :class:`GPIODevice` to add facilities common to GPIO + output devices: an :meth:`on` method to switch the device on, a + corresponding :meth:`off` method, and a :meth:`toggle` method. + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set the GPIO + to HIGH. If :data:`False`, the :meth:`on` method will set the GPIO to + LOW (the :meth:`off` method always does the opposite). + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), the device will be off initially. If + :data:`None`, the device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, active_high=True, initial_value=False, + pin_factory=None): + super(OutputDevice, self).__init__(pin, pin_factory=pin_factory) + self._lock = Lock() + self.active_high = active_high + if initial_value is None: + self.pin.function = 'output' + else: + self.pin.output_with_state(self._value_to_state(initial_value)) + + def _value_to_state(self, value): + return bool(self._active_state if value else self._inactive_state) + + def _write(self, value): + try: + self.pin.state = self._value_to_state(value) + except AttributeError: + self._check_open() + raise + + def on(self): + """ + Turns the device on. + """ + self._write(True) + + def off(self): + """ + Turns the device off. + """ + self._write(False) + + def toggle(self): + """ + Reverse the state of the device. If it's on, turn it off; if it's off, + turn it on. + """ + with self._lock: + if self.is_active: + self.off() + else: + self.on() + + @property + def value(self): + """ + Returns 1 if the device is currently active and 0 otherwise. Setting + this property changes the state of the device. + """ + return super(OutputDevice, self).value + + @value.setter + def value(self, value): + self._write(value) + + @property + def active_high(self): + """ + When :data:`True`, the :attr:`value` property is :data:`True` when the + device's :attr:`~GPIODevice.pin` is high. When :data:`False` the + :attr:`value` property is :data:`True` when the device's pin is low + (i.e. the value is inverted). + + This property can be set after construction; be warned that changing it + will invert :attr:`value` (i.e. changing this property doesn't change + the device's pin state - it just changes how that state is + interpreted). + """ + return self._active_state + + @active_high.setter + def active_high(self, value): + self._active_state = True if value else False + self._inactive_state = False if value else True + + def __repr__(self): + try: + return '' % ( + self.__class__.__name__, self.pin, self.active_high, self.is_active) + except: + return super(OutputDevice, self).__repr__() + + +class DigitalOutputDevice(OutputDevice): + """ + Represents a generic output device with typical on/off behaviour. + + This class extends :class:`OutputDevice` with a :meth:`blink` method which + uses an optional background thread to handle toggling the device state + without further interaction. + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set the GPIO + to HIGH. If :data:`False`, the :meth:`on` method will set the GPIO to + LOW (the :meth:`off` method always does the opposite). + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), the device will be off initially. If + :data:`None`, the device will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the device will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, active_high=True, initial_value=False, + pin_factory=None): + self._blink_thread = None + self._controller = None + super(DigitalOutputDevice, self).__init__( + pin, active_high, initial_value, pin_factory=pin_factory + ) + + @property + def value(self): + return super(DigitalOutputDevice, self).value + + @value.setter + def value(self, value): + self._stop_blink() + self._write(value) + + def close(self): + self._stop_blink() + super(DigitalOutputDevice, self).close() + + def on(self): + self._stop_blink() + self._write(True) + + def off(self): + self._stop_blink() + self._write(False) + + def blink(self, on_time=1, off_time=1, n=None, background=True): + """ + Make the device turn on and off repeatedly. + + :param float on_time: + Number of seconds on. Defaults to 1 second. + + :param float off_time: + Number of seconds off. Defaults to 1 second. + + :type n: int or None + :param n: + Number of times to blink; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue blinking and return immediately. If :data:`False`, only + return when the blink is finished (warning: the default value of + *n* will result in this method never returning). + """ + self._stop_blink() + self._blink_thread = GPIOThread( + self._blink_device, (on_time, off_time, n) + ) + self._blink_thread.start() + if not background: + self._blink_thread.join() + self._blink_thread = None + + def _stop_blink(self): + if getattr(self, '_controller', None): + self._controller._stop_blink(self) + self._controller = None + if getattr(self, '_blink_thread', None): + self._blink_thread.stop() + self._blink_thread = None + + def _blink_device(self, on_time, off_time, n): + iterable = repeat(0) if n is None else repeat(0, n) + for _ in iterable: + self._write(True) + if self._blink_thread.stopping.wait(on_time): + break + self._write(False) + if self._blink_thread.stopping.wait(off_time): + break + + +class LED(DigitalOutputDevice): + """ + Extends :class:`DigitalOutputDevice` and represents a light emitting diode + (LED). + + Connect the cathode (short leg, flat side) of the LED to a ground pin; + connect the anode (longer leg) to a limiting resistor; connect the other + side of the limiting resistor to a GPIO pin (the limiting resistor can be + placed either side of the LED). + + The following example will light the LED:: + + from gpiozero import LED + + led = LED(17) + led.on() + + :type pin: int or str + :param pin: + The GPIO pin which the LED is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the LED will operate normally with the + circuit described above. If :data:`False` you should wire the cathode + to the GPIO pin, and the anode to a 3V3 pin (via a limiting resistor). + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), the LED will be off initially. If + :data:`None`, the LED will be left in whatever state the pin is found + in when configured for output (warning: this can be on). If + :data:`True`, the LED will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + pass + +LED.is_lit = LED.is_active + + +class Buzzer(DigitalOutputDevice): + """ + Extends :class:`DigitalOutputDevice` and represents a digital buzzer + component. + + .. note:: + + This interface is only capable of simple on/off commands, and is not + capable of playing a variety of tones (see :class:`TonalBuzzer`). + + Connect the cathode (negative pin) of the buzzer to a ground pin; connect + the other side to any GPIO pin. + + The following example will sound the buzzer:: + + from gpiozero import Buzzer + + bz = Buzzer(3) + bz.on() + + :type pin: int or str + :param pin: + The GPIO pin which the buzzer is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the buzzer will operate normally with + the circuit described above. If :data:`False` you should wire the + cathode to the GPIO pin, and the anode to a 3V3 pin. + + :type initial_value: bool or None + :param initial_value: + If :data:`False` (the default), the buzzer will be silent initially. If + :data:`None`, the buzzer will be left in whatever state the pin is + found in when configured for output (warning: this can be on). If + :data:`True`, the buzzer will be switched on initially. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + pass + +Buzzer.beep = Buzzer.blink + + +class PWMOutputDevice(OutputDevice): + """ + Generic output device configured for pulse-width modulation (PWM). + + :type pin: int or str + :param pin: + The GPIO pin that the device is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set the GPIO + to HIGH. If :data:`False`, the :meth:`on` method will set the GPIO to + LOW (the :meth:`off` method always does the opposite). + + :param float initial_value: + If 0 (the default), the device's duty cycle will be 0 initially. + Other values between 0 and 1 can be specified as an initial duty cycle. + Note that :data:`None` cannot be specified (unlike the parent class) as + there is no way to tell PWM not to alter the state of the pin. + + :param int frequency: + The frequency (in Hz) of pulses emitted to drive the device. Defaults + to 100Hz. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, active_high=True, initial_value=0, frequency=100, + pin_factory=None): + self._blink_thread = None + self._controller = None + if not 0 <= initial_value <= 1: + raise OutputDeviceBadValue("initial_value must be between 0 and 1") + super(PWMOutputDevice, self).__init__( + pin, active_high, initial_value=None, pin_factory=pin_factory + ) + try: + # XXX need a way of setting these together + self.pin.frequency = frequency + self.value = initial_value + except: + self.close() + raise + + def close(self): + try: + self._stop_blink() + except AttributeError: + pass + try: + self.pin.frequency = None + except AttributeError: + # If the pin's already None, ignore the exception + pass + super(PWMOutputDevice, self).close() + + def _state_to_value(self, state): + return float(state if self.active_high else 1 - state) + + def _value_to_state(self, value): + return float(value if self.active_high else 1 - value) + + def _write(self, value): + if not 0 <= value <= 1: + raise OutputDeviceBadValue("PWM value must be between 0 and 1") + super(PWMOutputDevice, self)._write(value) + + @property + def value(self): + """ + The duty cycle of the PWM device. 0.0 is off, 1.0 is fully on. Values + in between may be specified for varying levels of power in the device. + """ + return super(PWMOutputDevice, self).value + + @value.setter + def value(self, value): + self._stop_blink() + self._write(value) + + def on(self): + self._stop_blink() + self._write(1) + + def off(self): + self._stop_blink() + self._write(0) + + def toggle(self): + """ + Toggle the state of the device. If the device is currently off + (:attr:`value` is 0.0), this changes it to "fully" on (:attr:`value` is + 1.0). If the device has a duty cycle (:attr:`value`) of 0.1, this will + toggle it to 0.9, and so on. + """ + self._stop_blink() + self.value = 1 - self.value + + @property + def is_active(self): + """ + Returns :data:`True` if the device is currently active (:attr:`value` + is non-zero) and :data:`False` otherwise. + """ + return self.value != 0 + + @property + def frequency(self): + """ + The frequency of the pulses used with the PWM device, in Hz. The + default is 100Hz. + """ + return self.pin.frequency + + @frequency.setter + def frequency(self, value): + self.pin.frequency = value + + def blink( + self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0, + n=None, background=True): + """ + Make the device turn on and off repeatedly. + + :param float on_time: + Number of seconds on. Defaults to 1 second. + + :param float off_time: + Number of seconds off. Defaults to 1 second. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 0. + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 0. + + :type n: int or None + :param n: + Number of times to blink; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue blinking and return immediately. If :data:`False`, only + return when the blink is finished (warning: the default value of + *n* will result in this method never returning). + """ + self._stop_blink() + self._blink_thread = GPIOThread( + self._blink_device, + (on_time, off_time, fade_in_time, fade_out_time, n) + ) + self._blink_thread.start() + if not background: + self._blink_thread.join() + self._blink_thread = None + + def pulse(self, fade_in_time=1, fade_out_time=1, n=None, background=True): + """ + Make the device fade in and out repeatedly. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 1. + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 1. + + :type n: int or None + :param n: + Number of times to pulse; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue pulsing and return immediately. If :data:`False`, only + return when the pulse is finished (warning: the default value of + *n* will result in this method never returning). + """ + on_time = off_time = 0 + self.blink( + on_time, off_time, fade_in_time, fade_out_time, n, background + ) + + def _stop_blink(self): + if self._controller: + self._controller._stop_blink(self) + self._controller = None + if self._blink_thread: + self._blink_thread.stop() + self._blink_thread = None + + def _blink_device( + self, on_time, off_time, fade_in_time, fade_out_time, n, fps=25): + sequence = [] + if fade_in_time > 0: + sequence += [ + (i * (1 / fps) / fade_in_time, 1 / fps) + for i in range(int(fps * fade_in_time)) + ] + sequence.append((1, on_time)) + if fade_out_time > 0: + sequence += [ + (1 - (i * (1 / fps) / fade_out_time), 1 / fps) + for i in range(int(fps * fade_out_time)) + ] + sequence.append((0, off_time)) + sequence = ( + cycle(sequence) if n is None else + chain.from_iterable(repeat(sequence, n)) + ) + for value, delay in sequence: + self._write(value) + if self._blink_thread.stopping.wait(delay): + break + + +class TonalBuzzer(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` and represents a tonal buzzer. + + :type pin: int or str + :param pin: + The GPIO pin which the buzzer is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param float initial_value: + If :data:`None` (the default), the buzzer will be off initially. Values + between -1 and 1 can be specified as an initial value for the buzzer. + + :type mid_tone: int or str + :param mid_tone: + The tone which is represented the device's middle value (0). The + default is "A4" (MIDI note 69). + + :param int octaves: + The number of octaves to allow away from the base note. The default is + 1, meaning a value of -1 goes one octave below the base note, and one + above, i.e. from A3 to A5 with the default base note of A4. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. note:: + + Note that this class does not currently work with + :class:`~gpiozero.pins.pigpio.PiGPIOFactory`. + """ + + def __init__(self, pin=None, initial_value=None, mid_tone=Tone("A4"), + octaves=1, pin_factory=None): + self._mid_tone = None + super(TonalBuzzer, self).__init__( + pwm_device=PWMOutputDevice( + pin=pin, pin_factory=pin_factory + ), pin_factory=pin_factory) + try: + self._mid_tone = Tone(mid_tone) + if not (0 < octaves <= 9): + raise ValueError('octaves must be between 1 and 9') + self._octaves = octaves + try: + self.min_tone.note + except ValueError: + raise ValueError( + '%r is too low for %d octaves' % + (self._mid_tone, self._octaves)) + try: + self.max_tone.note + except ValueError: + raise ValueError( + '%r is too high for %d octaves' % + (self._mid_tone, self._octaves)) + self.value = initial_value + except: + self.close() + raise + + def __repr__(self): + try: + self._check_open() + if self.value is None: + return '' % ( + self.pwm_device.pin,) + else: + return '' % ( + self.pwm_device.pin, self.tone.note) + except DeviceClosed: + return super(TonalBuzzer, self).__repr__() + + def play(self, tone): + """ + Play the given *tone*. This can either be an instance of + :class:`~gpiozero.tones.Tone` or can be anything that could be used to + construct an instance of :class:`~gpiozero.tones.Tone`. + + For example:: + + >>> from gpiozero import TonalBuzzer + >>> from gpiozero.tones import Tone + >>> b = TonalBuzzer(17) + >>> b.play(Tone("A4")) + >>> b.play(Tone(220.0)) # Hz + >>> b.play(Tone(60)) # middle C in MIDI notation + >>> b.play("A4") + >>> b.play(220.0) + >>> b.play(60) + """ + if tone is None: + self.value = None + else: + if not isinstance(tone, Tone): + tone = Tone(tone) + freq = tone.frequency + if self.min_tone.frequency <= tone <= self.max_tone.frequency: + self.pwm_device.pin.frequency = freq + self.pwm_device.value = 0.5 + else: + raise ValueError("tone is out of the device's range") + + def stop(self): + """ + Turn the buzzer off. This is equivalent to setting :attr:`value` to + :data:`None`. + """ + self.value = None + + @property + def tone(self): + """ + Returns the :class:`~gpiozero.tones.Tone` that the buzzer is currently + playing, or :data:`None` if the buzzer is silent. This property can + also be set to play the specified tone. + """ + if self.pwm_device.pin.frequency is None: + return None + else: + return Tone.from_frequency(self.pwm_device.pin.frequency) + + @tone.setter + def tone(self, value): + self.play(value) + + @property + def value(self): + """ + Represents the state of the buzzer as a value between -1 (representing + the minimum tone) and 1 (representing the maximum tone). This can also + be the special value :data:`None` indicating that the buzzer is + currently silent. + """ + if self.pwm_device.pin.frequency is None: + return None + else: + # Can't have zero-division here; zero-frequency Tone cannot be + # generated and self.octaves cannot be zero either + return log2( + self.pwm_device.pin.frequency / self.mid_tone.frequency + ) / self.octaves + + @value.setter + def value(self, value): + if value is None: + self.pwm_device.pin.frequency = None + elif -1 <= value <= 1: + freq = self.mid_tone.frequency * 2 ** (self.octaves * value) + self.pwm_device.pin.frequency = freq + self.pwm_device.value = 0.5 + else: + raise OutputDeviceBadValue( + 'TonalBuzzer value must be between -1 and 1, or None') + + @property + def is_active(self): + """ + Returns :data:`True` if the buzzer is currently playing, otherwise + :data:`False`. + """ + return self.value is not None + + @property + def octaves(self): + """ + The number of octaves available (above and below mid_tone). + """ + return self._octaves + + @property + def min_tone(self): + """ + The lowest tone that the buzzer can play, i.e. the tone played + when :attr:`value` is -1. + """ + return self._mid_tone.down(12 * self.octaves) + + @property + def mid_tone(self): + """ + The middle tone available, i.e. the tone played when :attr:`value` is + 0. + """ + return self._mid_tone + + @property + def max_tone(self): + """ + The highest tone that the buzzer can play, i.e. the tone played when + :attr:`value` is 1. + """ + return self._mid_tone.up(12 * self.octaves) + + +class PWMLED(PWMOutputDevice): + """ + Extends :class:`PWMOutputDevice` and represents a light emitting diode + (LED) with variable brightness. + + A typical configuration of such a device is to connect a GPIO pin to the + anode (long leg) of the LED, and the cathode (short leg) to ground, with + an optional resistor to prevent the LED from burning out. + + :type pin: int or str + :param pin: + The GPIO pin which the LED is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param bool active_high: + If :data:`True` (the default), the :meth:`on` method will set the GPIO + to HIGH. If :data:`False`, the :meth:`on` method will set the GPIO to + LOW (the :meth:`off` method always does the opposite). + + :param float initial_value: + If ``0`` (the default), the LED will be off initially. Other values + between 0 and 1 can be specified as an initial brightness for the LED. + Note that :data:`None` cannot be specified (unlike the parent class) as + there is no way to tell PWM not to alter the state of the pin. + + :param int frequency: + The frequency (in Hz) of pulses emitted to drive the LED. Defaults + to 100Hz. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + pass + +PWMLED.is_lit = PWMLED.is_active + + +class RGBLED(SourceMixin, Device): + """ + Extends :class:`Device` and represents a full color LED component (composed + of red, green, and blue LEDs). + + Connect the common cathode (longest leg) to a ground pin; connect each of + the other legs (representing the red, green, and blue anodes) to any GPIO + pins. You should use three limiting resistors (one per anode). + + The following code will make the LED yellow:: + + from gpiozero import RGBLED + + led = RGBLED(2, 3, 4) + led.color = (1, 1, 0) + + The `colorzero`_ library is also supported:: + + from gpiozero import RGBLED + from colorzero import Color + + led = RGBLED(2, 3, 4) + led.color = Color('yellow') + + :type red: int or str + :param red: + The GPIO pin that controls the red component of the RGB LED. See + :ref:`pin-numbering` for valid pin numbers. If this is :data:`None` a + :exc:`GPIODeviceError` will be raised. + + :type green: int or str + :param green: + The GPIO pin that controls the green component of the RGB LED. + + :type blue: int or str + :param blue: + The GPIO pin that controls the blue component of the RGB LED. + + :param bool active_high: + Set to :data:`True` (the default) for common cathode RGB LEDs. If you + are using a common anode RGB LED, set this to :data:`False`. + + :type initial_value: ~colorzero.Color or tuple + :param initial_value: + The initial color for the RGB LED. Defaults to black ``(0, 0, 0)``. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMLED` instances for + each component of the RGBLED. If :data:`False`, construct regular + :class:`LED` instances, which prevents smooth color graduations. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + + .. _colorzero: https://colorzero.readthedocs.io/ + """ + def __init__( + self, red=None, green=None, blue=None, active_high=True, + initial_value=(0, 0, 0), pwm=True, pin_factory=None): + self._leds = () + self._blink_thread = None + if not all(p is not None for p in [red, green, blue]): + raise GPIOPinMissing('red, green, and blue pins must be provided') + LEDClass = PWMLED if pwm else LED + super(RGBLED, self).__init__(pin_factory=pin_factory) + self._leds = tuple( + LEDClass(pin, active_high, pin_factory=pin_factory) + for pin in (red, green, blue) + ) + self.value = initial_value + + def close(self): + if getattr(self, '_leds', None): + self._stop_blink() + for led in self._leds: + led.close() + self._leds = () + super(RGBLED, self).close() + + @property + def closed(self): + return len(self._leds) == 0 + + @property + def value(self): + """ + Represents the color of the LED as an RGB 3-tuple of ``(red, green, + blue)`` where each value is between 0 and 1 if *pwm* was :data:`True` + when the class was constructed (and only 0 or 1 if not). + + For example, red would be ``(1, 0, 0)`` and yellow would be ``(1, 1, + 0)``, while orange would be ``(1, 0.5, 0)``. + """ + return tuple(led.value for led in self._leds) + + @value.setter + def value(self, value): + for component in value: + if not 0 <= component <= 1: + raise OutputDeviceBadValue( + 'each RGB color component must be between 0 and 1') + if isinstance(self._leds[0], LED): + if component not in (0, 1): + raise OutputDeviceBadValue( + 'each RGB color component must be 0 or 1 with non-PWM ' + 'RGBLEDs') + self._stop_blink() + for led, v in zip(self._leds, value): + led.value = v + + @property + def is_active(self): + """ + Returns :data:`True` if the LED is currently active (not black) and + :data:`False` otherwise. + """ + return self.value != (0, 0, 0) + + is_lit = is_active + + @property + def color(self): + """ + Represents the color of the LED as a :class:`~colorzero.Color` object. + """ + return Color(*self.value) + + @color.setter + def color(self, value): + self.value = value + + @property + def red(self): + """ + Represents the red element of the LED as a :class:`~colorzero.Red` + object. + """ + return self.color.red + + @red.setter + def red(self, value): + self._stop_blink() + r, g, b = self.value + self.value = value, g, b + + @property + def green(self): + """ + Represents the green element of the LED as a :class:`~colorzero.Green` + object. + """ + return self.color.green + + @green.setter + def green(self, value): + self._stop_blink() + r, g, b = self.value + self.value = r, value, b + + @property + def blue(self): + """ + Represents the blue element of the LED as a :class:`~colorzero.Blue` + object. + """ + return self.color.blue + + @blue.setter + def blue(self, value): + self._stop_blink() + r, g, b = self.value + self.value = r, g, value + + def on(self): + """ + Turn the LED on. This equivalent to setting the LED color to white + ``(1, 1, 1)``. + """ + self.value = (1, 1, 1) + + def off(self): + """ + Turn the LED off. This is equivalent to setting the LED color to black + ``(0, 0, 0)``. + """ + self.value = (0, 0, 0) + + def toggle(self): + """ + Toggle the state of the device. If the device is currently off + (:attr:`value` is ``(0, 0, 0)``), this changes it to "fully" on + (:attr:`value` is ``(1, 1, 1)``). If the device has a specific color, + this method inverts the color. + """ + r, g, b = self.value + self.value = (1 - r, 1 - g, 1 - b) + + def blink( + self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0, + on_color=(1, 1, 1), off_color=(0, 0, 0), n=None, background=True): + """ + Make the device turn on and off repeatedly. + + :param float on_time: + Number of seconds on. Defaults to 1 second. + + :param float off_time: + Number of seconds off. Defaults to 1 second. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 0. Must be 0 if + *pwm* was :data:`False` when the class was constructed + (:exc:`ValueError` will be raised if not). + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 0. Must be 0 if + *pwm* was :data:`False` when the class was constructed + (:exc:`ValueError` will be raised if not). + + :type on_color: ~colorzero.Color or tuple + :param on_color: + The color to use when the LED is "on". Defaults to white. + + :type off_color: ~colorzero.Color or tuple + :param off_color: + The color to use when the LED is "off". Defaults to black. + + :type n: int or None + :param n: + Number of times to blink; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue blinking and return immediately. If :data:`False`, only + return when the blink is finished (warning: the default value of + *n* will result in this method never returning). + """ + if isinstance(self._leds[0], LED): + if fade_in_time: + raise ValueError('fade_in_time must be 0 with non-PWM RGBLEDs') + if fade_out_time: + raise ValueError('fade_out_time must be 0 with non-PWM RGBLEDs') + self._stop_blink() + self._blink_thread = GPIOThread( + self._blink_device, + ( + on_time, off_time, fade_in_time, fade_out_time, + on_color, off_color, n + ) + ) + self._blink_thread.start() + if not background: + self._blink_thread.join() + self._blink_thread = None + + def pulse( + self, fade_in_time=1, fade_out_time=1, + on_color=(1, 1, 1), off_color=(0, 0, 0), n=None, background=True): + """ + Make the device fade in and out repeatedly. + + :param float fade_in_time: + Number of seconds to spend fading in. Defaults to 1. + + :param float fade_out_time: + Number of seconds to spend fading out. Defaults to 1. + + :type on_color: ~colorzero.Color or tuple + :param on_color: + The color to use when the LED is "on". Defaults to white. + + :type off_color: ~colorzero.Color or tuple + :param off_color: + The color to use when the LED is "off". Defaults to black. + + :type n: int or None + :param n: + Number of times to pulse; :data:`None` (the default) means forever. + + :param bool background: + If :data:`True` (the default), start a background thread to + continue pulsing and return immediately. If :data:`False`, only + return when the pulse is finished (warning: the default value of + *n* will result in this method never returning). + """ + on_time = off_time = 0 + self.blink( + on_time, off_time, fade_in_time, fade_out_time, + on_color, off_color, n, background + ) + + def _stop_blink(self, led=None): + # If this is called with a single led, we stop all blinking anyway + if self._blink_thread: + self._blink_thread.stop() + self._blink_thread = None + + def _blink_device( + self, on_time, off_time, fade_in_time, fade_out_time, on_color, + off_color, n, fps=25): + # Define a simple lambda to perform linear interpolation between + # off_color and on_color + lerp = lambda t, fade_in: tuple( + (1 - t) * off + t * on + if fade_in else + (1 - t) * on + t * off + for off, on in zip(off_color, on_color) + ) + sequence = [] + if fade_in_time > 0: + sequence += [ + (lerp(i * (1 / fps) / fade_in_time, True), 1 / fps) + for i in range(int(fps * fade_in_time)) + ] + sequence.append((on_color, on_time)) + if fade_out_time > 0: + sequence += [ + (lerp(i * (1 / fps) / fade_out_time, False), 1 / fps) + for i in range(int(fps * fade_out_time)) + ] + sequence.append((off_color, off_time)) + sequence = ( + cycle(sequence) if n is None else + chain.from_iterable(repeat(sequence, n)) + ) + for l in self._leds: + l._controller = self + for value, delay in sequence: + for l, v in zip(self._leds, value): + l._write(v) + if self._blink_thread.stopping.wait(delay): + break + + +class Motor(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` and represents a generic motor + connected to a bi-directional motor driver circuit (i.e. an `H-bridge`_). + + Attach an `H-bridge`_ motor controller to your Pi; connect a power source + (e.g. a battery pack or the 5V pin) to the controller; connect the outputs + of the controller board to the two terminals of the motor; connect the + inputs of the controller board to two GPIO pins. + + .. _H-bridge: https://en.wikipedia.org/wiki/H_bridge + + The following code will make the motor turn "forwards":: + + from gpiozero import Motor + + motor = Motor(17, 18) + motor.forward() + + :type forward: int or str + :param forward: + The GPIO pin that the forward input of the motor driver chip is + connected to. See :ref:`pin-numbering` for valid pin numbers. If this + is :data:`None` a :exc:`GPIODeviceError` will be raised. + + :type backward: int or str + :param backward: + The GPIO pin that the backward input of the motor driver chip is + connected to. See :ref:`pin-numbering` for valid pin numbers. If this + is :data:`None` a :exc:`GPIODeviceError` will be raised. + + :type enable: int or str or None + :param enable: + The GPIO pin that enables the motor. Required for *some* motor + controller boards. See :ref:`pin-numbering` for valid pin numbers. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller pins, allowing both direction and + variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, forward=None, backward=None, enable=None, pwm=True, + pin_factory=None): + if not all(p is not None for p in [forward, backward]): + raise GPIOPinMissing( + 'forward and backward pins must be provided' + ) + PinClass = PWMOutputDevice if pwm else DigitalOutputDevice + devices = OrderedDict(( + ('forward_device', PinClass(forward, pin_factory=pin_factory)), + ('backward_device', PinClass(backward, pin_factory=pin_factory)), + )) + if enable is not None: + devices['enable_device'] = DigitalOutputDevice( + enable, + initial_value=True, + pin_factory=pin_factory + ) + super(Motor, self).__init__(_order=devices.keys(), **devices) + + @property + def value(self): + """ + Represents the speed of the motor as a floating point value between -1 + (full speed backward) and 1 (full speed forward), with 0 representing + stopped. + """ + return self.forward_device.value - self.backward_device.value + + @value.setter + def value(self, value): + if not -1 <= value <= 1: + raise OutputDeviceBadValue("Motor value must be between -1 and 1") + if value > 0: + try: + self.forward(value) + except ValueError as e: + raise OutputDeviceBadValue(e) + elif value < 0: + try: + self.backward(-value) + except ValueError as e: + raise OutputDeviceBadValue(e) + else: + self.stop() + + @property + def is_active(self): + """ + Returns :data:`True` if the motor is currently running and + :data:`False` otherwise. + """ + return self.value != 0 + + def forward(self, speed=1): + """ + Drive the motor forwards. + + :param float speed: + The speed at which the motor should turn. Can be any value between + 0 (stopped) and the default 1 (maximum speed) if *pwm* was + :data:`True` when the class was constructed (and only 0 or 1 if + not). + """ + if not 0 <= speed <= 1: + raise ValueError('forward speed must be between 0 and 1') + if isinstance(self.forward_device, DigitalOutputDevice): + if speed not in (0, 1): + raise ValueError( + 'forward speed must be 0 or 1 with non-PWM Motors') + self.backward_device.off() + self.forward_device.value = speed + + def backward(self, speed=1): + """ + Drive the motor backwards. + + :param float speed: + The speed at which the motor should turn. Can be any value between + 0 (stopped) and the default 1 (maximum speed) if *pwm* was + :data:`True` when the class was constructed (and only 0 or 1 if + not). + """ + if not 0 <= speed <= 1: + raise ValueError('backward speed must be between 0 and 1') + if isinstance(self.backward_device, DigitalOutputDevice): + if speed not in (0, 1): + raise ValueError( + 'backward speed must be 0 or 1 with non-PWM Motors') + self.forward_device.off() + self.backward_device.value = speed + + def reverse(self): + """ + Reverse the current direction of the motor. If the motor is currently + idle this does nothing. Otherwise, the motor's direction will be + reversed at the current speed. + """ + self.value = -self.value + + def stop(self): + """ + Stop the motor. + """ + self.forward_device.off() + self.backward_device.off() + + +class PhaseEnableMotor(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` and represents a generic motor connected + to a Phase/Enable motor driver circuit; the phase of the driver controls + whether the motor turns forwards or backwards, while enable controls the + speed with PWM. + + The following code will make the motor turn "forwards":: + + from gpiozero import PhaseEnableMotor + motor = PhaseEnableMotor(12, 5) + motor.forward() + + :type phase: int or str + :param phase: + The GPIO pin that the phase (direction) input of the motor driver chip + is connected to. See :ref:`pin-numbering` for valid pin numbers. If + this is :data:`None` a :exc:`GPIODeviceError` will be raised. + + :type enable: int or str + :param enable: + The GPIO pin that the enable (speed) input of the motor driver chip + is connected to. See :ref:`pin-numbering` for valid pin numbers. If + this is :data:`None` a :exc:`GPIODeviceError` will be raised. + + :param bool pwm: + If :data:`True` (the default), construct :class:`PWMOutputDevice` + instances for the motor controller pins, allowing both direction and + variable speed control. If :data:`False`, construct + :class:`DigitalOutputDevice` instances, allowing only direction + control. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__(self, phase=None, enable=None, pwm=True, pin_factory=None): + if not all([phase, enable]): + raise GPIOPinMissing('phase and enable pins must be provided') + PinClass = PWMOutputDevice if pwm else DigitalOutputDevice + super(PhaseEnableMotor, self).__init__( + phase_device=DigitalOutputDevice(phase, pin_factory=pin_factory), + enable_device=PinClass(enable, pin_factory=pin_factory), + _order=('phase_device', 'enable_device'), + pin_factory=pin_factory + ) + + @property + def value(self): + """ + Represents the speed of the motor as a floating point value between -1 + (full speed backward) and 1 (full speed forward). + """ + return ( + -self.enable_device.value + if self.phase_device.is_active else + self.enable_device.value + ) + + @value.setter + def value(self, value): + if not -1 <= value <= 1: + raise OutputDeviceBadValue("Motor value must be between -1 and 1") + if value > 0: + self.forward(value) + elif value < 0: + self.backward(-value) + else: + self.stop() + + @property + def is_active(self): + """ + Returns :data:`True` if the motor is currently running and + :data:`False` otherwise. + """ + return self.value != 0 + + def forward(self, speed=1): + """ + Drive the motor forwards. + + :param float speed: + The speed at which the motor should turn. Can be any value between + 0 (stopped) and the default 1 (maximum speed). + """ + if isinstance(self.enable_device, DigitalOutputDevice): + if speed not in (0, 1): + raise ValueError( + 'forward speed must be 0 or 1 with non-PWM Motors') + self.enable_device.off() + self.phase_device.off() + self.enable_device.value = speed + + def backward(self, speed=1): + """ + Drive the motor backwards. + + :param float speed: + The speed at which the motor should turn. Can be any value between + 0 (stopped) and the default 1 (maximum speed). + """ + if isinstance(self.enable_device, DigitalOutputDevice): + if speed not in (0, 1): + raise ValueError( + 'backward speed must be 0 or 1 with non-PWM Motors') + self.enable_device.off() + self.phase_device.on() + self.enable_device.value = speed + + def reverse(self): + """ + Reverse the current direction of the motor. If the motor is currently + idle this does nothing. Otherwise, the motor's direction will be + reversed at the current speed. + """ + self.value = -self.value + + def stop(self): + """ + Stop the motor. + """ + self.enable_device.off() + + +class Servo(SourceMixin, CompositeDevice): + """ + Extends :class:`CompositeDevice` and represents a PWM-controlled servo + motor connected to a GPIO pin. + + Connect a power source (e.g. a battery pack or the 5V pin) to the power + cable of the servo (this is typically colored red); connect the ground + cable of the servo (typically colored black or brown) to the negative of + your battery pack, or a GND pin; connect the final cable (typically colored + white or orange) to the GPIO pin you wish to use for controlling the servo. + + The following code will make the servo move between its minimum, maximum, + and mid-point positions with a pause between each:: + + from gpiozero import Servo + from time import sleep + + servo = Servo(17) + + while True: + servo.min() + sleep(1) + servo.mid() + sleep(1) + servo.max() + sleep(1) + + You can also use the :attr:`value` property to move the servo to a + particular position, on a scale from -1 (min) to 1 (max) where 0 is the + mid-point:: + + from gpiozero import Servo + + servo = Servo(17) + + servo.value = 0.5 + + .. note:: + + To reduce servo jitter, use the pigpio pin driver rather than the default + RPi.GPIO driver (pigpio uses DMA sampling for much more precise edge + timing). See :ref:`changing-pin-factory` for further information. + + :type pin: int or str + :param pin: + The GPIO pin that the servo is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param float initial_value: + If ``0`` (the default), the device's mid-point will be set initially. + Other values between -1 and +1 can be specified as an initial position. + :data:`None` means to start the servo un-controlled (see + :attr:`value`). + + :param float min_pulse_width: + The pulse width corresponding to the servo's minimum position. This + defaults to 1ms. + + :param float max_pulse_width: + The pulse width corresponding to the servo's maximum position. This + defaults to 2ms. + + :param float frame_width: + The length of time between servo control pulses measured in seconds. + This defaults to 20ms which is a common value for servos. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, initial_value=0.0, + min_pulse_width=1/1000, max_pulse_width=2/1000, + frame_width=20/1000, pin_factory=None): + if min_pulse_width >= max_pulse_width: + raise ValueError('min_pulse_width must be less than max_pulse_width') + if max_pulse_width >= frame_width: + raise ValueError('max_pulse_width must be less than frame_width') + self._frame_width = frame_width + self._min_dc = min_pulse_width / frame_width + self._dc_range = (max_pulse_width - min_pulse_width) / frame_width + self._min_value = -1 + self._value_range = 2 + super(Servo, self).__init__( + pwm_device=PWMOutputDevice( + pin, frequency=int(1 / frame_width), pin_factory=pin_factory + ), + pin_factory=pin_factory + ) + + if PiGPIOFactory is None or not isinstance(self.pin_factory, PiGPIOFactory): + warnings.warn(PWMSoftwareFallback( + 'To reduce servo jitter, use the pigpio pin factory.' + 'See https://gpiozero.readthedocs.io/en/stable/api_output.html#servo for more info' + )) + + try: + self.value = initial_value + except: + self.close() + raise + + @property + def frame_width(self): + """ + The time between control pulses, measured in seconds. + """ + return self._frame_width + + @property + def min_pulse_width(self): + """ + The control pulse width corresponding to the servo's minimum position, + measured in seconds. + """ + return self._min_dc * self.frame_width + + @property + def max_pulse_width(self): + """ + The control pulse width corresponding to the servo's maximum position, + measured in seconds. + """ + return (self._dc_range * self.frame_width) + self.min_pulse_width + + @property + def pulse_width(self): + """ + Returns the current pulse width controlling the servo. + """ + if self.pwm_device.pin.frequency is None: + return None + else: + return self.pwm_device.pin.state * self.frame_width + + @pulse_width.setter + def pulse_width(self, value): + self.pwm_device.pin.state = value / self.frame_width + + def min(self): + """ + Set the servo to its minimum position. + """ + self.value = -1 + + def mid(self): + """ + Set the servo to its mid-point position. + """ + self.value = 0 + + def max(self): + """ + Set the servo to its maximum position. + """ + self.value = 1 + + def detach(self): + """ + Temporarily disable control of the servo. This is equivalent to + setting :attr:`value` to :data:`None`. + """ + self.value = None + + def _get_value(self): + if self.pwm_device.pin.frequency is None: + return None + else: + return ( + ((self.pwm_device.pin.state - self._min_dc) / self._dc_range) * + self._value_range + self._min_value) + + @property + def value(self): + """ + Represents the position of the servo as a value between -1 (the minimum + position) and +1 (the maximum position). This can also be the special + value :data:`None` indicating that the servo is currently + "uncontrolled", i.e. that no control signal is being sent. Typically + this means the servo's position remains unchanged, but that it can be + moved by hand. + """ + result = self._get_value() + if result is None: + return result + else: + # NOTE: This round() only exists to ensure we don't confuse people + # by returning 2.220446049250313e-16 as the default initial value + # instead of 0. The reason _get_value and _set_value are split + # out is for descendents that require the un-rounded values for + # accuracy + return round(result, 14) + + @value.setter + def value(self, value): + if value is None: + self.pwm_device.pin.frequency = None + elif -1 <= value <= 1: + self.pwm_device.pin.frequency = int(1 / self.frame_width) + self.pwm_device.pin.state = ( + self._min_dc + self._dc_range * + ((value - self._min_value) / self._value_range) + ) + else: + raise OutputDeviceBadValue( + "Servo value must be between -1 and 1, or None") + + @property + def is_active(self): + return self.value is not None + + +class AngularServo(Servo): + """ + Extends :class:`Servo` and represents a rotational PWM-controlled servo + motor which can be set to particular angles (assuming valid minimum and + maximum angles are provided to the constructor). + + Connect a power source (e.g. a battery pack or the 5V pin) to the power + cable of the servo (this is typically colored red); connect the ground + cable of the servo (typically colored black or brown) to the negative of + your battery pack, or a GND pin; connect the final cable (typically colored + white or orange) to the GPIO pin you wish to use for controlling the servo. + + Next, calibrate the angles that the servo can rotate to. In an interactive + Python session, construct a :class:`Servo` instance. The servo should move + to its mid-point by default. Set the servo to its minimum value, and + measure the angle from the mid-point. Set the servo to its maximum value, + and again measure the angle:: + + >>> from gpiozero import Servo + >>> s = Servo(17) + >>> s.min() # measure the angle + >>> s.max() # measure the angle + + You should now be able to construct an :class:`AngularServo` instance + with the correct bounds:: + + >>> from gpiozero import AngularServo + >>> s = AngularServo(17, min_angle=-42, max_angle=44) + >>> s.angle = 0.0 + >>> s.angle + 0.0 + >>> s.angle = 15 + >>> s.angle + 15.0 + + .. note:: + + You can set *min_angle* greater than *max_angle* if you wish to reverse + the sense of the angles (e.g. ``min_angle=45, max_angle=-45``). This + can be useful with servos that rotate in the opposite direction to your + expectations of minimum and maximum. + + :type pin: int or str + :param pin: + The GPIO pin that the servo is connected to. See :ref:`pin-numbering` + for valid pin numbers. If this is :data:`None` a :exc:`GPIODeviceError` + will be raised. + + :param float initial_angle: + Sets the servo's initial angle to the specified value. The default is + 0. The value specified must be between *min_angle* and *max_angle* + inclusive. :data:`None` means to start the servo un-controlled (see + :attr:`value`). + + :param float min_angle: + Sets the minimum angle that the servo can rotate to. This defaults to + -90, but should be set to whatever you measure from your servo during + calibration. + + :param float max_angle: + Sets the maximum angle that the servo can rotate to. This defaults to + 90, but should be set to whatever you measure from your servo during + calibration. + + :param float min_pulse_width: + The pulse width corresponding to the servo's minimum position. This + defaults to 1ms. + + :param float max_pulse_width: + The pulse width corresponding to the servo's maximum position. This + defaults to 2ms. + + :param float frame_width: + The length of time between servo control pulses measured in seconds. + This defaults to 20ms which is a common value for servos. + + :type pin_factory: Factory or None + :param pin_factory: + See :doc:`api_pins` for more information (this is an advanced feature + which most users can ignore). + """ + def __init__( + self, pin=None, initial_angle=0.0, + min_angle=-90, max_angle=90, + min_pulse_width=1/1000, max_pulse_width=2/1000, + frame_width=20/1000, pin_factory=None): + self._min_angle = min_angle + self._angular_range = max_angle - min_angle + if initial_angle is None: + initial_value = None + elif ((min_angle <= initial_angle <= max_angle) or + (max_angle <= initial_angle <= min_angle)): + initial_value = 2 * ((initial_angle - min_angle) / self._angular_range) - 1 + else: + raise OutputDeviceBadValue( + "AngularServo angle must be between %s and %s, or None" % + (min_angle, max_angle)) + super(AngularServo, self).__init__( + pin, initial_value, min_pulse_width, max_pulse_width, frame_width, + pin_factory=pin_factory + ) + + @property + def min_angle(self): + """ + The minimum angle that the servo will rotate to when :meth:`min` is + called. + """ + return self._min_angle + + @property + def max_angle(self): + """ + The maximum angle that the servo will rotate to when :meth:`max` is + called. + """ + return self._min_angle + self._angular_range + + @property + def angle(self): + """ + The position of the servo as an angle measured in degrees. This will + only be accurate if :attr:`min_angle` and :attr:`max_angle` have been + set appropriately in the constructor. + + This can also be the special value :data:`None` indicating that the + servo is currently "uncontrolled", i.e. that no control signal is being + sent. Typically this means the servo's position remains unchanged, but + that it can be moved by hand. + """ + result = self._get_value() + if result is None: + return None + else: + # NOTE: Why round(n, 12) here instead of 14? Angle ranges can be + # much larger than -1..1 so we need a little more rounding to + # smooth off the rough corners! + return round( + self._angular_range * + ((result - self._min_value) / self._value_range) + + self._min_angle, 12) + + @angle.setter + def angle(self, angle): + if angle is None: + self.value = None + elif ((self.min_angle <= angle <= self.max_angle) or + (self.max_angle <= angle <= self.min_angle)): + self.value = ( + self._value_range * + ((angle - self._min_angle) / self._angular_range) + + self._min_value) + else: + raise OutputDeviceBadValue( + "AngularServo angle must be between %s and %s, or None" % + (self.min_angle, self.max_angle)) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__init__.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/__init__.py new file mode 100644 index 0000000..8a68c25 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/__init__.py @@ -0,0 +1,777 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2018 Rick Ansell +# Copyright (c) 2018 Mike Kazantsev +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +from weakref import ref +from collections import defaultdict +from threading import Lock + +from ..devices import Device +from ..exc import ( + PinInvalidFunction, + PinSetInput, + PinFixedPull, + PinUnsupported, + PinSPIUnsupported, + PinPWMUnsupported, + PinEdgeDetectUnsupported, + SPIFixedClockMode, + SPIFixedBitOrder, + SPIFixedSelect, + SPIFixedWordSize, + SPIFixedRate, + GPIOPinInUse, + ) + + +class Factory(object): + """ + Generates pins and SPI interfaces for devices. This is an abstract + base class for pin factories. Descendents *must* override the following + methods: + + * :meth:`ticks` + * :meth:`ticks_diff` + + Descendents *may* override the following methods, if applicable: + + * :meth:`close` + * :meth:`reserve_pins` + * :meth:`release_pins` + * :meth:`release_all` + * :meth:`pin` + * :meth:`spi` + * :meth:`_get_pi_info` + """ + def __init__(self): + self._reservations = defaultdict(list) + self._res_lock = Lock() + + def reserve_pins(self, requester, *pins): + """ + Called to indicate that the device reserves the right to use the + specified *pins*. This should be done during device construction. If + pins are reserved, you must ensure that the reservation is released by + eventually called :meth:`release_pins`. + """ + with self._res_lock: + for pin in pins: + for reserver_ref in self._reservations[pin]: + reserver = reserver_ref() + if reserver is not None and requester._conflicts_with(reserver): + raise GPIOPinInUse('pin %s is already in use by %r' % + (pin, reserver)) + self._reservations[pin].append(ref(requester)) + + def release_pins(self, reserver, *pins): + """ + Releases the reservation of *reserver* against *pins*. This is + typically called during :meth:`~gpiozero.Device.close` to clean up + reservations taken during construction. Releasing a reservation that is + not currently held will be silently ignored (to permit clean-up after + failed / partial construction). + """ + with self._res_lock: + for pin in pins: + self._reservations[pin] = [ + ref for ref in self._reservations[pin] + if ref() not in (reserver, None) # may as well clean up dead refs + ] + + def release_all(self, reserver): + """ + Releases all pin reservations taken out by *reserver*. See + :meth:`release_pins` for further information). + """ + # Yes, this would be more efficient if it simply regenerated the + # reservations list without any references to reserver instead of + # (in release_pins) looping over each pin individually. However, this + # then causes a subtle bug in LocalPiFactory which does something + # horribly naughty (with good reason) and makes its _reservations + # dictionary equivalent to a class-level one. + self.release_pins(reserver, *self._reservations) + + def close(self): + """ + Closes the pin factory. This is expected to clean up all resources + manipulated by the factory. It it typically called at script + termination. + """ + pass + + def pin(self, spec): + """ + Creates an instance of a :class:`Pin` descendent representing the + specified pin. + + .. warning:: + + Descendents must ensure that pin instances representing the same + hardware are identical; i.e. two separate invocations of + :meth:`pin` for the same pin specification must return the same + object. + """ + raise PinUnsupported( # pragma: no cover + "Individual pins are not supported by this pin factory") + + def spi(self, **spi_args): + """ + Returns an instance of an :class:`SPI` interface, for the specified SPI + *port* and *device*, or for the specified pins (*clock_pin*, + *mosi_pin*, *miso_pin*, and *select_pin*). Only one of the schemes can + be used; attempting to mix *port* and *device* with pin numbers will + raise :exc:`SPIBadArgs`. + """ + raise PinSPIUnsupported( # pragma: no cover + 'SPI not supported by this pin factory') + + def ticks(self): + """ + Return the current ticks, according to the factory. The reference point + is undefined and thus the result of this method is only meaningful when + compared to another value returned by this method. + + The format of the time is also arbitrary, as is whether the time wraps + after a certain duration. Ticks should only be compared using the + :meth:`ticks_diff` method. + """ + raise NotImplementedError + + def ticks_diff(self, later, earlier): + """ + Return the time in seconds between two :meth:`ticks` results. The + arguments are specified in the same order as they would be in the + formula *later* - *earlier* but the result is guaranteed to be in + seconds, and to be positive even if the ticks "wrapped" between calls + to :meth:`ticks`. + """ + raise NotImplementedError + + def _get_pi_info(self): + return None # pragma: no cover + + pi_info = property( + lambda self: self._get_pi_info(), + doc="""\ + Returns a :class:`PiBoardInfo` instance representing the Pi that + instances generated by this factory will be attached to. + + If the pins represented by this class are not *directly* attached to a + Pi (e.g. the pin is attached to a board attached to the Pi, or the pins + are not on a Pi at all), this may return :data:`None`. + """) + + +class Pin(object): + """ + Abstract base class representing a pin attached to some form of controller, + be it GPIO, SPI, ADC, etc. + + Descendents should override property getters and setters to accurately + represent the capabilities of pins. Descendents *must* override the + following methods: + + * :meth:`_get_function` + * :meth:`_set_function` + * :meth:`_get_state` + + Descendents *may* additionally override the following methods, if + applicable: + + * :meth:`close` + * :meth:`output_with_state` + * :meth:`input_with_pull` + * :meth:`_set_state` + * :meth:`_get_frequency` + * :meth:`_set_frequency` + * :meth:`_get_pull` + * :meth:`_set_pull` + * :meth:`_get_bounce` + * :meth:`_set_bounce` + * :meth:`_get_edges` + * :meth:`_set_edges` + * :meth:`_get_when_changed` + * :meth:`_set_when_changed` + """ + + def __repr__(self): + return "" # pragma: no cover + + def close(self): + """ + Cleans up the resources allocated to the pin. After this method is + called, this :class:`Pin` instance may no longer be used to query or + control the pin's state. + """ + pass + + def output_with_state(self, state): + """ + Sets the pin's function to "output" and specifies an initial state + for the pin. By default this is equivalent to performing:: + + pin.function = 'output' + pin.state = state + + However, descendents may override this in order to provide the smallest + possible delay between configuring the pin for output and specifying an + initial value (which can be important for avoiding "blips" in + active-low configurations). + """ + self.function = 'output' + self.state = state + + def input_with_pull(self, pull): + """ + Sets the pin's function to "input" and specifies an initial pull-up + for the pin. By default this is equivalent to performing:: + + pin.function = 'input' + pin.pull = pull + + However, descendents may override this order to provide the smallest + possible delay between configuring the pin for input and pulling the + pin up/down (which can be important for avoiding "blips" in some + configurations). + """ + self.function = 'input' + self.pull = pull + + def _get_function(self): + raise NotImplementedError + + def _set_function(self, value): + raise NotImplementedError + + function = property( + lambda self: self._get_function(), + lambda self, value: self._set_function(value), + doc="""\ + The function of the pin. This property is a string indicating the + current function or purpose of the pin. Typically this is the string + "input" or "output". However, in some circumstances it can be other + strings indicating non-GPIO related functionality. + + With certain pin types (e.g. GPIO pins), this attribute can be changed + to configure the function of a pin. If an invalid function is + specified, for this attribute, :exc:`PinInvalidFunction` will be + raised. + """) + + def _get_state(self): + raise NotImplementedError + + def _set_state(self, value): + raise PinSetInput( # pragma: no cover + "Cannot set the state of pin %r" % self) + + state = property( + lambda self: self._get_state(), + lambda self, value: self._set_state(value), + doc="""\ + The state of the pin. This is 0 for low, and 1 for high. As a low level + view of the pin, no swapping is performed in the case of pull ups (see + :attr:`pull` for more information): + + .. code-block:: text + + HIGH - - - - > ,---------------------- + | + | + LOW ----------------' + + Descendents which implement analog, or analog-like capabilities can + return values between 0 and 1. For example, pins implementing PWM + (where :attr:`frequency` is not :data:`None`) return a value between + 0.0 and 1.0 representing the current PWM duty cycle. + + If a pin is currently configured for input, and an attempt is made to + set this attribute, :exc:`PinSetInput` will be raised. If an invalid + value is specified for this attribute, :exc:`PinInvalidState` will be + raised. + """) + + def _get_pull(self): + return 'floating' # pragma: no cover + + def _set_pull(self, value): + raise PinFixedPull( # pragma: no cover + "Cannot change pull-up on pin %r" % self) + + pull = property( + lambda self: self._get_pull(), + lambda self, value: self._set_pull(value), + doc="""\ + The pull-up state of the pin represented as a string. This is typically + one of the strings "up", "down", or "floating" but additional values + may be supported by the underlying hardware. + + If the pin does not support changing pull-up state (for example because + of a fixed pull-up resistor), attempts to set this property will raise + :exc:`PinFixedPull`. If the specified value is not supported by the + underlying hardware, :exc:`PinInvalidPull` is raised. + """) + + def _get_frequency(self): + return None # pragma: no cover + + def _set_frequency(self, value): + if value is not None: + raise PinPWMUnsupported( # pragma: no cover + "PWM is not supported on pin %r" % self) + + frequency = property( + lambda self: self._get_frequency(), + lambda self, value: self._set_frequency(value), + doc="""\ + The frequency (in Hz) for the pin's PWM implementation, or :data:`None` + if PWM is not currently in use. This value always defaults to + :data:`None` and may be changed with certain pin types to activate or + deactivate PWM. + + If the pin does not support PWM, :exc:`PinPWMUnsupported` will be + raised when attempting to set this to a value other than :data:`None`. + """) + + def _get_bounce(self): + return None # pragma: no cover + + def _set_bounce(self, value): + if value is not None: # pragma: no cover + raise PinEdgeDetectUnsupported( + "Edge detection is not supported on pin %r" % self) + + bounce = property( + lambda self: self._get_bounce(), + lambda self, value: self._set_bounce(value), + doc="""\ + The amount of bounce detection (elimination) currently in use by edge + detection, measured in seconds. If bounce detection is not currently in + use, this is :data:`None`. + + For example, if :attr:`edges` is currently "rising", :attr:`bounce` is + currently 5/1000 (5ms), then the waveform below will only fire + :attr:`when_changed` on two occasions despite there being three rising + edges: + + .. code-block:: text + + TIME 0...1...2...3...4...5...6...7...8...9...10..11..12 ms + + bounce elimination |===================| |============== + + HIGH - - - - > ,--. ,--------------. ,--. + | | | | | | + | | | | | | + LOW ----------------' `-' `-' `----------- + : : + : : + when_changed when_changed + fires fires + + If the pin does not support edge detection, attempts to set this + property will raise :exc:`PinEdgeDetectUnsupported`. If the pin + supports edge detection, the class must implement bounce detection, + even if only in software. + """) + + def _get_edges(self): + return 'none' # pragma: no cover + + def _set_edges(self, value): + raise PinEdgeDetectUnsupported( # pragma: no cover + "Edge detection is not supported on pin %r" % self) + + edges = property( + lambda self: self._get_edges(), + lambda self, value: self._set_edges(value), + doc="""\ + The edge that will trigger execution of the function or bound method + assigned to :attr:`when_changed`. This can be one of the strings + "both" (the default), "rising", "falling", or "none": + + .. code-block:: text + + HIGH - - - - > ,--------------. + | | + | | + LOW --------------------' `-------------- + : : + : : + Fires when_changed "both" "both" + when edges is ... "rising" "falling" + + If the pin does not support edge detection, attempts to set this + property will raise :exc:`PinEdgeDetectUnsupported`. + """) + + def _get_when_changed(self): + return None # pragma: no cover + + def _set_when_changed(self, value): + raise PinEdgeDetectUnsupported( # pragma: no cover + "Edge detection is not supported on pin %r" % self) + + when_changed = property( + lambda self: self._get_when_changed(), + lambda self, value: self._set_when_changed(value), + doc="""\ + A function or bound method to be called when the pin's state changes + (more specifically when the edge specified by :attr:`edges` is detected + on the pin). The function or bound method must accept two parameters: + the first will report the ticks (from :meth:`Factory.ticks`) when + the pin's state changed, and the second will report the pin's current + state. + + .. warning:: + + Depending on hardware support, the state is *not guaranteed to be + accurate*. For instance, many GPIO implementations will provide + an interrupt indicating when a pin's state changed but not what it + changed to. In this case the pin driver simply reads the pin's + current state to supply this parameter, but the pin's state may + have changed *since* the interrupt. Exercise appropriate caution + when relying upon this parameter. + + If the pin does not support edge detection, attempts to set this + property will raise :exc:`PinEdgeDetectUnsupported`. + """) + + +class SPI(Device): + """ + Abstract interface for `Serial Peripheral Interface`_ (SPI) + implementations. Descendents *must* override the following methods: + + * :meth:`transfer` + * :meth:`_get_clock_mode` + + Descendents *may* override the following methods, if applicable: + + * :meth:`read` + * :meth:`write` + * :meth:`_set_clock_mode` + * :meth:`_get_lsb_first` + * :meth:`_set_lsb_first` + * :meth:`_get_select_high` + * :meth:`_set_select_high` + * :meth:`_get_bits_per_word` + * :meth:`_set_bits_per_word` + + .. _Serial Peripheral Interface: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus + """ + + def read(self, n): + """ + Read *n* words of data from the SPI interface, returning them as a + sequence of unsigned ints, each no larger than the configured + :attr:`bits_per_word` of the interface. + + This method is typically used with read-only devices that feature + half-duplex communication. See :meth:`transfer` for full duplex + communication. + """ + return self.transfer([0] * n) + + def write(self, data): + """ + Write *data* to the SPI interface. *data* must be a sequence of + unsigned integer words each of which will fit within the configured + :attr:`bits_per_word` of the interface. The method returns the number + of words written to the interface (which may be less than or equal to + the length of *data*). + + This method is typically used with write-only devices that feature + half-duplex communication. See :meth:`transfer` for full duplex + communication. + """ + return len(self.transfer(data)) + + def transfer(self, data): + """ + Write *data* to the SPI interface. *data* must be a sequence of + unsigned integer words each of which will fit within the configured + :attr:`bits_per_word` of the interface. The method returns the sequence + of words read from the interface while writing occurred (full duplex + communication). + + The length of the sequence returned dictates the number of words of + *data* written to the interface. Each word in the returned sequence + will be an unsigned integer no larger than the configured + :attr:`bits_per_word` of the interface. + """ + raise NotImplementedError + + @property + def clock_polarity(self): + """ + The polarity of the SPI clock pin. If this is :data:`False` (the + default), the clock pin will idle low, and pulse high. Setting this to + :data:`True` will cause the clock pin to idle high, and pulse low. On + many data sheets this is documented as the CPOL value. + + The following diagram illustrates the waveform when + :attr:`clock_polarity` is :data:`False` (the default), equivalent to + CPOL 0: + + .. code-block:: text + + on on on on on on on + ,---. ,---. ,---. ,---. ,---. ,---. ,---. + CLK | | | | | | | | | | | | | | + | | | | | | | | | | | | | | + ------' `---' `---' `---' `---' `---' `---' `------ + idle off off off off off off idle + + The following diagram illustrates the waveform when + :attr:`clock_polarity` is :data:`True`, equivalent to CPOL 1: + + .. code-block:: text + + idle off off off off off off idle + ------. ,---. ,---. ,---. ,---. ,---. ,---. ,------ + | | | | | | | | | | | | | | + CLK | | | | | | | | | | | | | | + `---' `---' `---' `---' `---' `---' `---' + on on on on on on on + """ + return bool(self.clock_mode & 2) + + @clock_polarity.setter + def clock_polarity(self, value): + self.clock_mode = self.clock_mode & (~2) | (bool(value) << 1) + + @property + def clock_phase(self): + """ + The phase of the SPI clock pin. If this is :data:`False` (the default), + data will be read from the MISO pin when the clock pin activates. + Setting this to :data:`True` will cause data to be read from the MISO + pin when the clock pin deactivates. On many data sheets this is + documented as the CPHA value. Whether the clock edge is rising or + falling when the clock is considered activated is controlled by the + :attr:`clock_polarity` attribute (corresponding to CPOL). + + The following diagram indicates when data is read when + :attr:`clock_polarity` is :data:`False`, and :attr:`clock_phase` is + :data:`False` (the default), equivalent to CPHA 0: + + .. code-block:: text + + ,---. ,---. ,---. ,---. ,---. ,---. ,---. + CLK | | | | | | | | | | | | | | + | | | | | | | | | | | | | | + ----' `---' `---' `---' `---' `---' `---' `------- + : : : : : : : + MISO---. ,---. ,---. ,---. ,---. ,---. ,---. + / \\ / \\ / \\ / \\ / \\ / \\ / \\ + -{ Bit X Bit X Bit X Bit X Bit X Bit X Bit }------ + \\ / \\ / \\ / \\ / \\ / \\ / \\ / + `---' `---' `---' `---' `---' `---' `---' + + The following diagram indicates when data is read when + :attr:`clock_polarity` is :data:`False`, but :attr:`clock_phase` is + :data:`True`, equivalent to CPHA 1: + + .. code-block:: text + + ,---. ,---. ,---. ,---. ,---. ,---. ,---. + CLK | | | | | | | | | | | | | | + | | | | | | | | | | | | | | + ----' `---' `---' `---' `---' `---' `---' `------- + : : : : : : : + MISO ,---. ,---. ,---. ,---. ,---. ,---. ,---. + / \\ / \\ / \\ / \\ / \\ / \\ / \\ + -----{ Bit X Bit X Bit X Bit X Bit X Bit X Bit }-- + \\ / \\ / \\ / \\ / \\ / \\ / \\ / + `---' `---' `---' `---' `---' `---' `---' + """ + return bool(self.clock_mode & 1) + + @clock_phase.setter + def clock_phase(self, value): + self.clock_mode = self.clock_mode & (~1) | bool(value) + + def _get_clock_mode(self): + raise NotImplementedError # pragma: no cover + + def _set_clock_mode(self, value): + raise SPIFixedClockMode( # pragma: no cover + "clock_mode cannot be changed on %r" % self) + + clock_mode = property( + lambda self: self._get_clock_mode(), + lambda self, value: self._set_clock_mode(value), + doc="""\ + Presents a value representing the :attr:`clock_polarity` and + :attr:`clock_phase` attributes combined according to the following + table: + + +------+-----------------+--------------+ + | mode | polarity (CPOL) | phase (CPHA) | + +======+=================+==============+ + | 0 | False | False | + +------+-----------------+--------------+ + | 1 | False | True | + +------+-----------------+--------------+ + | 2 | True | False | + +------+-----------------+--------------+ + | 3 | True | True | + +------+-----------------+--------------+ + + Adjusting this value adjusts both the :attr:`clock_polarity` and + :attr:`clock_phase` attributes simultaneously. + """) + + def _get_lsb_first(self): + return False # pragma: no cover + + def _set_lsb_first(self, value): + raise SPIFixedBitOrder( # pragma: no cover + "lsb_first cannot be changed on %r" % self) + + lsb_first = property( + lambda self: self._get_lsb_first(), + lambda self, value: self._set_lsb_first(value), + doc="""\ + Controls whether words are read and written LSB in (Least Significant + Bit first) order. The default is :data:`False` indicating that words + are read and written in MSB (Most Significant Bit first) order. + Effectively, this controls the `Bit endianness`_ of the connection. + + The following diagram shows the a word containing the number 5 (binary + 0101) transmitted on MISO with :attr:`bits_per_word` set to 4, and + :attr:`clock_mode` set to 0, when :attr:`lsb_first` is :data:`False` + (the default): + + .. code-block:: text + + ,---. ,---. ,---. ,---. + CLK | | | | | | | | + | | | | | | | | + ----' `---' `---' `---' `----- + : ,-------. : ,-------. + MISO: | : | : | : | + : | : | : | : | + ----------' : `-------' : `---- + : : : : + MSB LSB + + And now with :attr:`lsb_first` set to :data:`True` (and all other + parameters the same): + + .. code-block:: text + + ,---. ,---. ,---. ,---. + CLK | | | | | | | | + | | | | | | | | + ----' `---' `---' `---' `----- + ,-------. : ,-------. : + MISO: | : | : | : + | : | : | : | : + --' : `-------' : `----------- + : : : : + LSB MSB + + .. _Bit endianness: https://en.wikipedia.org/wiki/Endianness#Bit_endianness + """) + + def _get_select_high(self): + return False # pragma: no cover + + def _set_select_high(self, value): + raise SPIFixedSelect( # pragma: no cover + "select_high cannot be changed on %r" % self) + + select_high = property( + lambda self: self._get_select_high(), + lambda self, value: self._set_select_high(value), + doc="""\ + If :data:`False` (the default), the chip select line is considered + active when it is pulled low. When set to :data:`True`, the chip select + line is considered active when it is driven high. + + The following diagram shows the waveform of the chip select line, and + the clock when :attr:`clock_polarity` is :data:`False`, and + :attr:`select_high` is :data:`False` (the default): + + .. code-block:: text + + ---. ,------ + __ | | + CS | chip is selected, and will react to clock | idle + `-----------------------------------------------------' + + ,---. ,---. ,---. ,---. ,---. ,---. ,---. + CLK | | | | | | | | | | | | | | + | | | | | | | | | | | | | | + ----' `---' `---' `---' `---' `---' `---' `------- + + And when :attr:`select_high` is :data:`True`: + + .. code-block:: text + + ,-----------------------------------------------------. + CS | chip is selected, and will react to clock | idle + | | + ---' `------ + + ,---. ,---. ,---. ,---. ,---. ,---. ,---. + CLK | | | | | | | | | | | | | | + | | | | | | | | | | | | | | + ----' `---' `---' `---' `---' `---' `---' `------- + """) + + def _get_bits_per_word(self): + return 8 # pragma: no cover + + def _set_bits_per_word(self, value): + raise SPIFixedWordSize( # pragma: no cover + "bits_per_word cannot be changed on %r" % self) + + bits_per_word = property( + lambda self: self._get_bits_per_word(), + lambda self, value: self._set_bits_per_word(value), + doc="""\ + Controls the number of bits that make up a word, and thus where the + word boundaries appear in the data stream, and the maximum value of a + word. Defaults to 8 meaning that words are effectively bytes. + + Several implementations do not support non-byte-sized words. + """) + + def _get_rate(self): + return 100000 # pragma: no cover + + def _set_rate(self, value): + raise SPIFixedRate( # pragma: no cover + "rate cannot be changed on %r" % self) + + rate = property( + lambda self: self._get_rate(), + lambda self, value: self._set_rate(value), + doc="""\ + Controls the speed of the SPI interface in Hz (or baud). + + Note that most software SPI implementations ignore this property, and + will raise :exc:`SPIFixedRate` if an attempt is made to set it, as they + have no rate control (they simply bit-bang as fast as possible because + typically this isn't very fast anyway, and introducing measures to + limit the rate would simply slow them down to the point of being + useless). + """) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0f2c4e1f21ff856c4330b92ab5955f6b9dcbc7b GIT binary patch literal 33106 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 WY_^DhI9@$<@;3@I`1_5*`Tq@}FO`S@ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/data.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00b88c4fdb55149d3da3d23bc93c018ab04df1a8 GIT binary patch literal 61362 zcmeIbYjj-KbtYIZ6bc{+zA1{Lr7KDl0X{(D!G|bHA_0&RDG>w-l9I0;#Uf6DC=#fG zZWTnKSY;=s65C1aD9+1Cn1qa-#Eug?@AuQ4hu!UNyJxayW>x=~nVz*~HU9MKAH905 z@tQSjzHgs~qfE`OUl$% zYS2ERhU}B-kUgvp+av0TJ*tk{r_|H-X?4tgK|N!?sE*rb)U)P7pqI%8i^XYE(iOZKbThtaIRJ@)JBg1V?C)FpNKZo+;etLbsYEpLaU(WUBp z&29SrF$vZ8mhavlM{}xakwFl?wcd>T({9^ zLmb^wr{uZr#itwM=>GD8JlFmD#fCV#kDrm}x?i7dh$FnAKAM%jsBAx7)NAT>^@e&g z@GPyas*Ji8cs8k&%Brcrv+HVF<AQ zDfMafBkD)hkEze7&#E6+@A<>C+l1nc(9e@Up?<=ZJz8SYqW-EY`$X5YM* zz8|r#X0P7MsGm|lrAt*mt$xP6`&spQ_wMJ^&#PZhchxW6U3))@QTCVc`DJ|AgTr~UA)H;dtTg%4z zs$!h4h4abU+1J!>-;HHomYlw-eh0CBcSW%pa0=x0d+Mv|_dTq>f_aLIxfkmkN;I)F zUdzSOc(sc4MU+VFzoh;kNGq>Ie;vQJqFBGXWUN0_f296csQL%$Pt>3KTIbKQucLLw zP{Ti0f1&=;jq_KCq3Mu9TmE(SO~kp3IDdmUUza#vMm{DETUqCG0dZK?zjAB0Tv>k$ ztd}e6Z_&oB%KE#z8*KGLME$+`hj%0DAF|myaeE5CzoEW~-`~uxSKn0s`c4c_ujA>z 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 Z`m?8f{RJG^wh!NrM>Y!lctn3T{r~e6JTCwM literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/lgpio.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/lgpio.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49ecd42913f515784089437c8ea4c733dd7ce770 GIT binary patch literal 12480 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 EKg%LZY5)KL literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/local.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/local.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8e5dc694f16bfed4aa4c600912e5065ee64b100 GIT binary patch literal 11149 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 VPh1PSd8B@(ex&~0`bYDn{{>Oo6fOV& literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/mock.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/mock.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..949ffb2466f77b6a7a8f95c852bae6aa80aeb5c3 GIT binary patch literal 17981 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 G`+oq5p0CRQ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/pi.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/pi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..240e5eab52888ae2a20ab652a1d1d13059d39949 GIT binary patch literal 11255 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 Fe**^1vU30c literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/rpigpio.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/rpigpio.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e6b2141f77aa74815487b6afc77cc2c7b3e480f GIT binary patch literal 7968 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/spi.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozero/pins/__pycache__/spi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3f8899819e40a474fc86612825d6501b8e3fcaf GIT binary patch literal 2542 zcmZuzOK%)S5bmCtot>F|#4&l8@EUPqr6lHnKnhWaLKKt;9Ec+fBcaK7yVpDRyxiU6 zmu4k|E#-ugAHczpIKV&1uiyvt5l)skapXi*uf5KLSxt3ycXd^5J-(h>yKoq6&g65^93@{6=Cj~{uz+`YXWxm=GJBZ}I!9oa3>-aI z7wNEMJkCg-BJ(zay*J?H&qAMqleay&vz;F^#Mk4Dm z8Bs==b>Ky|;ceys??8Yc3nrPYA8CHPlgoF!h@p^ zugTK^Fp4OMFXY2A`LG*kBS!XZvDc7w=gC8i?t06_{yK6~Ig?As<2tkz=}^v{xWI-;f6cvjll{Os=dY(Fb1!o|uQhWI>z*PPf;%N|X|2Tb#wsIV5L* z45&Ci9p1#HOGq$I=Hz8yBrXvMP1gh|fDi@no6obxp1WWHB~YO zjEPafqY$TIDZ-3PIlwb&%tOeLu_H#wkY5gyf`x)7U@j?U>iA}zZY3EnR9MvcDtH9W z8K*9Tu&PCo7Hg<22am$n{Fhf}nvM_*1d^pe&y=(FO7JjIrO<9B$LUCES4_v2NDBD- z*nQerEz3-|z>AujR@7EmnC{eeIT~pb}*Dt=NK)=iR6)=$<=t23aO&r zOMwAyqH$o~xg$bQ2sa8`7DbZtIMzWN=OwE%HZm`86$HB +# Copyright (c) 2018-2021 Ben Nuttall +# Copyright (c) 2020 chrisruk +# Copyright (c) 2016-2019 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import os +import sys +from textwrap import dedent +from itertools import cycle +from operator import attrgetter +from collections import namedtuple + +from ..exc import PinUnknownPi, PinMultiplePins, PinNoPins, PinInvalidPin +from ..devices import Device + + +# Some useful constants for describing pins + +V1_8 = '1V8' +V3_3 = '3V3' +V5 = '5V' +GND = 'GND' +NC = 'NC' # not connected +GPIO0 = 'GPIO0' +GPIO1 = 'GPIO1' +GPIO2 = 'GPIO2' +GPIO3 = 'GPIO3' +GPIO4 = 'GPIO4' +GPIO5 = 'GPIO5' +GPIO6 = 'GPIO6' +GPIO7 = 'GPIO7' +GPIO8 = 'GPIO8' +GPIO9 = 'GPIO9' +GPIO10 = 'GPIO10' +GPIO11 = 'GPIO11' +GPIO12 = 'GPIO12' +GPIO13 = 'GPIO13' +GPIO14 = 'GPIO14' +GPIO15 = 'GPIO15' +GPIO16 = 'GPIO16' +GPIO17 = 'GPIO17' +GPIO18 = 'GPIO18' +GPIO19 = 'GPIO19' +GPIO20 = 'GPIO20' +GPIO21 = 'GPIO21' +GPIO22 = 'GPIO22' +GPIO23 = 'GPIO23' +GPIO24 = 'GPIO24' +GPIO25 = 'GPIO25' +GPIO26 = 'GPIO26' +GPIO27 = 'GPIO27' +GPIO28 = 'GPIO28' +GPIO29 = 'GPIO29' +GPIO30 = 'GPIO30' +GPIO31 = 'GPIO31' +GPIO32 = 'GPIO32' +GPIO33 = 'GPIO33' +GPIO34 = 'GPIO34' +GPIO35 = 'GPIO35' +GPIO36 = 'GPIO36' +GPIO37 = 'GPIO37' +GPIO38 = 'GPIO38' +GPIO39 = 'GPIO39' +GPIO40 = 'GPIO40' +GPIO41 = 'GPIO41' +GPIO42 = 'GPIO42' +GPIO43 = 'GPIO43' +GPIO44 = 'GPIO44' +GPIO45 = 'GPIO45' + +# Board layout ASCII art + +REV1_BOARD = """\ +{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} +{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} +{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} +{style:white on green}| |{style:reset} +{style:white on green}| {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:black on white}+======{style:reset} +{style:white on green}| {style:on black}|S|{style:black on white}| Net{style:reset} +{style:white on green}| {style:on black}|I|{style:black on white}+======{style:reset} +{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} +{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" + +REV2_BOARD = """\ +{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} +{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} +{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} +{style:white on green}| {P5:{style} col1}{style:white on green} |{style:reset} +{style:white on green}| P5 {P5:{style} col2}{style:white on green} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:black on white}+======{style:reset} +{style:white on green}| {style:on black}|S|{style:black on white}| Net{style:reset} +{style:white on green}| {style:on black}|I|{style:black on white}+======{style:reset} +{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} +{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" + +A_BOARD = """\ +{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} +{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} +{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} +{style:white on green}| {P5:{style} col1}{style:white on green} |{style:reset} +{style:white on green}| P5 {P5:{style} col2}{style:white on green} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:on green} |{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} +{style:white on green}| {style:on black}|I|{style:on green} |{style:reset} +{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} +{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" + +BPLUS_BOARD = """\ +{style:white on green},--------------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+===={style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:black on white}+===={style:reset} +{style:white on green}| {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:on black}+----+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:on black}|SoC |{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:on black}| |{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:on black}+----+{style:on green} |{style:reset} +{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+======{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| Net{style:reset} +{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+======{style:reset} +{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" + +B3PLUS_BOARD = """\ +{style:white on green},--------------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+===={style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:black on white}| USB{style:reset} +{style:white on green}| {style:black on white} Wi {style:white on green} {POE:{style} row1}{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} {POE:{style} row2}{style:on green} |{style:reset} +{style:white on green}| {style:black on white},----.{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} |{style:reset} +{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+======{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| Net{style:reset} +{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+======{style:reset} +{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" + +B4_BOARD = """\ +{style:white on green},--------------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+======{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:black on white}| Net{style:reset} +{style:white on green}| {style:black on white} Wi {style:white on green} {POE:{style} row1}{style:on green} {style:black on white}+======{style:reset} +{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} {POE:{style} row2}{style:normal white on green} |{style:reset} +{style:white on green}| {style:black on white},----.{style:on green} {style:white on black}+---+{style:on green} {style:blue on white}+===={style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:white on black}|RAM|{style:on green} {style:blue on white}|USB3{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:white on black}| |{style:on green} {style:blue on white}+===={style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} {style:white on black}+---+{style:on green} |{style:reset} +{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}|USB2{style:reset} +{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|hd|{style:white on green} {style:black on white}|hd|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+===={style:reset} +{style:white on green}`-{style:black on white}| |{style:white on green}---{style:black on white}|m0|{style:white on green}---{style:black on white}|m1|{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" + +APLUS_BOARD = """\ +{style:white on green},--------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} +{style:white on green}| |{style:reset} +{style:white on green}| {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:on black}+----+{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:on black}|SoC |{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:on black}| |{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:on black}+----+{style:on green} |{style:reset} +{style:white on green}| {style:on black}|C|{style:on green} |{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} +{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} |{style:reset} +{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-'{style:reset}""" + +A3PLUS_BOARD = """\ +{style:white on green},--------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} +{style:white on green}| {style:black on white} Wi {style:white on green} |{style:reset} +{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:white on green}| {style:black on white},----.{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:black on white}| USB{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:black on white}+===={style:reset} +{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} |{style:reset} +{style:white on green}| {style:on black}|C|{style:on green} |{style:reset} +{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} +{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} |{style:reset} +{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-'{style:reset}""" + +ZERO12_BOARD = """\ +{style:white on green},-------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} +{style:black on white}---+{style:white on green} {style:on black}+---+{style:on green} {style:bold}PiZero{style:normal} |{style:reset} +{style:black on white} sd|{style:white on green} {style:on black}|SoC|{style:on green} {style:bold}V{pcb_revision:3s}{style:normal} |{style:reset} +{style:black on white}---+|hdmi|{style:white on green} {style:on black}+---+{style:on green} {style:black on white}usb{style:on green} {style:black on white}pwr{style:white on green} |{style:reset} +{style:white on green}`---{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-'{style:reset}""" + +ZERO13_BOARD = """\ +{style:white on green}.-------------------------.{style:reset} +{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} {style:black on white}|c{style:reset} +{style:black on white}---+{style:white on green} {style:on black}+---+{style:on green} {style:bold}Pi{model:6s}{style:normal}{style:black on white}|s{style:reset} +{style:black on white} sd|{style:white on green} {style:on black}|SoC|{style:on green} {style:bold}V{pcb_revision:3s}{style:normal} {style:black on white}|i{style:reset} +{style:black on white}---+|hdmi|{style:white on green} {style:on black}+---+{style:on green} {style:black on white}usb{style:on green} {style:on white}pwr{style:white on green} |{style:reset} +{style:white on green}`---{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-'{style:reset}""" + +CM_BOARD = """\ +{style:white on green}+---------------------------------------+{style:reset} +{style:white on green}| {style:yellow on black}O{style:bold white on green} Raspberry Pi {model:4s} {style:normal yellow on black}O{style:white on green} |{style:reset} + {style:white on green}) Version {pcb_revision:3s} {style:on black}+---+{style:on green} ({style:reset} +{style:white on green}| {style:on black}|SoC|{style:on green} |{style:reset} + {style:white on green}) {style:on black}+---+{style:on green} ({style:reset} +{style:white on green}| {style:on black}O{style:on green} _ {style:on black}O{style:on green} |{style:reset} +{style:white on green}||||||{style:reset} {style:white on green}||||||||||||||||||||||||||||||||||{style:reset}""" + +CM3PLUS_BOARD = """\ +{style:white on green}+---------------------------------------+{style:reset} +{style:white on green}| {style:yellow on black}O{style:bold white on green} Raspberry Pi {model:4s} {style:normal yellow on black}O{style:white on green} |{style:reset} + {style:white on green}) Version {pcb_revision:3s} {style:black on white},---.{style:white on green} ({style:reset} +{style:white on green}| {style:black on white}|SoC|{style:white on green} |{style:reset} + {style:white on green}) {style:black on white}`---'{style:white on green} ({style:reset} +{style:white on green}| {style:on black}O{style:on green} _ {style:on black}O{style:on green} |{style:reset} +{style:white on green}||||||{style:reset} {style:white on green}||||||||||||||||||||||||||||||||||{style:reset}""" + +CM4_BOARD = """\ +{style:white on green},--{style:black on white}csi1{style:white on green}---{style:black on white}dsi0{style:white on green}---{style:black on white}dsi1{style:white on green}-----------{style:bold},-------------.{style:normal}-----------.{style:reset} +{style:white on green}| {style:black on white}----{style:white on green} {style:black on white}----{style:white on green} {style:black on white}----{style:white on green} J2{J2:{style} col2}{style:bold white on green}|{style:yellow}O O{style:white}|{style:normal} |{style:reset} +{style:white on green}{style:black on white}c|{style:white on green} {style:bold yellow}O {style:white}Pi {model:4s} Rev {pcb_revision:3s}{style:normal} {J2:{style} col1}{style:bold white on green}| {style:normal black on white} Wi {style:white on green} {style:bold}|{style:normal} {style:bold yellow}O{style:normal white} |{style:reset} +{style:white on green}{style:black on white}s|{style:white on green} {style:bold}IO Board{style:normal} {style:bold}| {style:normal black on white} Fi {style:white on green} {style:bold}|{style:normal} |{style:reset} +{style:white on green}{style:black on white}i|{style:white on green} J6{J6:{style} col2}{style:bold white on green} | {style:normal white on black}+--+{style:on green}{style:bold}| {style:normal white on black}|P|{style:on green} |{style:reset} +{style:white on green}| J8 {J6:{style} col1}{style:bold white on green} | {style:normal black on white},----.{style:on green} {style:white on black}|eM|{style:bold on green}| {style:normal white on black}}}-{{{style:on green} |{style:reset} +{style:white on green}|{style:bold yellow}O{J8:{style} col2}{style:white on green} {style:bold yellow}O{style:white} | {style:normal black on white}|SoC |{style:on green} {style:white on black}|MC|{style:bold on green}| {style:normal white on black}|C|{style:on green} |{style:reset} +{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:bold}| {style:normal black on white}| |{style:on green} {style:white on black}+--+{style:bold on green}| {style:normal white on black}|I|{style:on green} |{style:reset} +{style:white on green}| {style:black on white},---.{style:white on green} {POE:{style} row1}{style:bold white on green} | {style:normal black on white}`----'{style:white on green} {style:bold}| {style:normal white on black}|e|{style:on green} |{style:reset} +{style:white on green}|{style:black on white}( ={style:on green}O{style:on white} |{style:white on green} {POE:{style} row2}{style:bold white on green} | {style:normal white on black}+----+{style:on green} {style:bold}|{style:normal} |{style:reset} +{style:white on green}| {style:black on white}) + |{style:white on green} {style:bold}|{style:yellow}O {style:normal white on black}|RAM |{style:on green} {style:bold yellow}O{style:white}|{style:normal} |{style:reset} +{style:white on green}|{style:black on white}( ={style:on green}O{style:on white} |{style:white on green} {style:bold}`--{style:normal white on black}+----+{style:bold on green}-----'{style:normal} |{style:reset} +{style:white on green}| {style:black on white}`---'{style:white on green} |{style:reset} +{style:white on green}| |{style:reset} +{style:white on green}| |{style:reset} +{style:white on green}| {style:bold yellow}O {style:normal black on white}|Net |{style:on green} {style:black on white}|USB|{style:on green} {style:black on white}|uSD|{style:white on green} {style:bold yellow}O{style:normal white on black}|p|{style:on green}|{style:reset} +{style:white on green}|{style:bold yellow}O {style:normal black on white}|HDMI|{style:on green} {style:black on white}|HDMI|{style:white on green} {style:bold yellow}O {style:normal black on white}| |{style:on green} {style:black on white}| 2 |{style:on green} {style:black on white}usb{style:white on green} {style:black on white}| |{style:white on green} {style:on black}|w|{style:on green}|{style:reset} +{style:white on green}`----{style:black on white}| 0 |{style:white on green}---{style:black on white}| 1 |{style:white on green}-------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}------------{style:white on black}|r|{style:on green}'{style:reset}""" + +P400_BOARD = """\ + {style:white on red},------+----+----+----+----+---+--+--+--+--------------------+---.{style:reset} + {style:white on red},' |{style:white on black}Net {style:white on red}|{style:white on black}USB {style:white on red}|{style:cyan on black}USB {style:white on red}|{style:cyan on black}USB {style:white on red}|{style:white on black}pwr{style:white on red}|{style:white on black}hd{style:white on red}|{style:white on black}hd{style:white on red}|{style:white on black}sd{style:white on red}|{J8:{style} col2}{style:white on red}| `.{style:reset} + {style:white on red}/ {style:black}=={style:white} |{style:white on black} {style:white on red}|{style:white on black} 2 {style:white on red}|{style:cyan on black} 3 {style:white on red}|{style:cyan on black} 3 {style:white on red}|{style:white on black} {style:white on red}|{style:white on black}m1{style:white on red}|{style:white on black}m0{style:white on red}|{style:white on black} {style:white on red}|{J8:{style} col1}{style:white on red}| \\{style:reset} +{style:black on white},------------------------------------------------------------------------.{style:reset} +{style:black on white}| ___ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ {style:bold on white}o o {style:green}o{style:normal black}____ |{style:reset} +{style:black on white}| |Esc|F1{style:red}11{style:black}|F2{style:red}12{style:black}|F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10{style:red}o{style:black}|NumL|Pt{style:red}Sq{style:black}|Dl{style:red}In{style:black}| |{style:reset} +{style:black on white}| ___ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ ___ ____ _______ |{style:reset} +{style:black on white}| |¬ |! |" |£ |$ |% |^ |& {style:red}7{style:black}|* {style:red}8{style:black}|( {style:red}9{style:black}|) {style:red}*{style:black}|_ |+ |BkSpc | |{style:reset} +{style:black on white}| |` ||1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |<-- | |{style:reset} +{style:black on white}| _____ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ ____ __ ______ |{style:reset} +{style:black on white}| |Tab |Q |W |E |R |T |Y |U {style:red}4{style:black}|I {style:red}5{style:black}|O {style:red}6{style:black}|P {style:red}-{style:black}|{{ |}} |Enter | |{style:reset} +{style:black on white}| |->| | | | | | | | | | | |[ |] |<-' | |{style:reset} +{style:black on white}| ______ ____ ____ ____ ____ ____ ____ ___ ____ ____ ____ ____ __ | |{style:reset} +{style:black on white}| |Caps |A |S |D |F |G |H |J {style:red}1{style:black}|K {style:red}2{style:black}|L {style:red}3{style:black}|: {style:red}+{style:black}|@ |~ | | |{style:reset} +{style:black on white}| |Lock | | | | | | | | | |; |' |# | | |{style:reset} +{style:black on white}| _____ ___ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ __________ |{style:reset} +{style:black on white}| |Shift|| |Z |X |C |V |B |N |M {style:red}0{style:black}|< |> {style:red}.{style:black}|? {style:red}/{style:black}|Shift | |{style:reset} +{style:black on white}| |^ |\\ | | | | | | | |, |. |/ |^ | |{style:reset} +{style:black on white}| ____ ___ ____ ____ _______________________ ____ ____ _____ |{style:reset} +{style:black on white}| |Ctrl|{style:red}Fn{style:black} | {style:red}**{style:black} |Alt | |Alt |Ctrl|____|^{style:red}PgUp{style:black}|____ |{style:reset} +{style:black on white}| | | | {style:red}{{}}{style:black} | | | | |<{style:red}Hom{style:black}|v{style:red}PgDn{style:black}|>{style:red}End{style:black}| |{style:reset} +{style:black on white}`------------------------------------------------------------------------'{style:reset} + Raspberry Pi {style:bold red}{model}{style:reset} Rev {pcb_revision}""" + +# Pin maps for various board revisions and headers + +REV1_P1 = { +# pin func pullup pin func pullup + 1: (V3_3, False), 2: (V5, False), + 3: (GPIO0, True), 4: (V5, False), + 5: (GPIO1, True), 6: (GND, False), + 7: (GPIO4, False), 8: (GPIO14, False), + 9: (GND, False), 10: (GPIO15, False), + 11: (GPIO17, False), 12: (GPIO18, False), + 13: (GPIO21, False), 14: (GND, False), + 15: (GPIO22, False), 16: (GPIO23, False), + 17: (V3_3, False), 18: (GPIO24, False), + 19: (GPIO10, False), 20: (GND, False), + 21: (GPIO9, False), 22: (GPIO25, False), + 23: (GPIO11, False), 24: (GPIO8, False), + 25: (GND, False), 26: (GPIO7, False), + } + +REV2_P1 = { + 1: (V3_3, False), 2: (V5, False), + 3: (GPIO2, True), 4: (V5, False), + 5: (GPIO3, True), 6: (GND, False), + 7: (GPIO4, False), 8: (GPIO14, False), + 9: (GND, False), 10: (GPIO15, False), + 11: (GPIO17, False), 12: (GPIO18, False), + 13: (GPIO27, False), 14: (GND, False), + 15: (GPIO22, False), 16: (GPIO23, False), + 17: (V3_3, False), 18: (GPIO24, False), + 19: (GPIO10, False), 20: (GND, False), + 21: (GPIO9, False), 22: (GPIO25, False), + 23: (GPIO11, False), 24: (GPIO8, False), + 25: (GND, False), 26: (GPIO7, False), + } + +REV2_P5 = { + 1: (V5, False), 2: (V3_3, False), + 3: (GPIO28, False), 4: (GPIO29, False), + 5: (GPIO30, False), 6: (GPIO31, False), + 7: (GND, False), 8: (GND, False), + } + +PLUS_J8 = { + 1: (V3_3, False), 2: (V5, False), + 3: (GPIO2, True), 4: (V5, False), + 5: (GPIO3, True), 6: (GND, False), + 7: (GPIO4, False), 8: (GPIO14, False), + 9: (GND, False), 10: (GPIO15, False), + 11: (GPIO17, False), 12: (GPIO18, False), + 13: (GPIO27, False), 14: (GND, False), + 15: (GPIO22, False), 16: (GPIO23, False), + 17: (V3_3, False), 18: (GPIO24, False), + 19: (GPIO10, False), 20: (GND, False), + 21: (GPIO9, False), 22: (GPIO25, False), + 23: (GPIO11, False), 24: (GPIO8, False), + 25: (GND, False), 26: (GPIO7, False), + 27: (GPIO0, False), 28: (GPIO1, False), + 29: (GPIO5, False), 30: (GND, False), + 31: (GPIO6, False), 32: (GPIO12, False), + 33: (GPIO13, False), 34: (GND, False), + 35: (GPIO19, False), 36: (GPIO16, False), + 37: (GPIO26, False), 38: (GPIO20, False), + 39: (GND, False), 40: (GPIO21, False), + } + +PLUS_POE = { + 1: ('TR01', False), 2: ('TR00', False), + 3: ('TR03', False), 4: ('TR02', False), + } + +CM_SODIMM = { + 1: (GND, False), 2: ('EMMC DISABLE N', False), + 3: (GPIO0, False), 4: (NC, False), + 5: (GPIO1, False), 6: (NC, False), + 7: (GND, False), 8: (NC, False), + 9: (GPIO2, False), 10: (NC, False), + 11: (GPIO3, False), 12: (NC, False), + 13: (GND, False), 14: (NC, False), + 15: (GPIO4, False), 16: (NC, False), + 17: (GPIO5, False), 18: (NC, False), + 19: (GND, False), 20: (NC, False), + 21: (GPIO6, False), 22: (NC, False), + 23: (GPIO7, False), 24: (NC, False), + 25: (GND, False), 26: (GND, False), + 27: (GPIO8, False), 28: (GPIO28, False), + 29: (GPIO9, False), 30: (GPIO29, False), + 31: (GND, False), 32: (GND, False), + 33: (GPIO10, False), 34: (GPIO30, False), + 35: (GPIO11, False), 36: (GPIO31, False), + 37: (GND, False), 38: (GND, False), + 39: ('GPIO0-27 VREF', False), 40: ('GPIO0-27 VREF', False), + # Gap in SODIMM pins + 41: ('GPIO28-45 VREF', False), 42: ('GPIO28-45 VREF', False), + 43: (GND, False), 44: (GND, False), + 45: (GPIO12, False), 46: (GPIO32, False), + 47: (GPIO13, False), 48: (GPIO33, False), + 49: (GND, False), 50: (GND, False), + 51: (GPIO14, False), 52: (GPIO34, False), + 53: (GPIO15, False), 54: (GPIO35, False), + 55: (GND, False), 56: (GND, False), + 57: (GPIO16, False), 58: (GPIO36, False), + 59: (GPIO17, False), 60: (GPIO37, False), + 61: (GND, False), 62: (GND, False), + 63: (GPIO18, False), 64: (GPIO38, False), + 65: (GPIO19, False), 66: (GPIO39, False), + 67: (GND, False), 68: (GND, False), + 69: (GPIO20, False), 70: (GPIO40, False), + 71: (GPIO21, False), 72: (GPIO41, False), + 73: (GND, False), 74: (GND, False), + 75: (GPIO22, False), 76: (GPIO42, False), + 77: (GPIO23, False), 78: (GPIO43, False), + 79: (GND, False), 80: (GND, False), + 81: (GPIO24, False), 82: (GPIO44, False), + 83: (GPIO25, False), 84: (GPIO45, False), + 85: (GND, False), 86: (GND, False), + 87: (GPIO26, False), 88: ('GPIO46 1V8', False), + 89: (GPIO27, False), 90: ('GPIO47 1V8', False), + 91: (GND, False), 92: (GND, False), + 93: ('DSI0 DN1', False), 94: ('DSI1 DP0', False), + 95: ('DSI0 DP1', False), 96: ('DSI1 DN0', False), + 97: (GND, False), 98: (GND, False), + 99: ('DSI0 DN0', False), 100: ('DSI1 CP', False), + 101: ('DSI0 DP0', False), 102: ('DSI1 CN', False), + 103: (GND, False), 104: (GND, False), + 105: ('DSI0 CN', False), 106: ('DSI1 DP3', False), + 107: ('DSI0 CP', False), 108: ('DSI1 DN3', False), + 109: (GND, False), 110: (GND, False), + 111: ('HDMI CK N', False), 112: ('DSI1 DP2', False), + 113: ('HDMI CK P', False), 114: ('DSI1 DN2', False), + 115: (GND, False), 116: (GND, False), + 117: ('HDMI D0 N', False), 118: ('DSI1 DP1', False), + 119: ('HDMI D0 P', False), 120: ('DSI1 DN1', False), + 121: (GND, False), 122: (GND, False), + 123: ('HDMI D1 N', False), 124: (NC, False), + 125: ('HDMI D1 P', False), 126: (NC, False), + 127: (GND, False), 128: (NC, False), + 129: ('HDMI D2 N', False), 130: (NC, False), + 131: ('HDMI D2 P', False), 132: (NC, False), + 133: (GND, False), 134: (GND, False), + 135: ('CAM1 DP3', False), 136: ('CAM0 DP0', False), + 137: ('CAM1 DN3', False), 138: ('CAM0 DN0', False), + 139: (GND, False), 140: (GND, False), + 141: ('CAM1 DP2', False), 142: ('CAM0 CP', False), + 143: ('CAM1 DN2', False), 144: ('CAM0 CN', False), + 145: (GND, False), 146: (GND, False), + 147: ('CAM1 CP', False), 148: ('CAM0 DP1', False), + 149: ('CAM1 CN', False), 150: ('CAM0 DN1', False), + 151: (GND, False), 152: (GND, False), + 153: ('CAM1 DP1', False), 154: (NC, False), + 155: ('CAM1 DN1', False), 156: (NC, False), + 157: (GND, False), 158: (NC, False), + 159: ('CAM1 DP0', False), 160: (NC, False), + 161: ('CAM1 DN0', False), 162: (NC, False), + 163: (GND, False), 164: (GND, False), + 165: ('USB DP', False), 166: ('TVDAC', False), + 167: ('USB DM', False), 168: ('USB OTGID', False), + 169: (GND, False), 170: (GND, False), + 171: ('HDMI CEC', False), 172: ('VC TRST N', False), + 173: ('HDMI SDA', False), 174: ('VC TDI', False), + 175: ('HDMI SCL', False), 176: ('VC TMS', False), + 177: ('RUN', False), 178: ('VC TDO', False), + 179: ('VDD CORE', False), 180: ('VC TCK', False), + 181: (GND, False), 182: (GND, False), + 183: (V1_8, False), 184: (V1_8, False), + 185: (V1_8, False), 186: (V1_8, False), + 187: (GND, False), 188: (GND, False), + 189: ('VDAC', False), 190: ('VDAC', False), + 191: (V3_3, False), 192: (V3_3, False), + 193: (V3_3, False), 194: (V3_3, False), + 195: (GND, False), 196: (GND, False), + 197: ('VBAT', False), 198: ('VBAT', False), + 199: ('VBAT', False), 200: ('VBAT', False), + } + +CM3_SODIMM = CM_SODIMM.copy() +CM3_SODIMM.update({ + 4: ('NC / SDX VREF', False), + 6: ('NC / SDX VREF', False), + 8: (GND, False), + 10: ('NC / SDX CLK', False), + 12: ('NC / SDX CMD', False), + 14: (GND, False), + 16: ('NC / SDX D0', False), + 18: ('NC / SDX D1', False), + 20: (GND, False), + 22: ('NC / SDX D2', False), + 24: ('NC / SDX D3', False), + 88: ('HDMI HPD N 1V8', False), + 90: ('EMMC EN N 1V8', False), + }) + +CM4_J6 = { + 1: ('1-2 CAM0+DISP0', False), 2: ('1-2 CAM0+DISP0', False), + 3: ('3-4 CAM0+DISP0', False), 4: ('3-4 CAM0+DISP0', False), + } + +CM4_J2 = { + 1: ('1-2 DISABLE eMMC BOOT', False), 2: ('1-2 DISABLE eMMC BOOT', False), + 3: ('3-4 WRITE-PROT EEPROM', False), 4: ('3-4 WRITE-PROT EEPROM', False), + 5: ('UNKNOWN', False), 6: ('UNKNOWN', False), + 7: ('UNKNOWN', False), 8: ('UNKNOWN', False), + 9: ('UNKNOWN', False), 10: ('UNKNOWN', False), + 11: ('UNKNOWN', False), 12: ('UNKNOWN', False), + 13: ('UNKNOWN', False), 14: ('UNKNOWN', False), + } + +# The following data is sourced from a combination of the following locations: +# +# http://elinux.org/RPi_HardwareHistory +# http://elinux.org/RPi_Low-level_peripherals +# https://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c#l807 +# https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md + +PI_REVISIONS = { + # rev model pcb_rev released soc manufacturer ram storage usb eth wifi bt csi dsi headers board + 0x2: ('B', '1.0', '2012Q1', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV1_P1}, REV1_BOARD, ), + 0x3: ('B', '1.0', '2012Q3', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV1_P1}, REV1_BOARD, ), + 0x4: ('B', '2.0', '2012Q3', 'BCM2835', 'Sony', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0x5: ('B', '2.0', '2012Q4', 'BCM2835', 'Qisda', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0x6: ('B', '2.0', '2012Q4', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0x7: ('A', '2.0', '2013Q1', 'BCM2835', 'Egoman', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), + 0x8: ('A', '2.0', '2013Q1', 'BCM2835', 'Sony', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), + 0x9: ('A', '2.0', '2013Q1', 'BCM2835', 'Qisda', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), + 0xd: ('B', '2.0', '2012Q4', 'BCM2835', 'Egoman', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0xe: ('B', '2.0', '2012Q4', 'BCM2835', 'Sony', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0xf: ('B', '2.0', '2012Q4', 'BCM2835', 'Qisda', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), + 0x10: ('B+', '1.2', '2014Q3', 'BCM2835', 'Sony', 512, 'MicroSD', 4, 1, False, False, 1, 1, {'J8': PLUS_J8}, BPLUS_BOARD, ), + 0x11: ('CM', '1.1', '2014Q2', 'BCM2835', 'Sony', 512, 'eMMC', 1, 0, False, False, 2, 2, {'SODIMM': CM_SODIMM}, CM_BOARD, ), + 0x12: ('A+', '1.1', '2014Q4', 'BCM2835', 'Sony', 256, 'MicroSD', 1, 0, False, False, 1, 1, {'J8': PLUS_J8}, APLUS_BOARD, ), + 0x13: ('B+', '1.2', '2015Q1', 'BCM2835', 'Egoman', 512, 'MicroSD', 4, 1, False, False, 1, 1, {'J8': PLUS_J8}, BPLUS_BOARD, ), + 0x14: ('CM', '1.1', '2014Q2', 'BCM2835', 'Embest', 512, 'eMMC', 1, 0, False, False, 2, 2, {'SODIMM': CM_SODIMM}, CM_BOARD, ), + 0x15: ('A+', '1.1', '2014Q4', 'BCM2835', 'Embest', 256, 'MicroSD', 1, 0, False, False, 1, 1, {'J8': PLUS_J8}, APLUS_BOARD, ), + } + + +# ANSI color codes, for the pretty printers (nothing comprehensive, just enough +# for our purposes) + +class Style(object): + def __init__(self, color=None): + self.color = self._term_supports_color() if color is None else bool(color) + self.effects = { + 'reset': 0, + 'bold': 1, + 'normal': 22, + } + self.colors = { + 'black': 0, + 'red': 1, + 'green': 2, + 'yellow': 3, + 'blue': 4, + 'magenta': 5, + 'cyan': 6, + 'white': 7, + 'default': 9, + } + + @staticmethod + def _term_supports_color(): + try: + stdout_fd = sys.stdout.fileno() + except IOError: + return False + else: + is_a_tty = os.isatty(stdout_fd) + is_windows = sys.platform.startswith('win') + return is_a_tty and not is_windows + + @classmethod + def from_style_content(cls, format_spec): + specs = set(format_spec.split()) + style = specs & {'mono', 'color'} + content = specs - style + if len(style) > 1: + raise ValueError('cannot specify both mono and color styles') + try: + style = style.pop() + except KeyError: + style = 'color' if cls._term_supports_color() else 'mono' + if len(content) > 1: + raise ValueError('cannot specify more than one content element') + try: + content = content.pop() + except KeyError: + content = 'full' + return cls(style == 'color'), content + + def __call__(self, format_spec): + specs = format_spec.split() + codes = [] + fore = True + for spec in specs: + if spec == 'on': + fore = False + else: + try: + codes.append(self.effects[spec]) + except KeyError: + try: + if fore: + codes.append(30 + self.colors[spec]) + else: + codes.append(40 + self.colors[spec]) + except KeyError: + raise ValueError( + 'invalid format specification "%s"' % spec) + if self.color: + return '\x1b[%sm' % (';'.join(str(code) for code in codes)) + else: + return '' + + def __format__(self, format_spec): + if format_spec == '': + return 'color' if self.color else 'mono' + else: + return self(format_spec) + + +class PinInfo(namedtuple('PinInfo', ( + 'number', + 'function', + 'pull_up', + 'row', + 'col', + ))): + """ + This class is a :func:`~collections.namedtuple` derivative used to + represent information about a pin present on a GPIO header. The following + attributes are defined: + + .. attribute:: number + + An integer containing the physical pin number on the header (starting + from 1 in accordance with convention). + + .. attribute:: function + + A string describing the function of the pin. Some common examples + include "GND" (for pins connecting to ground), "3V3" (for pins which + output 3.3 volts), "GPIO9" (for GPIO9 in the Broadcom numbering + scheme), etc. + + .. attribute:: pull_up + + A bool indicating whether the pin has a physical pull-up resistor + permanently attached (this is usually :data:`False` but GPIO2 and GPIO3 + are *usually* :data:`True`). This is used internally by gpiozero to + raise errors when pull-down is requested on a pin with a physical + pull-up resistor. + + .. attribute:: row + + An integer indicating on which row the pin is physically located in + the header (1-based) + + .. attribute:: col + + An integer indicating in which column the pin is physically located + in the header (1-based) + """ + __slots__ = () # workaround python issue #24931 + + +class HeaderInfo(namedtuple('HeaderInfo', ( + 'name', + 'rows', + 'columns', + 'pins', + ))): + """ + This class is a :func:`~collections.namedtuple` derivative used to + represent information about a pin header on a board. The object can be used + in a format string with various custom specifications:: + + from gpiozero import * + + print('{0}'.format(pi_info().headers['J8'])) + print('{0:full}'.format(pi_info().headers['J8'])) + print('{0:col2}'.format(pi_info().headers['P1'])) + print('{0:row1}'.format(pi_info().headers['P1'])) + + "color" and "mono" can be prefixed to format specifications to force the + use of `ANSI color codes`_. If neither is specified, ANSI codes will only + be used if stdout is detected to be a tty:: + + print('{0:color row2}'.format(pi_info().headers['J8'])) # force use of ANSI codes + print('{0:mono row2}'.format(pi_info().headers['P1'])) # force plain ASCII + + The following attributes are defined: + + .. automethod:: pprint + + .. attribute:: name + + The name of the header, typically as it appears silk-screened on the + board (e.g. "P1" or "J8"). + + .. attribute:: rows + + The number of rows on the header. + + .. attribute:: columns + + The number of columns on the header. + + .. attribute:: pins + + A dictionary mapping physical pin numbers to :class:`PinInfo` tuples. + + .. _ANSI color codes: https://en.wikipedia.org/wiki/ANSI_escape_code + """ + __slots__ = () # workaround python issue #24931 + + def _func_style(self, function, style): + if function == V5: + return style('bold red') + elif function in (V3_3, V1_8): + return style('bold cyan') + elif function in (GND, NC): + return style('bold black') + elif function.startswith('GPIO') and function[4:].isdigit(): + return style('bold green') + else: + return style('yellow') + + def _format_full(self, style): + Cell = namedtuple('Cell', ('content', 'align', 'style')) + + lines = [] + for row in range(self.rows): + line = [] + for col in range(self.columns): + pin = (row * self.columns) + col + 1 + try: + pin = self.pins[pin] + cells = [ + Cell(pin.function, '><'[col % 2], self._func_style(pin.function, style)), + Cell('(%d)' % pin.number, '><'[col % 2], ''), + ] + if col % 2: + cells = reversed(cells) + line.extend(cells) + except KeyError: + line.append(Cell('', '<', '')) + lines.append(line) + cols = list(zip(*lines)) + col_lens = [max(len(cell.content) for cell in col) for col in cols] + lines = [ + ' '.join( + '{cell.style}{cell.content:{cell.align}{width}s}{style:reset}'.format( + cell=cell, width=width, style=style) + for cell, width, align in zip(line, col_lens, cycle('><'))) + for line in lines + ] + return '\n'.join(lines) + + def _format_pin(self, pin, style): + return ''.join(( + style('on black'), + ( + ' ' if pin is None else + self._func_style(pin.function, style) + + ('1' if pin.number == 1 else 'o') + ), + style('reset') + )) + + def _format_row(self, row, style): + if row > self.rows: + raise ValueError('invalid row %d for header %s' % (row, self.name)) + start_pin = (row - 1) * self.columns + 1 + return ''.join( + self._format_pin(pin, style) + for n in range(start_pin, start_pin + self.columns) + for pin in (self.pins.get(n),) + ) + + def _format_col(self, col, style): + if col > self.columns: + raise ValueError('invalid col %d for header %s' % (col, self.name)) + return ''.join( + self._format_pin(pin, style) + for n in range(col, self.rows * self.columns + 1, self.columns) + for pin in (self.pins.get(n),) + ) + + def __format__(self, format_spec): + style, content = Style.from_style_content(format_spec) + if content == 'full': + return self._format_full(style) + elif content.startswith('row') and content[3:].isdigit(): + return self._format_row(int(content[3:]), style) + elif content.startswith('col') and content[3:].isdigit(): + return self._format_col(int(content[3:]), style) + else: + raise ValueError('Invalid format specifier') + + def pprint(self, color=None): + """ + Pretty-print a diagram of the header pins. + + If *color* is :data:`None` (the default, the diagram will include ANSI + color codes if stdout is a color-capable terminal). Otherwise *color* + can be set to :data:`True` or :data:`False` to force color or + monochrome output. + """ + print('{0:{style} full}'.format(self, style=Style(color))) + + +class PiBoardInfo(namedtuple('PiBoardInfo', ( + 'revision', + 'model', + 'pcb_revision', + 'released', + 'soc', + 'manufacturer', + 'memory', + 'storage', + 'usb', + 'usb3', + 'ethernet', + 'eth_speed', + 'wifi', + 'bluetooth', + 'csi', + 'dsi', + 'headers', + 'board', + ))): + """ + This class is a :func:`~collections.namedtuple` derivative used to + represent information about a particular model of Raspberry Pi. While it is + a tuple, it is strongly recommended that you use the following named + attributes to access the data contained within. The object can be used + in format strings with various custom format specifications:: + + from gpiozero import * + + print('{0}'.format(pi_info())) + print('{0:full}'.format(pi_info())) + print('{0:board}'.format(pi_info())) + print('{0:specs}'.format(pi_info())) + print('{0:headers}'.format(pi_info())) + + "color" and "mono" can be prefixed to format specifications to force the + use of `ANSI color codes`_. If neither is specified, ANSI codes will only + be used if stdout is detected to be a tty:: + + print('{0:color board}'.format(pi_info())) # force use of ANSI codes + print('{0:mono board}'.format(pi_info())) # force plain ASCII + + .. _ANSI color codes: https://en.wikipedia.org/wiki/ANSI_escape_code + + .. automethod:: physical_pin + + .. automethod:: physical_pins + + .. automethod:: pprint + + .. automethod:: pulled_up + + .. automethod:: to_gpio + + .. attribute:: revision + + A string indicating the revision of the Pi. This is unique to each + revision and can be considered the "key" from which all other + attributes are derived. However, in itself the string is fairly + meaningless. + + .. attribute:: model + + A string containing the model of the Pi (for example, "B", "B+", "A+", + "2B", "CM" (for the Compute Module), or "Zero"). + + .. attribute:: pcb_revision + + A string containing the PCB revision number which is silk-screened onto + the Pi (on some models). + + .. note:: + + This is primarily useful to distinguish between the model B + revision 1.0 and 2.0 (not to be confused with the model 2B) which + had slightly different pinouts on their 26-pin GPIO headers. + + .. attribute:: released + + A string containing an approximate release date for this revision of + the Pi (formatted as yyyyQq, e.g. 2012Q1 means the first quarter of + 2012). + + .. attribute:: soc + + A string indicating the SoC (`system on a chip`_) that this revision + of the Pi is based upon. + + .. attribute:: manufacturer + + A string indicating the name of the manufacturer (usually "Sony" but a + few others exist). + + .. attribute:: memory + + An integer indicating the amount of memory (in Mb) connected to the + SoC. + + .. note:: + + This can differ substantially from the amount of RAM available + to the operating system as the GPU's memory is shared with the + CPU. When the camera module is activated, at least 128Mb of RAM + is typically reserved for the GPU. + + .. attribute:: storage + + A string indicating the type of bootable storage used with this + revision of Pi, e.g. "SD", "MicroSD", or "eMMC" (for the Compute + Module). + + .. attribute:: usb + + An integer indicating how many USB ports are physically present on + this revision of the Pi, of any type. + + .. note:: + + This does *not* include the micro-USB or USB-C port used to power + the Pi. + + .. attribute:: usb3 + + An integer indicating how many of the USB ports are USB3 ports on this + revision of the Pi. + + .. attribute:: ethernet + + An integer indicating how many Ethernet ports are physically present + on this revision of the Pi. + + .. attribute:: eth_speed + + An integer indicating the maximum speed (in Mbps) of the Ethernet ports + (if any). If no Ethernet ports are present, this is 0. + + .. attribute:: wifi + + A bool indicating whether this revision of the Pi has wifi built-in. + + .. attribute:: bluetooth + + A bool indicating whether this revision of the Pi has bluetooth + built-in. + + .. attribute:: csi + + An integer indicating the number of CSI (camera) ports available on + this revision of the Pi. + + .. attribute:: dsi + + An integer indicating the number of DSI (display) ports available on + this revision of the Pi. + + .. attribute:: headers + + A dictionary which maps header labels to :class:`HeaderInfo` tuples. + For example, to obtain information about header P1 you would query + ``headers['P1']``. To obtain information about pin 12 on header J8 you + would query ``headers['J8'].pins[12]``. + + A rendered version of this data can be obtained by using the + :class:`PiBoardInfo` object in a format string:: + + from gpiozero import * + print('{0:headers}'.format(pi_info())) + + .. attribute:: board + + An ASCII art rendition of the board, primarily intended for console + pretty-print usage. A more usefully rendered version of this data can + be obtained by using the :class:`PiBoardInfo` object in a format + string. For example:: + + from gpiozero import * + print('{0:board}'.format(pi_info())) + + .. _system on a chip: https://en.wikipedia.org/wiki/System_on_a_chip + """ + __slots__ = () # workaround python issue #24931 + + @classmethod + def from_revision(cls, revision): + if revision & 0x800000: + # New-style revision, parse information from bit-pattern: + # + # MSB -----------------------> LSB + # NOQuuuWuFMMMCCCCPPPPTTTTTTTTRRRR + # + # N - Overvoltage (0=allowed, 1=disallowed) + # O - OTP programming (0=allowed, 1=disallowed) + # Q - OTP read (0=allowed, 1=disallowed) + # u - Unused + # W - Warranty bit (0=intact, 1=voided by overclocking) + # F - New flag (1=valid new-style revision, 0=old-style) + # MMM - Memory size (0=256, 1=512, 2=1024) + # CCCC - Manufacturer (0=Sony, 1=Egoman, 2=Embest, 3=Sony Japan, 4=Embest, 5=Stadium) + # PPPP - Processor (0=2835, 1=2836, 2=2837) + # TTTTTTTT - Type (0=A, 1=B, 2=A+, 3=B+, 4=2B, 5=Alpha (??), 6=CM, + # 8=3B, 9=Zero, 10=CM3, 12=Zero W, 13=3B+, 14=3A+) + # RRRR - Revision (0, 1, 2, etc.) + revcode_memory = (revision & 0x700000) >> 20 + revcode_manufacturer = (revision & 0xf0000) >> 16 + revcode_processor = (revision & 0xf000) >> 12 + revcode_type = (revision & 0xff0) >> 4 + revcode_revision = (revision & 0x0f) + model = { + 0x0: 'A', + 0x1: 'B', + 0x2: 'A+', + 0x3: 'B+', + 0x4: '2B', + 0x6: 'CM', + 0x8: '3B', + 0x9: 'Zero', + 0xa: 'CM3', + 0xc: 'Zero W', + 0xd: '3B+', + 0xe: '3A+', + 0x10: 'CM3+', + 0x11: '4B', + 0x13: '400', + 0x14: 'CM4', + }.get(revcode_type, '???') + if model in ('A', 'B'): + pcb_revision = { + 0: '1.0', # is this right? + 1: '1.0', + 2: '2.0', + }.get(revcode_revision, 'Unknown') + else: + pcb_revision = '1.%d' % revcode_revision + soc = { + 0: 'BCM2835', + 1: 'BCM2836', + 2: 'BCM2837', + 3: 'BCM2711', + }.get(revcode_processor, 'Unknown') + manufacturer = { + 0: 'Sony', + 1: 'Egoman', + 2: 'Embest', + 3: 'Sony Japan', + 4: 'Embest', + 5: 'Stadium', + }.get(revcode_manufacturer, 'Unknown') + memory = { + 0: 256, + 1: 512, + 2: 1024, + 3: 2048, + 4: 4096, + 5: 8192, + }.get(revcode_memory, None) + released = { + 'A': '2013Q1', + 'B': '2012Q1' if pcb_revision == '1.0' else '2012Q4', + 'A+': '2014Q4' if memory == 512 else '2016Q3', + 'B+': '2014Q3', + '2B': '2015Q1' if pcb_revision in ('1.0', '1.1') else '2016Q3', + 'CM': '2014Q2', + '3B': '2016Q1' if manufacturer in ('Sony', 'Embest') else '2016Q4', + 'Zero': '2015Q4' if pcb_revision == '1.2' else '2016Q2', + 'CM3': '2017Q1', + 'Zero W': '2017Q1', + '3B+': '2018Q1', + '3A+': '2018Q4', + 'CM3+': '2019Q1', + '4B': '2020Q2' if memory == 8192 else '2019Q2', + 'CM4': '2020Q4', + '400': '2020Q4', + }.get(model, 'Unknown') + storage = { + 'A': 'SD', + 'B': 'SD', + 'CM': 'eMMC', + 'CM3': 'eMMC / off-board', + 'CM3+': 'eMMC / off-board', + 'CM4': 'eMMC / off-board', + }.get(model, 'MicroSD') + usb = { + 'A': 1, + 'A+': 1, + 'Zero': 1, + 'Zero W': 1, + 'B': 2, + 'CM': 1, + 'CM3': 1, + '3A+': 1, + 'CM3+': 1, + 'CM4': 2, + '400': 3, + }.get(model, 4) + usb3 = { + '4B': 2, + '400': 2, + }.get(model, 0) + ethernet = { + 'A': 0, + 'A+': 0, + 'Zero': 0, + 'Zero W': 0, + 'CM': 0, + 'CM3': 0, + '3A+': 0, + 'CM3+': 0, + }.get(model, 1) + eth_speed = { + 'B': 100, + 'B+': 100, + '2B': 100, + '3B': 100, + '3B+': 300, + '4B': 1000, + '400': 1000, + 'CM4': 1000, + }.get(model, 0) + wifi = { + '3B': True, + 'Zero W': True, + '3B+': True, + '3A+': True, + '4B': True, + '400': True, + 'CM4': True, + }.get(model, False) + bluetooth = { + '3B': True, + 'Zero W': True, + '3B+': True, + '3A+': True, + '4B': True, + '400': True, + 'CM4': True, + }.get(model, False) + csi = { + 'Zero': 0 if pcb_revision == '1.0' else 1, + 'Zero W': 1, + 'CM': 2, + 'CM3': 2, + 'CM3+': 2, + '400': 0, + 'CM4': 2, + }.get(model, 1) + dsi = { + 'Zero': 0, + 'Zero W': 0, + 'CM': 2, + 'CM3': 2, + 'CM3+': 2, + }.get(model, csi) + headers = { + 'A': {'P1': REV2_P1, 'P5': REV2_P5}, + 'B': {'P1': REV1_P1} if pcb_revision == '1.0' else {'P1': REV2_P1, 'P5': REV2_P5}, + 'CM': {'SODIMM': CM_SODIMM}, + 'CM3': {'SODIMM': CM3_SODIMM}, + 'CM3+': {'SODIMM': CM3_SODIMM}, + '3B+': {'J8': PLUS_J8, 'POE': PLUS_POE}, + '4B': {'J8': PLUS_J8, 'POE': PLUS_POE}, + 'CM4': {'J8': PLUS_J8, 'J2': CM4_J2, 'J6': CM4_J6, 'POE': PLUS_POE}, + }.get(model, {'J8': PLUS_J8}) + board = { + 'A': A_BOARD, + 'B': REV1_BOARD if pcb_revision == '1.0' else REV2_BOARD, + 'A+': APLUS_BOARD, + 'CM': CM_BOARD, + 'CM3': CM_BOARD, + 'CM3+': CM3PLUS_BOARD, + 'Zero': ZERO12_BOARD if pcb_revision == '1.2' else ZERO13_BOARD, + 'Zero W': ZERO13_BOARD, + '3A+': A3PLUS_BOARD, + '3B+': B3PLUS_BOARD, + '4B': B4_BOARD, + 'CM4': CM4_BOARD, + '400': P400_BOARD, + }.get(model, BPLUS_BOARD) + else: + # Old-style revision, use the lookup table + try: + ( + model, + pcb_revision, + released, + soc, + manufacturer, + memory, + storage, + usb, + ethernet, + wifi, + bluetooth, + csi, + dsi, + headers, + board, + ) = PI_REVISIONS[revision] + usb3 = 0 + eth_speed = ethernet * 100 + except KeyError: + raise PinUnknownPi('unknown old-style revision "%x"' % revision) + headers = { + header: HeaderInfo(name=header, rows=max(header_data) // 2, columns=2, pins={ + number: PinInfo( + number=number, function=function, pull_up=pull_up, + row=row + 1, col=col + 1) + for number, (function, pull_up) in header_data.items() + for row, col in (divmod(number - 1, 2),) + }) + for header, header_data in headers.items() + } + return cls( + '%04x' % revision, + model, + pcb_revision, + released, + soc, + manufacturer, + memory, + storage, + usb, + usb3, + ethernet, + eth_speed, + wifi, + bluetooth, + csi, + dsi, + headers, + board, + ) + + def physical_pins(self, function): + """ + Return the physical pins supporting the specified *function* as tuples + of ``(header, pin_number)`` where *header* is a string specifying the + header containing the *pin_number*. Note that the return value is a + :class:`set` which is not indexable. Use :func:`physical_pin` if you + are expecting a single return value. + + :param str function: + The pin function you wish to search for. Usually this is something + like "GPIO9" for Broadcom GPIO pin 9, or "GND" for all the pins + connecting to electrical ground. + """ + return { + (header, pin.number) + for (header, info) in self.headers.items() + for pin in info.pins.values() + if pin.function == function + } + + def physical_pin(self, function): + """ + Return the physical pin supporting the specified *function*. If no pins + support the desired *function*, this function raises :exc:`PinNoPins`. + If multiple pins support the desired *function*, :exc:`PinMultiplePins` + will be raised (use :func:`physical_pins` if you expect multiple pins + in the result, such as for electrical ground). + + :param str function: + The pin function you wish to search for. Usually this is something + like "GPIO9" for Broadcom GPIO pin 9. + """ + result = self.physical_pins(function) + if len(result) > 1: + raise PinMultiplePins('multiple pins can be used for %s' % function) + elif result: + return result.pop() + else: + raise PinNoPins('no pins can be used for %s' % function) + + def pulled_up(self, function): + """ + Returns a bool indicating whether a physical pull-up is attached to + the pin supporting the specified *function*. Either :exc:`PinNoPins` + or :exc:`PinMultiplePins` may be raised if the function is not + associated with a single pin. + + :param str function: + The pin function you wish to determine pull-up for. Usually this is + something like "GPIO9" for Broadcom GPIO pin 9. + """ + try: + header, number = self.physical_pin(function) + except PinNoPins: + return False + else: + return self.headers[header].pins[number].pull_up + + def to_gpio(self, spec): + """ + Parses a pin *spec*, returning the equivalent Broadcom GPIO port number + or raising a :exc:`ValueError` exception if the spec does not represent + a GPIO port. + + The *spec* may be given in any of the following forms: + + * An integer, which will be accepted as a GPIO number + * 'GPIOn' where n is the GPIO number + * 'WPIn' where n is the `wiringPi`_ pin number + * 'BCMn' where n is the GPIO number (alias of GPIOn) + * 'BOARDn' where n is the physical pin number on the main header + * 'h:n' where h is the header name and n is the physical pin number + (for example J8:5 is physical pin 5 on header J8, which is the main + header on modern Raspberry Pis) + + .. _wiringPi: http://wiringpi.com/pins/ + """ + if isinstance(spec, int): + if not 0 <= spec < 54: + raise PinInvalidPin('invalid GPIO port %d specified ' + '(range 0..53) ' % spec) + return spec + else: + if isinstance(spec, bytes): + spec = spec.decode('ascii') + spec = spec.upper() + if spec.isdigit(): + return self.to_gpio(int(spec)) + if spec.startswith('GPIO') and spec[4:].isdigit(): + return self.to_gpio(int(spec[4:])) + elif spec.startswith('BCM') and spec[3:].isdigit(): + return self.to_gpio(int(spec[3:])) + elif spec.startswith('WPI') and spec[3:].isdigit(): + main_head = 'P1' if 'P1' in self.headers else 'J8' + try: + return self.to_gpio({ + 0: '%s:11' % main_head, + 1: '%s:12' % main_head, + 2: '%s:13' % main_head, + 3: '%s:15' % main_head, + 4: '%s:16' % main_head, + 5: '%s:18' % main_head, + 6: '%s:22' % main_head, + 7: '%s:7' % main_head, + 8: '%s:3' % main_head, + 9: '%s:5' % main_head, + 10: '%s:24' % main_head, + 11: '%s:26' % main_head, + 12: '%s:19' % main_head, + 13: '%s:21' % main_head, + 14: '%s:23' % main_head, + 15: '%s:8' % main_head, + 16: '%s:10' % main_head, + 17: 'P5:3', + 18: 'P5:4', + 19: 'P5:5', + 20: 'P5:6', + 21: '%s:29' % main_head, + 22: '%s:31' % main_head, + 23: '%s:33' % main_head, + 24: '%s:35' % main_head, + 25: '%s:37' % main_head, + 26: '%s:32' % main_head, + 27: '%s:36' % main_head, + 28: '%s:38' % main_head, + 29: '%s:40' % main_head, + 30: '%s:27' % main_head, + 31: '%s:28' % main_head, + }[int(spec[3:])]) + except KeyError: + raise PinInvalidPin('%s is not a valid wiringPi pin' % spec) + elif ':' in spec: + header, pin = spec.split(':', 1) + if pin.isdigit(): + try: + header = self.headers[header] + except KeyError: + raise PinInvalidPin( + 'there is no %s header on this Pi' % header) + try: + function = header.pins[int(pin)].function + except KeyError: + raise PinInvalidPin( + 'no such pin %s on header %s' % (pin, header.name)) + if function.startswith('GPIO') and function[4:].isdigit(): + return self.to_gpio(int(function[4:])) + else: + raise PinInvalidPin('%s is not a GPIO pin' % spec) + elif spec.startswith('BOARD') and spec[5:].isdigit(): + main_head = ({'P1', 'J8', 'SODIMM'} & set(self.headers)).pop() + return self.to_gpio('%s:%s' % (main_head, spec[5:])) + raise PinInvalidPin('%s is not a valid pin spec' % spec) + + def __repr__(self): + return '{cls}({fields})'.format( + cls=self.__class__.__name__, + fields=', '.join( + ( + '{name}=...' if name in ('headers', 'board') else + '{name}={value!r}').format(name=name, value=value) + for name, value in zip(self._fields, self) + ) + ) + + def __format__(self, format_spec): + style, content = Style.from_style_content(format_spec) + if content == 'full': + return dedent("""\ + {self:{style} board} + + {self:{style} specs} + + {self:{style} headers}""" + ).format(self=self, style=style) + elif content == 'board': + kw = self._asdict() + kw.update({ + name: header + for name, header in self.headers.items() + }) + return self.board.format(style=style, **kw) + elif content == 'specs': + specs = self._asdict() + if specs['memory'] < 1024: + specs['memory_unit'] = "MB" + else: + specs['memory'] = int(specs['memory'] / 1024) + specs['memory_unit'] = "GB" + return dedent("""\ + {style:bold}Revision {style:reset}: {revision} + {style:bold}SoC {style:reset}: {soc} + {style:bold}RAM {style:reset}: {memory}{memory_unit} + {style:bold}Storage {style:reset}: {storage} + {style:bold}USB ports {style:reset}: {usb} (of which {usb3} USB3) + {style:bold}Ethernet ports {style:reset}: {ethernet} ({eth_speed}Mbps max. speed) + {style:bold}Wi-fi {style:reset}: {wifi} + {style:bold}Bluetooth {style:reset}: {bluetooth} + {style:bold}Camera ports (CSI) {style:reset}: {csi} + {style:bold}Display ports (DSI){style:reset}: {dsi}""" + ).format(style=style, **specs) + elif content == 'headers': + return '\n\n'.join( + dedent("""\ + {style:bold}{header.name}{style:reset}: + {header:{style} full}""" + ).format(header=header, style=style) + for header in sorted(self.headers.values(), key=attrgetter('name')) + ) + else: + raise ValueError('Invalid format specifier') + + def pprint(self, color=None): + """ + Pretty-print a representation of the board along with header diagrams. + + If *color* is :data:`None` (the default), the diagram will include ANSI + color codes if stdout is a color-capable terminal. Otherwise *color* + can be set to :data:`True` or :data:`False` to force color or monochrome + output. + """ + print('{0:{style} full}'.format(self, style=Style(color))) + + +def pi_info(revision=None): + """ + Returns a :class:`PiBoardInfo` instance containing information about a + *revision* of the Raspberry Pi. + + :param str revision: + The revision of the Pi to return information about. If this is omitted + or :data:`None` (the default), then the library will attempt to determine + the model of Pi it is running on and return information about that. + """ + if revision is None: + if Device.pin_factory is None: + Device.pin_factory = Device._default_pin_factory() + result = Device.pin_factory.pi_info + if result is None: + raise PinUnknownPi('The default pin_factory is not attached to a Pi') + else: + return result + else: + if isinstance(revision, bytes): + revision = revision.decode('ascii') + if isinstance(revision, str): + revision = int(revision, base=16) + else: + # be nice to people passing an int (or something numeric anyway) + revision = int(revision) + return PiBoardInfo.from_revision(revision) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/lgpio.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/lgpio.py new file mode 100644 index 0000000..4d9331e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/lgpio.py @@ -0,0 +1,359 @@ +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import os + +import lgpio + +from . import SPI +from .pi import spi_port_device +from .local import LocalPiFactory, LocalPiPin +from ..mixins import SharedMixin +from ..exc import ( + PinInvalidFunction, + PinSetInput, + PinFixedPull, + PinInvalidPull, + PinInvalidBounce, + PinInvalidState, + SPIBadArgs, + SPIInvalidClockMode, + PinPWMFixedValue, + DeviceClosed +) + + +class LGPIOFactory(LocalPiFactory): + """ + Extends :class:`~gpiozero.pins.local.LocalPiFactory`. Uses the `lgpio`_ + library to interface to the local computer's GPIO pins. The lgpio library + simply talks to Linux gpiochip devices; it is not specific to the Raspberry + Pi although this class is currently constructed under the assumption that + it is running on a Raspberry Pi. + + You can construct lgpio pins manually like so:: + + from gpiozero.pins.lgpio import LGPIOFactory + from gpiozero import LED + + factory = LGPIOFactory(chip=0) + led = LED(12, pin_factory=factory) + + The *chip* parameter to the factory constructor specifies which gpiochip + device to attempt to open. It defaults to 0 and thus doesn't normally need + to be specified (the example above only includes it for completeness). + + The lgpio library relies on access to the :file:`/dev/gpiochip*` devices. + If you run into issues, please check that your user has read/write access + to the specific gpiochip device you are attempting to open (0 by default). + + .. _lgpio: http://abyz.me.uk/lg/py_lgpio.html + """ + def __init__(self, chip=0): + super(LGPIOFactory, self).__init__() + self._handle = lgpio.gpiochip_open(chip) + self._chip = chip + self.pin_class = LGPIOPin + + def close(self): + super(LGPIOFactory, self).close() + if self._handle is not None: + lgpio.gpiochip_close(self._handle) + self._handle = None + + @property + def chip(self): + return self._chip + + def _get_spi_class(self, shared, hardware): + # support via lgpio instead of spidev + if hardware: + return [LGPIOHardwareSPI, LGPIOHardwareSPIShared][shared] + return super(LGPIOFactory, self)._get_spi_class(shared, hardware=False) + + +class LGPIOPin(LocalPiPin): + """ + Extends :class:`~gpiozero.pins.local.LocalPiPin`. Pin implementation for + the `lgpio`_ library. See :class:`LGPIOFactory` for more information. + + .. _lgpio: http://abyz.me.uk/lg/py_lgpio.html + """ + GPIO_IS_KERNEL = 1 << 0 + GPIO_IS_OUT = 1 << 1 + GPIO_IS_ACTIVE_LOW = 1 << 2 + GPIO_IS_OPEN_DRAIN = 1 << 3 + GPIO_IS_OPEN_SOURCE = 1 << 4 + GPIO_IS_BIAS_PULL_UP = 1 << 5 + GPIO_IS_BIAS_PULL_DOWN = 1 << 6 + GPIO_IS_BIAS_DISABLE = 1 << 7 + GPIO_IS_LG_INPUT = 1 << 8 + GPIO_IS_LG_OUTPUT = 1 << 9 + GPIO_IS_LG_ALERT = 1 << 10 + GPIO_IS_LG_GROUP = 1 << 11 + + GPIO_LINE_FLAGS_MASK = ( + GPIO_IS_ACTIVE_LOW | GPIO_IS_OPEN_DRAIN | GPIO_IS_OPEN_SOURCE | + GPIO_IS_BIAS_PULL_UP | GPIO_IS_BIAS_PULL_DOWN | GPIO_IS_BIAS_DISABLE) + + GPIO_EDGES = { + 'both': lgpio.BOTH_EDGES, + 'rising': lgpio.RISING_EDGE, + 'falling': lgpio.FALLING_EDGE, + } + + GPIO_EDGES_NAMES = {v: k for (k, v) in GPIO_EDGES.items()} + + def __init__(self, factory, number): + super(LGPIOPin, self).__init__(factory, number) + self._pwm = None + self._bounce = None + self._callback = None + self._edges = lgpio.BOTH_EDGES + lgpio.gpio_claim_input( + self.factory._handle, self.number, lgpio.SET_BIAS_DISABLE) + + def close(self): + if self.factory._handle is not None: + # Closing is really just "resetting" the function of the pin; + # we let the factory close deal with actually freeing stuff + lgpio.gpio_claim_input( + self.factory._handle, self.number, lgpio.SET_BIAS_DISABLE) + + def _get_function(self): + mode = lgpio.gpio_get_mode(self.factory._handle, self.number) + return ['input', 'output'][bool(mode & self.GPIO_IS_OUT)] + + def _set_function(self, value): + if self._callback is not None: + self._callback.cancel() + self._callback = None + try: + { + 'input': lgpio.gpio_claim_input, + 'output': lgpio.gpio_claim_output, + }[value](self.factory._handle, self.number) + except KeyError: + raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self)) + + def _get_state(self): + if self._pwm: + return self._pwm[1] / 100 + else: + return bool(lgpio.gpio_read(self.factory._handle, self.number)) + + def _set_state(self, value): + if self._pwm: + freq, duty = self._pwm + self._pwm = (freq, int(value * 100)) + try: + lgpio.tx_pwm(self.factory._handle, self.number, *self._pwm) + except lgpio.error: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + elif self.function == 'input': + raise PinSetInput('cannot set state of pin %r' % self) + else: + lgpio.gpio_write(self.factory._handle, self.number, bool(value)) + + def _get_pull(self): + mode = lgpio.gpio_get_mode(self.factory._handle, self.number) + if mode & self.GPIO_IS_BIAS_PULL_UP: + return 'up' + elif mode & self.GPIO_IS_BIAS_PULL_DOWN: + return 'down' + else: + return 'floating' + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + flags = { + 'up': lgpio.SET_BIAS_PULL_UP, + 'down': lgpio.SET_BIAS_PULL_DOWN, + 'floating': lgpio.SET_BIAS_DISABLE, + }[value] + except KeyError: + raise PinInvalidPull('invalid pull "%s" for pin %r' % (value, self)) + else: + # Simply calling gpio_claim_input is insufficient to change the + # line flags on a pin; it needs to be freed and re-claimed + lgpio.gpio_free(self.factory._handle, self.number) + lgpio.gpio_claim_input(self.factory._handle, self.number, flags) + + def _get_frequency(self): + if self._pwm: + freq, duty = self._pwm + return freq + else: + return None + + def _set_frequency(self, value): + if not self._pwm and value is not None and value > 0: + if self.function != 'output': + raise PinPWMFixedValue('cannot start PWM on pin %r' % self) + lgpio.tx_pwm(self.factory._handle, self.number, value, 0) + self._pwm = (value, 0) + elif self._pwm and value is not None and value > 0: + freq, duty = self._pwm + lgpio.tx_pwm(self.factory._handle, self.number, value, duty) + self._pwm = (value, duty) + elif self._pwm and (value is None or value == 0): + lgpio.tx_pwm(self.factory._handle, self.number, 0, 0) + self._pwm = None + + def _get_bounce(self): + return None if not self._bounce else self._bounce / 1000000 + + def _set_bounce(self, value): + if value is None: + value = 0 + elif value < 0: + raise PinInvalidBounce('bounce must be 0 or greater') + value = int(value * 1000000) + lgpio.gpio_set_debounce_micros(self.factory._handle, self.number, value) + self._bounce = value + + def _get_edges(self): + return self.GPIO_EDGES_NAMES[self._edges] + + def _set_edges(self, value): + f = self.when_changed + self.when_changed = None + try: + self._edges = self.GPIO_EDGES[value] + finally: + self.when_changed = f + + def _call_when_changed(self, chip, gpio, level, ticks): + super(LGPIOPin, self)._call_when_changed(ticks / 1000000000, level) + + def _enable_event_detect(self): + lgpio.gpio_claim_alert( + self.factory._handle, self.number, self._edges, + lgpio.gpio_get_mode(self.factory._handle, self.number) & + self.GPIO_LINE_FLAGS_MASK) + self._callback = lgpio.callback( + self.factory._handle, self.number, self._edges, + self._call_when_changed) + + def _disable_event_detect(self): + if self._callback is not None: + self._callback.cancel() + self._callback = None + lgpio.gpio_claim_input( + self.factory._handle, self.number, + lgpio.gpio_get_mode(self.factory._handle, self.number) & + self.GPIO_LINE_FLAGS_MASK) + + +class LGPIOHardwareSPI(SPI): + """ + Hardware SPI implementation for the `lgpio`_ library. Uses the ``spi_*`` + functions from the lgpio API. + + .. _lgpio: http://abyz.me.uk/lg/py_lgpio.html + """ + def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + port, device = spi_port_device( + clock_pin, mosi_pin, miso_pin, select_pin) + self._port = port + self._device = device + self._baud = 500000 + self._spi_flags = 0 + self._handle = None + super(LGPIOHardwareSPI, self).__init__(pin_factory=pin_factory) + to_reserve = {clock_pin, select_pin} + if mosi_pin is not None: + to_reserve.add(mosi_pin) + if miso_pin is not None: + to_reserve.add(miso_pin) + self.pin_factory.reserve_pins(self, *to_reserve) + self._handle = lgpio.spi_open(port, device, self._baud, self._spi_flags) + + def _conflicts_with(self, other): + return not ( + isinstance(other, LGPIOHardwareSPI) and + (self._port, self._device) != (other._port, other._device) + ) + + def close(self): + if not self.closed: + lgpio.spi_close(self._handle) + self._handle = None + self.pin_factory.release_all(self) + super(LGPIOHardwareSPI, self).close() + + @property + def closed(self): + return self._handle is None + + def __repr__(self): + try: + self._check_open() + return 'SPI(port=%d, device=%d)' % (self._port, self._device) + except DeviceClosed: + return 'SPI(closed)' + + def _get_clock_mode(self): + return self._spi_flags + + def _set_clock_mode(self, value): + self._check_open() + if not 0 <= value < 4: + raise SPIInvalidClockMode("%d is not a valid SPI clock mode" % value) + lgpio.spi_close(self._handle) + self._spi_flags = value + self._handle = lgpio.spi_open( + self._port, self._device, self._baud, self._spi_flags) + + def _get_rate(self): + return self._baud + + def _set_rate(self, value): + self._check_open() + value = int(value) + lgpio.spi_close(self._handle) + self._baud = value + self._handle = lgpio.spi_open( + self._port, self._device, self._baud, self._spi_flags) + + def read(self, n): + self._check_open() + count, data = lgpio.spi_read(self._handle, n) + if count < 0: + raise IOError('SPI transfer error %d' % count) + return [int(b) for b in data] + + def write(self, data): + self._check_open() + count = lgpio.spi_write(self._handle, data) + if count < 0: + raise IOError('SPI transfer error %d' % count) + return len(data) + + def transfer(self, data): + self._check_open() + count, data = lgpio.spi_xfer(self._handle, data) + if count < 0: + raise IOError('SPI transfer error %d' % count) + return [int(b) for b in data] + + +class LGPIOHardwareSPIShared(SharedMixin, LGPIOHardwareSPI): + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + return (clock_pin, select_pin) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/local.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/local.py new file mode 100644 index 0000000..2e65708 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/local.py @@ -0,0 +1,308 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2020 Ben Nuttall +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +nstr = str +str = type('') + +import io +import errno +import struct +import warnings +from collections import defaultdict +from threading import Lock +try: + from time import monotonic +except ImportError: + from time import time as monotonic + +try: + from spidev import SpiDev +except ImportError: + SpiDev = None + +from . import SPI +from .pi import PiFactory, PiPin, SPI_HARDWARE_PINS, spi_port_device +from .spi import SPISoftwareBus +from ..devices import Device, SharedMixin +from ..output_devices import OutputDevice +from ..exc import DeviceClosed, PinUnknownPi, SPIInvalidClockMode + + +def get_pi_revision(): + revision = None + try: + with io.open('/proc/device-tree/system/linux,revision', 'rb') as f: + revision = hex(struct.unpack(nstr('>L'), f.read(4))[0])[2:] + except IOError as e: + if e.errno != errno.ENOENT: + raise e + with io.open('/proc/cpuinfo', 'r') as f: + for line in f: + if line.startswith('Revision'): + revision = line.split(':')[1].strip().lower() + if revision is not None: + overvolted = revision.startswith('100') + if overvolted: + revision = revision[-4:] + return int(revision, base=16) + raise PinUnknownPi( + 'unable to locate Pi revision in /proc/device-tree or /proc/cpuinfo') + + +class LocalPiFactory(PiFactory): + """ + Extends :class:`~gpiozero.pins.pi.PiFactory`. Abstract base class + representing pins attached locally to a Pi. This forms the base class for + local-only pin interfaces (:class:`~gpiozero.pins.rpigpio.RPiGPIOPin`, + :class:`~gpiozero.pins.rpio.RPIOPin`, and + :class:`~gpiozero.pins.native.NativePin`). + """ + pins = {} + _reservations = defaultdict(list) + _res_lock = Lock() + + def __init__(self): + super(LocalPiFactory, self).__init__() + # Override the reservations and pins dict to be this class' attributes. + # This is a bit of a dirty hack, but ensures that anyone evil enough to + # mix pin implementations doesn't try and control the same pin with + # different backends + self.pins = LocalPiFactory.pins + self._reservations = LocalPiFactory._reservations + self._res_lock = LocalPiFactory._res_lock + + def _get_revision(self): + return get_pi_revision() + + def _get_spi_class(self, shared, hardware): + return { + (False, True): LocalPiHardwareSPI, + (True, True): LocalPiHardwareSPIShared, + (False, False): LocalPiSoftwareSPI, + (True, False): LocalPiSoftwareSPIShared, + }[shared, hardware] + + @staticmethod + def ticks(): + return monotonic() + + @staticmethod + def ticks_diff(later, earlier): + # NOTE: technically the guarantee to always return a positive result + # cannot be maintained in versions where monotonic() is not available + # and we fall back to time(). However, in that situation we've no + # access to a true monotonic source, and no idea how far the clock has + # skipped back so this is the best we can do anyway. + return max(0, later - earlier) + + +class LocalPiPin(PiPin): + """ + Extends :class:`~gpiozero.pins.pi.PiPin`. Abstract base class representing + a multi-function GPIO pin attached to the local Raspberry Pi. + """ + def _call_when_changed(self, ticks=None, state=None): + """ + Overridden to provide default ticks from the local Pi factory. + + .. warning:: + + The local pin factory uses a seconds-based monotonic value for + its ticks but you *must not* rely upon this behaviour. Ticks are + an opaque value that should only be compared with the associated + :meth:`Factory.ticks_diff` method. + """ + super(LocalPiPin, self)._call_when_changed( + self._factory.ticks() if ticks is None else ticks, + self.state if state is None else state) + + +class LocalPiHardwareSPI(SPI): + def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + self._port, self._device = spi_port_device( + clock_pin, mosi_pin, miso_pin, select_pin) + self._interface = None + if SpiDev is None: + raise ImportError('failed to import spidev') + super(LocalPiHardwareSPI, self).__init__(pin_factory=pin_factory) + to_reserve = {clock_pin, select_pin} + if mosi_pin is not None: + to_reserve.add(mosi_pin) + if miso_pin is not None: + to_reserve.add(miso_pin) + self.pin_factory.reserve_pins(self, *to_reserve) + self._interface = SpiDev() + self._interface.open(self._port, self._device) + self._interface.max_speed_hz = 500000 + + def close(self): + if self._interface is not None: + self._interface.close() + self._interface = None + self.pin_factory.release_all(self) + super(LocalPiHardwareSPI, self).close() + + @property + def closed(self): + return self._interface is None + + def __repr__(self): + try: + self._check_open() + return 'SPI(port=%d, device=%d)' % (self._port, self._device) + except DeviceClosed: + return 'SPI(closed)' + + def transfer(self, data): + """ + Writes data (a list of integer words where each word is assumed to have + :attr:`bits_per_word` bits or less) to the SPI interface, and reads an + equivalent number of words, returning them as a list of integers. + """ + return self._interface.xfer2(data) + + def _get_clock_mode(self): + return self._interface.mode + + def _set_clock_mode(self, value): + self._interface.mode = value + + def _get_lsb_first(self): + return self._interface.lsbfirst + + def _set_lsb_first(self, value): + self._interface.lsbfirst = bool(value) + + def _get_select_high(self): + return self._interface.cshigh + + def _set_select_high(self, value): + self._interface.cshigh = bool(value) + + def _get_bits_per_word(self): + return self._interface.bits_per_word + + def _set_bits_per_word(self, value): + self._interface.bits_per_word = value + + def _get_rate(self): + return self._interface.max_speed_hz + + def _set_rate(self, value): + self._interface.max_speed_hz = int(value) + + +class LocalPiSoftwareSPI(SPI): + def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + self._bus = None + self._select = None + super(LocalPiSoftwareSPI, self).__init__(pin_factory=pin_factory) + try: + self._clock_phase = False + self._lsb_first = False + self._bits_per_word = 8 + self._bus = SPISoftwareBus(clock_pin, mosi_pin, miso_pin) + self._select = OutputDevice( + select_pin, active_high=False, pin_factory=pin_factory) + except: + self.close() + raise + + def _conflicts_with(self, other): + return not ( + isinstance(other, LocalPiSoftwareSPI) and + (self._select.pin.number != other._select.pin.number) + ) + + def close(self): + if self._select: + self._select.close() + self._select = None + if self._bus is not None: + self._bus.close() + self._bus = None + super(LocalPiSoftwareSPI, self).close() + + @property + def closed(self): + return self._bus is None + + def __repr__(self): + try: + self._check_open() + return 'SPI(clock_pin=%d, mosi_pin=%d, miso_pin=%d, select_pin=%d)' % ( + self._bus.clock.pin.number, + self._bus.mosi.pin.number, + self._bus.miso.pin.number, + self._select.pin.number) + except DeviceClosed: + return 'SPI(closed)' + + def transfer(self, data): + with self._bus.lock: + self._select.on() + try: + return self._bus.transfer( + data, self._clock_phase, self._lsb_first, self._bits_per_word) + finally: + self._select.off() + + def _get_clock_mode(self): + with self._bus.lock: + return (not self._bus.clock.active_high) << 1 | self._clock_phase + + def _set_clock_mode(self, value): + if not (0 <= value < 4): + raise SPIInvalidClockMode("%d is not a valid clock mode" % value) + with self._bus.lock: + self._bus.clock.active_high = not (value & 2) + self._clock_phase = bool(value & 1) + + def _get_lsb_first(self): + return self._lsb_first + + def _set_lsb_first(self, value): + self._lsb_first = bool(value) + + def _get_bits_per_word(self): + return self._bits_per_word + + def _set_bits_per_word(self, value): + if value < 1: + raise ValueError('bits_per_word must be positive') + self._bits_per_word = int(value) + + def _get_select_high(self): + return self._select.active_high + + def _set_select_high(self, value): + with self._bus.lock: + self._select.active_high = value + self._select.off() + + +class LocalPiHardwareSPIShared(SharedMixin, LocalPiHardwareSPI): + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin, select_pin, + pin_factory): + return (clock_pin, select_pin) + + +class LocalPiSoftwareSPIShared(SharedMixin, LocalPiSoftwareSPI): + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin, select_pin, + pin_factory): + return (clock_pin, select_pin) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/mock.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/mock.py new file mode 100644 index 0000000..81901f3 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/mock.py @@ -0,0 +1,492 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + + +import os +from collections import namedtuple +from time import time, sleep +from threading import Thread, Event +try: + from math import isclose +except ImportError: + from ..compat import isclose + +import pkg_resources + +from ..exc import ( + PinPWMUnsupported, + PinSetInput, + PinFixedPull, + PinInvalidFunction, + PinInvalidPull, + PinInvalidBounce, + ) +from ..devices import Device +from .local import LocalPiPin, LocalPiFactory + + +PinState = namedtuple('PinState', ('timestamp', 'state')) + +class MockPin(LocalPiPin): + """ + A mock pin used primarily for testing. This class does *not* support PWM. + """ + + def __init__(self, factory, number): + super(MockPin, self).__init__(factory, number) + self._function = 'input' + self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + self._state = self._pull == 'up' + self._bounce = None + self._edges = 'both' + self._when_changed = None + self.clear_states() + + def close(self): + self.when_changed = None + self.function = 'input' + + def _get_function(self): + return self._function + + def _set_function(self, value): + if value not in ('input', 'output'): + raise PinInvalidFunction('function must be input or output') + self._function = value + if value == 'input': + # Drive the input to the pull + self._set_pull(self._get_pull()) + + def _get_state(self): + return self._state + + def _set_state(self, value): + if self._function == 'input': + raise PinSetInput('cannot set state of pin %r' % self) + assert self._function == 'output' + assert 0 <= value <= 1 + self._change_state(bool(value)) + + def _change_state(self, value): + if self._state != value: + t = time() + self._state = value + self.states.append(PinState(t - self._last_change, value)) + self._last_change = t + return True + return False + + def _get_frequency(self): + return None + + def _set_frequency(self, value): + if value is not None: + raise PinPWMUnsupported() + + def _get_pull(self): + return self._pull + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + if value not in ('floating', 'up', 'down'): + raise PinInvalidPull('pull must be floating, up, or down') + self._pull = value + if value == 'up': + self.drive_high() + elif value == 'down': + self.drive_low() + + def _get_bounce(self): + return self._bounce + + def _set_bounce(self, value): + # XXX Need to implement this + if value is not None: + try: + value = float(value) + except ValueError: + raise PinInvalidBounce('bounce must be None or a float') + self._bounce = value + + def _get_edges(self): + return self._edges + + def _set_edges(self, value): + assert value in ('none', 'falling', 'rising', 'both') + self._edges = value + + def _disable_event_detect(self): + pass + + def _enable_event_detect(self): + pass + + def drive_high(self): + assert self._function == 'input' + if self._change_state(True): + if self._edges in ('both', 'rising') and self._when_changed is not None: + self._call_when_changed() + + def drive_low(self): + assert self._function == 'input' + if self._change_state(False): + if self._edges in ('both', 'falling') and self._when_changed is not None: + self._call_when_changed() + + def clear_states(self): + self._last_change = time() + self.states = [PinState(0.0, self._state)] + + def assert_states(self, expected_states): + # Tests that the pin went through the expected states (a list of values) + for actual, expected in zip(self.states, expected_states): + assert actual.state == expected + + def assert_states_and_times(self, expected_states): + # Tests that the pin went through the expected states at the expected + # times (times are compared with a tolerance of tens-of-milliseconds as + # that's about all we can reasonably expect in a non-realtime + # environment on a Pi 1) + for actual, expected in zip(self.states, expected_states): + assert isclose(actual.timestamp, expected[0], rel_tol=0.05, abs_tol=0.05) + assert isclose(actual.state, expected[1]) + + +class MockConnectedPin(MockPin): + """ + This derivative of :class:`MockPin` emulates a pin connected to another + mock pin. This is used in the "real pins" portion of the test suite to + check that one pin can influence another. + """ + def __init__(self, factory, number, input_pin=None): + super(MockConnectedPin, self).__init__(factory, number) + self.input_pin = input_pin + + def _change_state(self, value): + if self.input_pin: + if value: + self.input_pin.drive_high() + else: + self.input_pin.drive_low() + return super(MockConnectedPin, self)._change_state(value) + + +class MockChargingPin(MockPin): + """ + This derivative of :class:`MockPin` emulates a pin which, when set to + input, waits a predetermined length of time and then drives itself high + (as if attached to, e.g. a typical circuit using an LDR and a capacitor + to time the charging rate). + """ + def __init__(self, factory, number, charge_time=0.01): + super(MockChargingPin, self).__init__(factory, number) + self.charge_time = charge_time # dark charging time + self._charge_stop = Event() + self._charge_thread = None + + def _set_function(self, value): + super(MockChargingPin, self)._set_function(value) + if value == 'input': + if self._charge_thread: + self._charge_stop.set() + self._charge_thread.join() + self._charge_stop.clear() + self._charge_thread = Thread(target=self._charge) + self._charge_thread.start() + elif value == 'output': + if self._charge_thread: + self._charge_stop.set() + self._charge_thread.join() + else: + assert False + + def _charge(self): + if not self._charge_stop.wait(self.charge_time): + try: + self.drive_high() + except AssertionError: # pragma: no cover + # Charging pins are typically flipped between input and output + # repeatedly; if another thread has already flipped us to + # output ignore the assertion-error resulting from attempting + # to drive the pin high + pass + + +class MockTriggerPin(MockPin): + """ + This derivative of :class:`MockPin` is intended to be used with another + :class:`MockPin` to emulate a distance sensor. Set *echo_pin* to the + corresponding pin instance. When this pin is driven high it will trigger + the echo pin to drive high for the echo time. + """ + def __init__(self, factory, number, echo_pin=None, echo_time=0.04): + super(MockTriggerPin, self).__init__(factory, number) + self.echo_pin = echo_pin + self.echo_time = echo_time # longest echo time + self._echo_thread = None + + def _set_state(self, value): + super(MockTriggerPin, self)._set_state(value) + if value: + if self._echo_thread: + self._echo_thread.join() + self._echo_thread = Thread(target=self._echo) + self._echo_thread.start() + + def _echo(self): + sleep(0.001) + self.echo_pin.drive_high() + sleep(self.echo_time) + self.echo_pin.drive_low() + + +class MockPWMPin(MockPin): + """ + This derivative of :class:`MockPin` adds PWM support. + """ + def __init__(self, factory, number): + super(MockPWMPin, self).__init__(factory, number) + self._frequency = None + + def close(self): + self.frequency = None + super(MockPWMPin, self).close() + + def _set_state(self, value): + if self._function == 'input': + raise PinSetInput('cannot set state of pin %r' % self) + assert self._function == 'output' + assert 0 <= value <= 1 + self._change_state(float(value)) + + def _get_frequency(self): + return self._frequency + + def _set_frequency(self, value): + if value is not None: + assert self._function == 'output' + self._frequency = value + if value is None: + self._change_state(0.0) + + +class MockSPIClockPin(MockPin): + """ + This derivative of :class:`MockPin` is intended to be used as the clock pin + of a mock SPI device. It is not intended for direct construction in tests; + rather, construct a :class:`MockSPIDevice` with various pin numbers, and + this class will be used for the clock pin. + """ + def __init__(self, factory, number): + super(MockSPIClockPin, self).__init__(factory, number) + self.spi_devices = getattr(self, 'spi_devices', []) + + def _set_state(self, value): + super(MockSPIClockPin, self)._set_state(value) + for dev in self.spi_devices: + dev.on_clock() + + +class MockSPISelectPin(MockPin): + """ + This derivative of :class:`MockPin` is intended to be used as the select + pin of a mock SPI device. It is not intended for direct construction in + tests; rather, construct a :class:`MockSPIDevice` with various pin numbers, + and this class will be used for the select pin. + """ + def __init__(self, factory, number): + super(MockSPISelectPin, self).__init__(factory, number) + self.spi_device = getattr(self, 'spi_device', None) + + def _set_state(self, value): + super(MockSPISelectPin, self)._set_state(value) + if self.spi_device: + self.spi_device.on_select() + + +class MockSPIDevice(object): + def __init__( + self, clock_pin, mosi_pin=None, miso_pin=None, select_pin=None, + clock_polarity=False, clock_phase=False, lsb_first=False, + bits_per_word=8, select_high=False): + self.clock_pin = Device.pin_factory.pin(clock_pin, pin_class=MockSPIClockPin) + self.mosi_pin = None if mosi_pin is None else Device.pin_factory.pin(mosi_pin) + self.miso_pin = None if miso_pin is None else Device.pin_factory.pin(miso_pin) + self.select_pin = None if select_pin is None else Device.pin_factory.pin(select_pin, pin_class=MockSPISelectPin) + self.clock_polarity = clock_polarity + self.clock_phase = clock_phase + self.lsb_first = lsb_first + self.bits_per_word = bits_per_word + self.select_high = select_high + self.rx_bit = 0 + self.rx_buf = [] + self.tx_buf = [] + self.clock_pin.spi_devices.append(self) + self.select_pin.spi_device = self + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_tb): + self.close() + + def close(self): + if self in self.clock_pin.spi_devices: + self.clock_pin.spi_devices.remove(self) + if self.select_pin is not None: + self.select_pin.spi_device = None + + def on_select(self): + if self.select_pin.state == self.select_high: + self.on_start() + + def on_clock(self): + # Don't do anything if this SPI device isn't currently selected + if self.select_pin is None or self.select_pin.state == self.select_high: + # The XOR of the clock pin's values, polarity and phase indicates + # whether we're meant to be acting on this edge + if self.clock_pin.state ^ self.clock_polarity ^ self.clock_phase: + self.rx_bit += 1 + if self.mosi_pin is not None: + self.rx_buf.append(self.mosi_pin.state) + if self.miso_pin is not None: + try: + tx_value = self.tx_buf.pop(0) + except IndexError: + tx_value = 0 + if tx_value: + self.miso_pin.drive_high() + else: + self.miso_pin.drive_low() + self.on_bit() + + def on_start(self): + """ + Override this in descendents to detect when the mock SPI device's + select line is activated. + """ + self.rx_bit = 0 + self.rx_buf = [] + self.tx_buf = [] + + def on_bit(self): + """ + Override this in descendents to react to receiving a bit. + + The :attr:`rx_bit` attribute gives the index of the bit received (this + is reset to 0 by default by :meth:`on_select`). The :attr:`rx_buf` + sequence gives the sequence of 1s and 0s that have been recevied so + far. The :attr:`tx_buf` sequence gives the sequence of 1s and 0s to + transmit on the next clock pulses. All these attributes can be modified + within this method. + + The :meth:`rx_word` and :meth:`tx_word` methods can also be used to + read and append to the buffers using integers instead of bool bits. + """ + pass + + def rx_word(self): + result = 0 + bits = reversed(self.rx_buf) if self.lsb_first else self.rx_buf + for bit in bits: + result <<= 1 + result |= bit + return result + + def tx_word(self, value, bits_per_word=None): + if bits_per_word is None: + bits_per_word = self.bits_per_word + bits = [0] * bits_per_word + for bit in range(bits_per_word): + bits[bit] = value & 1 + value >>= 1 + assert not value + if not self.lsb_first: + bits = reversed(bits) + self.tx_buf.extend(bits) + + +class MockFactory(LocalPiFactory): + """ + Factory for generating mock pins. The *revision* parameter specifies what + revision of Pi the mock factory pretends to be (this affects the result of + the :attr:`~gpiozero.Factory.pi_info` attribute as well as where pull-ups + are assumed to be). The *pin_class* attribute specifies which mock pin + class will be generated by the :meth:`pin` method by default. This can be + changed after construction by modifying the :attr:`pin_class` attribute. + + .. attribute:: pin_class + + This attribute stores the :class:`MockPin` class (or descendent) that + will be used when constructing pins with the :meth:`pin` method (if + no *pin_class* parameter is used to override it). It defaults on + construction to the value of the *pin_class* parameter in the + constructor, or :class:`MockPin` if that is unspecified. + """ + def __init__(self, revision=None, pin_class=None): + super(MockFactory, self).__init__() + if revision is None: + revision = os.environ.get('GPIOZERO_MOCK_REVISION', 'a02082') + if pin_class is None: + pin_class = os.environ.get('GPIOZERO_MOCK_PIN_CLASS', MockPin) + self._revision = int(revision, base=16) + if isinstance(pin_class, bytes): + pin_class = pin_class.decode('ascii') + if isinstance(pin_class, str): + dist = pkg_resources.get_distribution('gpiozero') + group = 'gpiozero_mock_pin_classes' + pin_class = pkg_resources.load_entry_point(dist, group, pin_class.lower()) + if not issubclass(pin_class, MockPin): + raise ValueError('invalid mock pin_class: %r' % pin_class) + self.pin_class = pin_class + + def _get_revision(self): + return self._revision + + def reset(self): + """ + Clears the pins and reservations sets. This is primarily useful in + test suites to ensure the pin factory is back in a "clean" state before + the next set of tests are run. + """ + self.pins.clear() + self._reservations.clear() + + def pin(self, spec, pin_class=None, **kwargs): + """ + The pin method for :class:`MockFactory` additionally takes a *pin_class* + attribute which can be used to override the class' :attr:`pin_class` + attribute. Any additional keyword arguments will be passed along to the + pin constructor (useful with things like :class:`MockConnectedPin` which + expect to be constructed with another pin). + """ + if pin_class is None: + pin_class = self.pin_class + n = self.pi_info.to_gpio(spec) + try: + pin = self.pins[n] + except KeyError: + pin = pin_class(self, n, **kwargs) + self.pins[n] = pin + else: + # Ensure the pin class expected supports PWM (or not) + if issubclass(pin_class, MockPWMPin) != isinstance(pin, MockPWMPin): + raise ValueError('pin %d is already in use as a %s' % (n, pin.__class__.__name__)) + return pin diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/native.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/native.py new file mode 100644 index 0000000..bbdde0b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/native.py @@ -0,0 +1,633 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2016-2020 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +try: + range = xrange +except NameError: + pass +nstr = str +str = type('') + +import io +import os +import sys +import mmap +import errno +import struct +import select +import warnings +from time import sleep +from threading import Thread, Event, RLock +from collections import Counter +try: + from queue import Queue, Empty +except ImportError: + from Queue import Queue, Empty + +from .local import LocalPiPin, LocalPiFactory +from ..exc import ( + PinInvalidPull, + PinInvalidEdges, + PinInvalidFunction, + PinFixedPull, + PinSetInput, + ) + + +def dt_resolve_alias(alias, root='/proc/device-tree'): + """ + Returns the full path of a device-tree alias. For example: + + >>> dt_resolve_alias('gpio') + '/proc/device-tree/soc/gpio@7e200000' + >>> dt_resolve_alias('ethernet0', root='/proc/device-tree') + '/proc/device-tree/scb/ethernet@7d580000' + """ + # XXX Change this return a pathlib.Path when we drop 2.x + filename = os.path.join(root, 'aliases', alias) + with io.open(filename, 'rb') as f: + node, tail = f.read().split(b'\0', 1) + fs_encoding = sys.getfilesystemencoding() + return os.path.join(root, node.decode(fs_encoding).lstrip('/')) + +def dt_peripheral_reg(node, root='/proc/device-tree'): + """ + Returns the :class:`range` covering the registers of the specified *node* + of the device-tree, mapped to the CPU's address space. For example: + + >>> reg = dt_peripheral_reg(dt_resolve_alias('gpio')) + >>> '%#x..%#x' % (reg.start, reg.stop) + '0xfe200000..0xfe2000b4' + >>> hex(dt_peripheral_reg(dt_resolve_alias('ethernet0')).start) + '0xfd580000' + """ + # Returns a tuple of (address-cells, size-cells) for *node* + def _cells(node): + with io.open(os.path.join(node, '#address-cells'), 'rb') as f: + address_cells = struct.unpack(nstr('>L'), f.read())[0] + with io.open(os.path.join(node, '#size-cells'), 'rb') as f: + size_cells = struct.unpack(nstr('>L'), f.read())[0] + return (address_cells, size_cells) + + # Returns a generator function which, given a file-like object *source* + # iteratively decodes it, yielding a tuple of values from it. Each tuple + # contains one integer for each specified *length*, which is the number of + # 32-bit device-tree cells that make up that value. + def _reader(*lengths): + structs = [struct.Struct(nstr('>{cells}L'.format(cells=cells))) + for cells in lengths] + offsets = [sum(s.size for s in structs[:i]) + for i in range(len(structs))] + buf_len = sum(s.size for s in structs) + + def fn(source): + while True: + buf = source.read(buf_len) + if not buf: + break + elif len(buf) < buf_len: + raise IOError('failed to read {buf_len} bytes'.format( + buf_len=buf_len)) + row = () + for offset, s in zip(offsets, structs): + cells = s.unpack_from(buf, offset) + value = 0 + for cell in cells: + value = (value << 32) | cell + row += (value,) + yield row + return fn + + # Returns a list of (child-range, parent-range) tuples for *node* + def _ranges(node): + child_cells, size_cells = _cells(node) + parent = os.path.dirname(node) + parent_cells, _ = _cells(parent) + ranges_reader = _reader(child_cells, parent_cells, size_cells) + with io.open(os.path.join(node, 'ranges'), 'rb') as f: + return [ + (range(child_base, child_base + size), + range(parent_base, parent_base + size)) + for child_base, parent_base, size in ranges_reader(f) + ] + + # XXX Replace all this gubbins with pathlib.Path stuff once we drop 2.x + node = os.path.join(root, node) + parent = os.path.dirname(node) + child_cells, size_cells = _cells(parent) + reg_reader = _reader(child_cells, size_cells) + with io.open(os.path.join(node, 'reg'), 'rb') as f: + base, size = list(reg_reader(f))[0] + while parent != root: + # Iterate up the hierarchy, resolving the base address as we go + if os.path.exists(os.path.join(parent, 'ranges')): + for child_range, parent_range in _ranges(parent): + if base in child_range: + # XXX Can't use .start here as python2's crappy xrange + # lacks it; change this when we drop 2.x! + base += parent_range[0] - child_range[0] + break + parent = os.path.dirname(parent) + return range(base, base + size) + + +class GPIOMemory(object): + GPIO_BASE_OFFSET = 0x200000 + PERI_BASE_OFFSET = { + 'BCM2835': 0x20000000, + 'BCM2836': 0x3f000000, + 'BCM2837': 0x3f000000, + 'BCM2711': 0xfe000000, + } + + # From BCM2835 data-sheet, p.91 + GPFSEL_OFFSET = 0x00 >> 2 + GPSET_OFFSET = 0x1c >> 2 + GPCLR_OFFSET = 0x28 >> 2 + GPLEV_OFFSET = 0x34 >> 2 + GPEDS_OFFSET = 0x40 >> 2 + GPREN_OFFSET = 0x4c >> 2 + GPFEN_OFFSET = 0x58 >> 2 + GPHEN_OFFSET = 0x64 >> 2 + GPLEN_OFFSET = 0x70 >> 2 + GPAREN_OFFSET = 0x7c >> 2 + GPAFEN_OFFSET = 0x88 >> 2 + GPPUD_OFFSET = 0x94 >> 2 + GPPUDCLK_OFFSET = 0x98 >> 2 + # pull-control registers for BCM2711 + GPPUPPDN_OFFSET = 0xe4 >> 2 + + def __init__(self, soc): + try: + self.fd = os.open('/dev/gpiomem', os.O_RDWR | os.O_SYNC) + except OSError: + try: + self.fd = os.open('/dev/mem', os.O_RDWR | os.O_SYNC) + except OSError: + raise IOError( + 'unable to open /dev/gpiomem or /dev/mem; ' + 'upgrade your kernel or run as root') + else: + offset = self.gpio_base(soc) + else: + offset = 0 + self.mem = mmap.mmap(self.fd, 4096, offset=offset) + # Register reads and writes must be in native format (otherwise + # struct resorts to individual byte reads/writes and you can't hit + # half a register :). For arm64 compat we have to figure out what the + # native unsigned 32-bit type is... + try: + self.reg_fmt = { + struct.calcsize(fmt): fmt + for fmt in (nstr('@I'), nstr('@L')) + }[4] + except KeyError: + raise RuntimeError('unable to find native unsigned 32-bit type') + + def close(self): + self.mem.close() + os.close(self.fd) + + def gpio_base(self, soc): + try: + # XXX Replace this with .start when 2.x is dropped + return dt_peripheral_reg(dt_resolve_alias('gpio'))[0] + except IOError: + try: + return self.PERI_BASE_OFFSET[soc] + self.GPIO_BASE_OFFSET + except KeyError: + pass + raise IOError('unable to determine gpio base') + + def __getitem__(self, index): + return struct.unpack_from(self.reg_fmt, self.mem, index * 4)[0] + + def __setitem__(self, index, value): + struct.pack_into(self.reg_fmt, self.mem, index * 4, value) + + +class GPIOFS(object): + GPIO_PATH = '/sys/class/gpio' + + def __init__(self, factory, queue): + self._lock = RLock() + self._exports = {} + self._thread = NativeWatchThread(factory, queue) + + def close(self): + # We *could* track the stuff we've exported and unexport it here, but + # exports are a system global resource. We can't guarantee that some + # other process isn't relying on something we've exported. In other + # words, once exported it's *never* safe to unexport something. The + # unexport method below is largely provided for debugging and testing. + if self._thread is not None: + self._thread.close() + self._thread = None + + def path(self, name): + return os.path.join(self.GPIO_PATH, name) + + def path_value(self, pin): + return self.path('gpio%d/value' % pin) + + def path_dir(self, pin): + return self.path('gpio%d/direction' % pin) + + def path_edge(self, pin): + return self.path('gpio%d/edge' % pin) + + def exported(self, pin): + return pin in self._exports + + def export(self, pin): + with self._lock: + try: + result = self._exports[pin] + except KeyError: + result = None + # Dirty hack to wait for udev to set permissions on + # gpioN/value; there's no other way around this as there's no + # synchronous mechanism for setting permissions on sysfs + for i in range(10): + try: + # Must be O_NONBLOCK for use with epoll in edge + # triggered mode + result = os.open(self.path_value(pin), + os.O_RDONLY | os.O_NONBLOCK) + except IOError as e: + if e.errno == errno.ENOENT: + with io.open(self.path('export'), 'wb') as f: + f.write(str(pin).encode('ascii')) + elif e.errno == errno.EACCES: + sleep(i / 100) + else: + raise + else: + self._exports[pin] = result + break + # Same for gpioN/edge. It must exist by this point but the + # chmod -R may not have reached it yet... + for i in range(10): + try: + with io.open(self.path_edge(pin), 'w+b'): + pass + except IOError as e: + if e.errno == errno.EACCES: + sleep(i / 100) + else: + raise + if result is None: + raise RuntimeError('failed to export pin %d' % pin) + return result + + def unexport(self, pin): + with self._lock: + try: + os.close(self._exports.pop(pin)) + except KeyError: + # unexport should be idempotent + pass + else: + try: + with io.open(self.path('unexport'), 'wb') as f: + f.write(str(pin).encode('ascii')) + except IOError as e: + if e.errno == errno.EINVAL: + # Someone already unexported it; ignore the error + pass + + def watch(self, pin): + with self._lock: + self._thread.watch(self.export(pin), pin) + + def unwatch(self, pin): + with self._lock: + try: + self._thread.unwatch(self._exports[pin]) + except KeyError: + pass + + +class NativeWatchThread(Thread): + def __init__(self, factory, queue): + super(NativeWatchThread, self).__init__( + target=self._run, args=(factory, queue)) + self.daemon = True + self._stop_evt = Event() + # XXX Make this compatible with BSDs with poll() option? + self._epoll = select.epoll() + self._watches = {} + self.start() + + def close(self): + self._stop_evt.set() + self.join() + self._epoll.close() + + def watch(self, fd, pin): + self._watches[fd] = pin + flags = select.EPOLLIN | select.EPOLLPRI | select.EPOLLET + self._epoll.register(fd, flags) + + def unwatch(self, fd): + self._epoll.unregister(fd) + fd = self._watches.pop(fd, None) + + def _run(self, factory, queue): + ticks = factory.ticks + while not self._stop_evt.wait(0): + for fd, event in self._epoll.poll(0.01): + when = ticks() + state = os.read(fd, 1) == b'1' + os.lseek(fd, 0, 0) + try: + queue.put((self._watches[fd], when, state)) + except KeyError: + pass + + +class NativeDispatchThread(Thread): + def __init__(self, factory, queue): + super(NativeDispatchThread, self).__init__( + target=self._run, args=(factory, queue)) + self.daemon = True + self._stop_evt = Event() + self.start() + + def close(self): + self._stop_evt.set() + self.join() + + def _run(self, factory, queue): + pins = factory.pins + while not self._stop_evt.wait(0): + try: + num, ticks, state = queue.get(timeout=0.1) + except Empty: + continue + try: + pin = pins[num] + except KeyError: + pass + else: + if ( + pin._bounce is None or pin._last_call is None or + factory.ticks_diff(ticks, pin._last_call) > pin._bounce + ): + pin._call_when_changed(ticks, state) + pin._last_call = ticks + + +class NativeFactory(LocalPiFactory): + """ + Extends :class:`~gpiozero.pins.local.LocalPiFactory`. Uses a built-in pure + Python implementation to interface to the Pi's GPIO pins. This is the + default pin implementation if no third-party libraries are discovered. + + .. warning:: + + This implementation does *not* currently support PWM. Attempting to + use any class which requests PWM will raise an exception. + + You can construct native pin instances manually like so:: + + from gpiozero.pins.native import NativeFactory + from gpiozero import LED + + factory = NativeFactory() + led = LED(12, pin_factory=factory) + """ + def __init__(self): + super(NativeFactory, self).__init__() + queue = Queue() + self.mem = GPIOMemory(self.pi_info.soc) + self.fs = GPIOFS(self, queue) + self.dispatch = NativeDispatchThread(self, queue) + if self.pi_info.soc == 'BCM2711': + self.pin_class = Native2711Pin + else: + self.pin_class = Native2835Pin + + def close(self): + if self.dispatch is not None: + self.dispatch.close() + self.dispatch = None + super(NativeFactory, self).close() + if self.fs is not None: + self.fs.close() + self.fs = None + if self.mem is not None: + self.mem.close() + self.mem = None + + +class NativePin(LocalPiPin): + """ + Extends :class:`~gpiozero.pins.local.LocalPiPin`. Native pin + implementation. See :class:`NativeFactory` for more information. + """ + GPIO_FUNCTIONS = { + 'input': 0b000, + 'output': 0b001, + 'alt0': 0b100, + 'alt1': 0b101, + 'alt2': 0b110, + 'alt3': 0b111, + 'alt4': 0b011, + 'alt5': 0b010, + } + + GPIO_FUNCTION_NAMES = {v: k for (k, v) in GPIO_FUNCTIONS.items()} + + def __init__(self, factory, number): + super(NativePin, self).__init__(factory, number) + self._reg_init(factory, number) + self._last_call = None + self._when_changed = None + self._change_thread = None + self._change_event = Event() + self.function = 'input' + self.pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + self.bounce = None + self.edges = 'none' + + def _reg_init(self, factory, number): + self._func_offset = self.factory.mem.GPFSEL_OFFSET + (number // 10) + self._func_shift = (number % 10) * 3 + self._set_offset = self.factory.mem.GPSET_OFFSET + (number // 32) + self._set_shift = number % 32 + self._clear_offset = self.factory.mem.GPCLR_OFFSET + (number // 32) + self._clear_shift = number % 32 + self._level_offset = self.factory.mem.GPLEV_OFFSET + (number // 32) + self._level_shift = number % 32 + self._edge_offset = self.factory.mem.GPEDS_OFFSET + (number // 32) + self._edge_shift = number % 32 + self._rising_offset = self.factory.mem.GPREN_OFFSET + (number // 32) + self._rising_shift = number % 32 + self._falling_offset = self.factory.mem.GPFEN_OFFSET + (number // 32) + self._falling_shift = number % 32 + + def close(self): + self.edges = 'none' + self.frequency = None + self.when_changed = None + self.function = 'input' + self.pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + + def _get_function(self): + return self.GPIO_FUNCTION_NAMES[(self.factory.mem[self._func_offset] >> self._func_shift) & 7] + + def _set_function(self, value): + try: + value = self.GPIO_FUNCTIONS[value] + except KeyError: + raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self)) + self.factory.mem[self._func_offset] = ( + self.factory.mem[self._func_offset] + & ~(7 << self._func_shift) + | (value << self._func_shift) + ) + + def _get_state(self): + return bool(self.factory.mem[self._level_offset] & (1 << self._level_shift)) + + def _set_state(self, value): + if self.function == 'input': + raise PinSetInput('cannot set state of pin %r' % self) + if value: + self.factory.mem[self._set_offset] = 1 << self._set_shift + else: + self.factory.mem[self._clear_offset] = 1 << self._clear_shift + + def _get_pull(self): + raise NotImplementedError + + def _set_pull(self, value): + raise NotImplementedError + + def _get_bounce(self): + return self._bounce + + def _set_bounce(self, value): + self._bounce = None if value is None else float(value) + + def _get_edges(self): + try: + with io.open(self.factory.fs.path_edge(self.number), 'r') as f: + return f.read().strip() + except IOError as e: + if e.errno == errno.ENOENT: + return 'none' + else: + raise + + def _set_edges(self, value): + if value != 'none': + self.factory.fs.export(self.number) + try: + with io.open(self.factory.fs.path_edge(self.number), 'w') as f: + f.write(value) + except IOError as e: + if e.errno == errno.ENOENT and value == 'none': + pass + elif e.errno == errno.EINVAL: + raise PinInvalidEdges('invalid edge specification "%s" for pin %r' % self) + else: + raise + + def _enable_event_detect(self): + self.factory.fs.watch(self.number) + self._last_call = None + + def _disable_event_detect(self): + self.factory.fs.unwatch(self.number) + + +class Native2835Pin(NativePin): + """ + Extends :class:`NativePin` for Pi hardware prior to the Pi 4 (Pi 0, 1, 2, + 3, and 3+). + """ + GPIO_PULL_UPS = { + 'up': 0b10, + 'down': 0b01, + 'floating': 0b00, + } + + GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()} + + def _reg_init(self, factory, number): + super(Native2835Pin, self)._reg_init(factory, number) + self._pull_offset = self.factory.mem.GPPUDCLK_OFFSET + (number // 32) + self._pull_shift = number % 32 + self._pull = 'floating' + + def _get_pull(self): + return self.GPIO_PULL_UP_NAMES[self._pull] + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + value = self.GPIO_PULL_UPS[value] + except KeyError: + raise PinInvalidPull('invalid pull direction "%s" for pin %r' % (value, self)) + self.factory.mem[self.factory.mem.GPPUD_OFFSET] = value + sleep(0.000000214) + self.factory.mem[self._pull_offset] = 1 << self._pull_shift + sleep(0.000000214) + self.factory.mem[self.factory.mem.GPPUD_OFFSET] = 0 + self.factory.mem[self._pull_offset] = 0 + self._pull = value + + +class Native2711Pin(NativePin): + """ + Extends :class:`NativePin` for Pi 4 hardware (Pi 4, CM4, Pi 400 at the time + of writing). + """ + GPIO_PULL_UPS = { + 'up': 0b01, + 'down': 0b10, + 'floating': 0b00, + } + + GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()} + + def _reg_init(self, factory, number): + super(Native2711Pin, self)._reg_init(factory, number) + self._pull_offset = self.factory.mem.GPPUPPDN_OFFSET + (number // 16) + self._pull_shift = (number % 16) * 2 + + def _get_pull(self): + pull = (self.factory.mem[self._pull_offset] >> self._pull_shift) & 3 + return self.GPIO_PULL_UP_NAMES[pull] + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + value = self.GPIO_PULL_UPS[value] + except KeyError: + raise PinInvalidPull('invalid pull direction "%s" for pin %r' % (value, self)) + self.factory.mem[self._pull_offset] = ( + self.factory.mem[self._pull_offset] + & ~(3 << self._pull_shift) + | (value << self._pull_shift) + ) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/pi.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/pi.py new file mode 100644 index 0000000..3e8b820 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/pi.py @@ -0,0 +1,334 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import io +from threading import RLock, Lock +from types import MethodType +from collections import defaultdict +try: + from weakref import ref, WeakMethod +except ImportError: + + from ..compat import WeakMethod +import warnings + +try: + from spidev import SpiDev +except ImportError: + SpiDev = None + +from . import Factory, Pin +from .data import PiBoardInfo +from ..exc import ( + PinNoPins, + PinNonPhysical, + PinInvalidPin, + SPIBadArgs, + SPISoftwareFallback, + ) + + +SPI_HARDWARE_PINS = { + 0: { + 'clock': 11, + 'mosi': 10, + 'miso': 9, + 'select': (8, 7), + }, +} + + +def spi_port_device(clock_pin, mosi_pin, miso_pin, select_pin): + """ + Convert a mapping of pin definitions, which must contain 'clock_pin', and + 'select_pin' at a minimum, to a hardware SPI port, device tuple. Raises + :exc:`~gpiozero.SPIBadArgs` if the pins do not represent a valid hardware + SPI device. + """ + for port, pins in SPI_HARDWARE_PINS.items(): + if all(( + clock_pin == pins['clock'], + mosi_pin in (None, pins['mosi']), + miso_pin in (None, pins['miso']), + select_pin in pins['select'], + )): + device = pins['select'].index(select_pin) + return (port, device) + raise SPIBadArgs('invalid pin selection for hardware SPI') + + +class PiFactory(Factory): + """ + Extends :class:`~gpiozero.Factory`. Abstract base class representing + hardware attached to a Raspberry Pi. This forms the base of + :class:`~gpiozero.pins.local.LocalPiFactory`. + """ + def __init__(self): + super(PiFactory, self).__init__() + self._info = None + self.pins = {} + self.pin_class = None + + def close(self): + for pin in self.pins.values(): + pin.close() + self.pins.clear() + + def reserve_pins(self, requester, *pins): + super(PiFactory, self).reserve_pins( + requester, *(self.pi_info.to_gpio(pin) for pin in pins)) + + def release_pins(self, reserver, *pins): + super(PiFactory, self).release_pins( + reserver, *(self.pi_info.to_gpio(pin) for pin in pins)) + + def pin(self, spec): + n = self.pi_info.to_gpio(spec) + try: + pin = self.pins[n] + except KeyError: + pin = self.pin_class(self, n) + self.pins[n] = pin + return pin + + def _get_revision(self): + """ + This method must be overridden by descendents to return the Pi's + revision code as an :class:`int`. The default is unimplemented. + """ + raise NotImplementedError + + def _get_pi_info(self): + if self._info is None: + self._info = PiBoardInfo.from_revision(self._get_revision()) + return self._info + + def spi(self, **spi_args): + """ + Returns an SPI interface, for the specified SPI *port* and *device*, or + for the specified pins (*clock_pin*, *mosi_pin*, *miso_pin*, and + *select_pin*). Only one of the schemes can be used; attempting to mix + *port* and *device* with pin numbers will raise + :exc:`~gpiozero.SPIBadArgs`. + + If the pins specified match the hardware SPI pins (clock on GPIO11, + MOSI on GPIO10, MISO on GPIO9, and chip select on GPIO8 or GPIO7), and + the spidev module can be imported, a hardware based interface (using + spidev) will be returned. Otherwise, a software based interface will be + returned which will use simple bit-banging to communicate. + + Both interfaces have the same API, support clock polarity and phase + attributes, and can handle half and full duplex communications, but the + hardware interface is significantly faster (though for many simpler + devices this doesn't matter). + """ + spi_args, kwargs = self._extract_spi_args(**spi_args) + shared = bool(kwargs.pop('shared', False)) + if kwargs: + raise SPIBadArgs( + 'unrecognized keyword argument %s' % kwargs.popitem()[0]) + try: + port, device = spi_port_device(**spi_args) + except SPIBadArgs: + # Assume request is for a software SPI implementation + pass + else: + try: + return self._get_spi_class(shared, hardware=True)( + pin_factory=self, **spi_args) + except Exception as e: + warnings.warn( + SPISoftwareFallback( + 'failed to initialize hardware SPI, falling back to ' + 'software (error was: %s)' % str(e))) + return self._get_spi_class(shared, hardware=False)( + pin_factory=self, **spi_args) + + def _extract_spi_args(self, **kwargs): + """ + Given a set of keyword arguments, splits it into those relevant to SPI + implementations and all the rest. SPI arguments are augmented with + defaults and converted into the pin format (from the port/device + format) if necessary. + + Returns a tuple of ``(spi_args, other_args)``. + """ + dev_defaults = { + 'port': 0, + 'device': 0, + } + default_hw = SPI_HARDWARE_PINS[dev_defaults['port']] + pin_defaults = { + 'clock_pin': default_hw['clock'], + 'mosi_pin': default_hw['mosi'], + 'miso_pin': default_hw['miso'], + 'select_pin': default_hw['select'][dev_defaults['device']], + } + spi_args = { + key: value for (key, value) in kwargs.items() + if key in pin_defaults or key in dev_defaults + } + kwargs = { + key: value for (key, value) in kwargs.items() + if key not in spi_args + } + if not spi_args: + spi_args = pin_defaults + elif set(spi_args) <= set(pin_defaults): + spi_args = { + key: None if spi_args.get(key, default) is None else + self.pi_info.to_gpio(spi_args.get(key, default)) + for key, default in pin_defaults.items() + } + elif set(spi_args) <= set(dev_defaults): + spi_args = { + key: spi_args.get(key, default) + for key, default in dev_defaults.items() + } + try: + selected_hw = SPI_HARDWARE_PINS[spi_args['port']] + except KeyError: + raise SPIBadArgs( + 'port %d is not a valid SPI port' % spi_args['port']) + try: + selected_hw['select'][spi_args['device']] + except IndexError: + raise SPIBadArgs( + 'device must be in the range 0..%d' % + len(selected_hw['select'])) + spi_args = { + key: value if key != 'select_pin' else selected_hw['select'][spi_args['device']] + for key, value in pin_defaults.items() + } + else: + raise SPIBadArgs( + 'you must either specify port and device, or clock_pin, ' + 'mosi_pin, miso_pin, and select_pin; combinations of the two ' + 'schemes (e.g. port and clock_pin) are not permitted') + return spi_args, kwargs + + def _get_spi_class(self, shared, hardware): + """ + Returns a sub-class of the :class:`SPI` which can be constructed with + *clock_pin*, *mosi_pin*, *miso_pin*, and *select_pin* arguments. The + *shared* argument dictates whether the returned class uses the + :class:`SharedMixin` to permit sharing instances between components, + while *hardware* indicates whether the returned class uses the kernel's + SPI device(s) rather than a bit-banged software implementation. + """ + raise NotImplementedError + + +class PiPin(Pin): + """ + Extends :class:`~gpiozero.Pin`. Abstract base class representing a + multi-function GPIO pin attached to a Raspberry Pi. Descendents *must* + override the following methods: + + * :meth:`_get_function` + * :meth:`_set_function` + * :meth:`_get_state` + * :meth:`_call_when_changed` + * :meth:`_enable_event_detect` + * :meth:`_disable_event_detect` + + Descendents *may* additionally override the following methods, if + applicable: + + * :meth:`close` + * :meth:`output_with_state` + * :meth:`input_with_pull` + * :meth:`_set_state` + * :meth:`_get_frequency` + * :meth:`_set_frequency` + * :meth:`_get_pull` + * :meth:`_set_pull` + * :meth:`_get_bounce` + * :meth:`_set_bounce` + * :meth:`_get_edges` + * :meth:`_set_edges` + """ + def __init__(self, factory, number): + super(PiPin, self).__init__() + self._factory = factory + self._when_changed_lock = RLock() + self._when_changed = None + self._number = number + try: + factory.pi_info.physical_pin(repr(self)) + except PinNoPins: + warnings.warn( + PinNonPhysical( + 'no physical pins exist for %s' % repr(self))) + + @property + def number(self): + return self._number + + def __repr__(self): + return 'GPIO%d' % self._number + + @property + def factory(self): + return self._factory + + def _call_when_changed(self, ticks, state): + """ + Called to fire the :attr:`when_changed` event handler; override this + in descendents if additional (currently redundant) parameters need + to be passed. + """ + method = self._when_changed() + if method is None: + self.when_changed = None + else: + method(ticks, state) + + def _get_when_changed(self): + return None if self._when_changed is None else self._when_changed() + + def _set_when_changed(self, value): + with self._when_changed_lock: + if value is None: + if self._when_changed is not None: + self._disable_event_detect() + self._when_changed = None + else: + enabled = self._when_changed is not None + # Have to take care, if value is either a closure or a bound + # method, not to keep a strong reference to the containing + # object + if isinstance(value, MethodType): + self._when_changed = WeakMethod(value) + else: + self._when_changed = ref(value) + if not enabled: + self._enable_event_detect() + + def _enable_event_detect(self): + """ + Enables event detection. This is called to activate event detection on + pin :attr:`number`, watching for the specified :attr:`edges`. In + response, :meth:`_call_when_changed` should be executed. + """ + raise NotImplementedError + + def _disable_event_detect(self): + """ + Disables event detection. This is called to deactivate event detection + on pin :attr:`number`. + """ + raise NotImplementedError diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/pigpio.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/pigpio.py new file mode 100644 index 0000000..72bf4cb --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/pigpio.py @@ -0,0 +1,601 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2021 Kyle Morgan +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2020 Ben Nuttall +# Copyright (c) 2019 Maksim Levental +# Copyright (c) 2019 Aaron Rogers +# Copyright (c) 2016 BuildTools +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import os + +import pigpio + +from . import SPI +from .pi import PiPin, PiFactory, spi_port_device +from ..mixins import SharedMixin +from ..exc import ( + PinInvalidFunction, + PinSetInput, + PinFixedPull, + PinInvalidPull, + PinInvalidBounce, + PinInvalidState, + SPIBadArgs, + SPIInvalidClockMode, + PinPWMFixedValue, + DeviceClosed +) + + +class PiGPIOFactory(PiFactory): + """ + Extends :class:`~gpiozero.pins.pi.PiFactory`. Uses the `pigpio`_ library to + interface to the Pi's GPIO pins. The pigpio library relies on a daemon + (:command:`pigpiod`) to be running as root to provide access to the GPIO + pins, and communicates with this daemon over a network socket. + + While this does mean only the daemon itself should control the pins, the + architecture does have several advantages: + + * Pins can be remote controlled from another machine (the other + machine doesn't even have to be a Raspberry Pi; it simply needs the + `pigpio`_ client library installed on it) + * The daemon supports hardware PWM via the DMA controller + * Your script itself doesn't require root privileges; it just needs to + be able to communicate with the daemon + + You can construct pigpio pins manually like so:: + + from gpiozero.pins.pigpio import PiGPIOFactory + from gpiozero import LED + + factory = PiGPIOFactory() + led = LED(12, pin_factory=factory) + + This is particularly useful for controlling pins on a remote machine. To + accomplish this simply specify the host (and optionally port) when + constructing the pin:: + + from gpiozero.pins.pigpio import PiGPIOFactory + from gpiozero import LED + + factory = PiGPIOFactory(host='192.168.0.2') + led = LED(12, pin_factory=factory) + + .. note:: + + In some circumstances, especially when playing with PWM, it does appear + to be possible to get the daemon into "unusual" states. We would be + most interested to hear any bug reports relating to this (it may be a + bug in our pin implementation). A workaround for now is simply to + restart the :command:`pigpiod` daemon. + + .. _pigpio: http://abyz.me.uk/rpi/pigpio/ + """ + def __init__(self, host=None, port=None): + super(PiGPIOFactory, self).__init__() + if host is None: + host = os.environ.get('PIGPIO_ADDR', 'localhost') + if port is None: + # XXX Use getservbyname + port = int(os.environ.get('PIGPIO_PORT', 8888)) + self.pin_class = PiGPIOPin + self._connection = pigpio.pi(host, port) + # Annoyingly, pigpio doesn't raise an exception when it fails to make a + # connection; it returns a valid (but disconnected) pi object + if self.connection is None: + raise IOError('failed to connect to %s:%s' % (host, port)) + self._host = host + self._port = port + self._spis = [] + + def close(self): + super(PiGPIOFactory, self).close() + # We *have* to keep track of SPI interfaces constructed with pigpio; + # if we fail to close them they prevent future interfaces from using + # the same pins + if self.connection: + while self._spis: + self._spis[0].close() + self.connection.stop() + self._connection = None + + @property + def connection(self): + # If we're shutting down, the connection may have disconnected itself + # already. Unfortunately, the connection's "connected" property is + # rather buggy - disconnecting doesn't set it to False! So we're + # naughty and check an internal variable instead... + try: + if self._connection.sl.s is not None: + return self._connection + except AttributeError: + pass + + @property + def host(self): + return self._host + + @property + def port(self): + return self._port + + def _get_revision(self): + return self.connection.get_hardware_revision() + + def _get_spi_class(self, shared, hardware): + return { + (False, True): PiGPIOHardwareSPI, + (True, True): PiGPIOHardwareSPIShared, + (False, False): PiGPIOSoftwareSPI, + (True, False): PiGPIOSoftwareSPIShared, + }[shared, hardware] + + def spi(self, **spi_args): + intf = super(PiGPIOFactory, self).spi(**spi_args) + self._spis.append(intf) + return intf + + def ticks(self): + return self._connection.get_current_tick() + + @staticmethod + def ticks_diff(later, earlier): + # NOTE: pigpio ticks are unsigned 32-bit quantities that wrap every + # 71.6 minutes. The modulo below (oh the joys of having an *actual* + # modulo operator, unlike C's remainder) ensures the result is valid + # even when later < earlier due to wrap-around (assuming the duration + # measured is not longer than the period) + return ((later - earlier) % 0x100000000) / 1000000 + + +class PiGPIOPin(PiPin): + """ + Extends :class:`~gpiozero.pins.pi.PiPin`. Pin implementation for the + `pigpio`_ library. See :class:`PiGPIOFactory` for more information. + + .. _pigpio: http://abyz.me.uk/rpi/pigpio/ + """ + GPIO_FUNCTIONS = { + 'input': pigpio.INPUT, + 'output': pigpio.OUTPUT, + 'alt0': pigpio.ALT0, + 'alt1': pigpio.ALT1, + 'alt2': pigpio.ALT2, + 'alt3': pigpio.ALT3, + 'alt4': pigpio.ALT4, + 'alt5': pigpio.ALT5, + } + + GPIO_PULL_UPS = { + 'up': pigpio.PUD_UP, + 'down': pigpio.PUD_DOWN, + 'floating': pigpio.PUD_OFF, + } + + GPIO_EDGES = { + 'both': pigpio.EITHER_EDGE, + 'rising': pigpio.RISING_EDGE, + 'falling': pigpio.FALLING_EDGE, + } + + GPIO_FUNCTION_NAMES = {v: k for (k, v) in GPIO_FUNCTIONS.items()} + GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()} + GPIO_EDGES_NAMES = {v: k for (k, v) in GPIO_EDGES.items()} + + def __init__(self, factory, number): + super(PiGPIOPin, self).__init__(factory, number) + self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + self._pwm = False + self._bounce = None + self._callback = None + self._edges = pigpio.EITHER_EDGE + try: + self.factory.connection.set_mode(self.number, pigpio.INPUT) + except pigpio.error as e: + raise ValueError(e) + self.factory.connection.set_pull_up_down(self.number, self.GPIO_PULL_UPS[self._pull]) + self.factory.connection.set_glitch_filter(self.number, 0) + + def close(self): + if self.factory.connection: + self.frequency = None + self.when_changed = None + self.function = 'input' + self.pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + + def _get_function(self): + return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)] + + def _set_function(self, value): + if value != 'input': + self._pull = 'floating' + try: + self.factory.connection.set_mode(self.number, self.GPIO_FUNCTIONS[value]) + except KeyError: + raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self)) + + def _get_state(self): + if self._pwm: + return ( + self.factory.connection.get_PWM_dutycycle(self.number) / + self.factory.connection.get_PWM_range(self.number) + ) + else: + return bool(self.factory.connection.read(self.number)) + + def _set_state(self, value): + if self._pwm: + try: + value = int(value * self.factory.connection.get_PWM_range(self.number)) + if value != self.factory.connection.get_PWM_dutycycle(self.number): + self.factory.connection.set_PWM_dutycycle(self.number, value) + except pigpio.error: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + elif self.function == 'input': + raise PinSetInput('cannot set state of pin %r' % self) + else: + # write forces pin to OUTPUT, hence the check above + self.factory.connection.write(self.number, bool(value)) + + def _get_pull(self): + return self._pull + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + self.factory.connection.set_pull_up_down(self.number, self.GPIO_PULL_UPS[value]) + self._pull = value + except KeyError: + raise PinInvalidPull('invalid pull "%s" for pin %r' % (value, self)) + + def _get_frequency(self): + if self._pwm: + return self.factory.connection.get_PWM_frequency(self.number) + return None + + def _set_frequency(self, value): + if not self._pwm and value is not None: + if self.function != 'output': + raise PinPWMFixedValue('cannot start PWM on pin %r' % self) + # NOTE: the pin's state *must* be set to zero; if it's currently + # high, starting PWM and setting a 0 duty-cycle *doesn't* bring + # the pin low; it stays high! + self.factory.connection.write(self.number, 0) + self.factory.connection.set_PWM_frequency(self.number, int(value)) + self.factory.connection.set_PWM_range(self.number, 10000) + self.factory.connection.set_PWM_dutycycle(self.number, 0) + self._pwm = True + elif self._pwm and value is not None: + if value != self.factory.connection.get_PWM_frequency(self.number): + self.factory.connection.set_PWM_frequency(self.number, int(value)) + self.factory.connection.set_PWM_range(self.number, 10000) + elif self._pwm and value is None: + self.factory.connection.write(self.number, 0) + self._pwm = False + + def _get_bounce(self): + return None if not self._bounce else self._bounce / 1000000 + + def _set_bounce(self, value): + if value is None: + value = 0 + elif not 0 <= value <= 0.3: + raise PinInvalidBounce('bounce must be between 0 and 0.3') + self.factory.connection.set_glitch_filter(self.number, int(value * 1000000)) + + def _get_edges(self): + return self.GPIO_EDGES_NAMES[self._edges] + + def _set_edges(self, value): + f = self.when_changed + self.when_changed = None + try: + self._edges = self.GPIO_EDGES[value] + finally: + self.when_changed = f + + def _call_when_changed(self, gpio, level, ticks): + super(PiGPIOPin, self)._call_when_changed(ticks, level) + + def _enable_event_detect(self): + self._callback = self.factory.connection.callback( + self.number, self._edges, self._call_when_changed) + + def _disable_event_detect(self): + if self._callback is not None: + self._callback.cancel() + self._callback = None + + +class PiGPIOHardwareSPI(SPI): + """ + Hardware SPI implementation for the `pigpio`_ library. Uses the ``spi_*`` + functions from the pigpio API. + + .. _pigpio: http://abyz.me.uk/rpi/pigpio/ + """ + def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + port, device = spi_port_device( + clock_pin, mosi_pin, miso_pin, select_pin) + self._port = port + self._device = device + self._handle = None + super(PiGPIOHardwareSPI, self).__init__(pin_factory=pin_factory) + to_reserve = {clock_pin, select_pin} + if mosi_pin is not None: + to_reserve.add(mosi_pin) + if miso_pin is not None: + to_reserve.add(miso_pin) + self.pin_factory.reserve_pins(self, *to_reserve) + self._spi_flags = (8 << 16) | (port << 8) + self._baud = 500000 + self._handle = self.pin_factory.connection.spi_open( + device, self._baud, self._spi_flags) + + def _conflicts_with(self, other): + return not ( + isinstance(other, PiGPIOHardwareSPI) and + (self.pin_factory.host, self._port, self._device) != + (other.pin_factory.host, other._port, other._device) + ) + + def close(self): + try: + self.pin_factory._spis.remove(self) + except (ReferenceError, ValueError): + # If the factory has died already or we're not present in its + # internal list, ignore the error + pass + if not self.closed: + self.pin_factory.connection.spi_close(self._handle) + self._handle = None + self.pin_factory.release_all(self) + super(PiGPIOHardwareSPI, self).close() + + @property + def closed(self): + return self._handle is None or self.pin_factory.connection is None + + def __repr__(self): + try: + self._check_open() + return 'SPI(port=%d, device=%d)' % (self._port, self._device) + except DeviceClosed: + return 'SPI(closed)' + + def _get_clock_mode(self): + return self._spi_flags & 0x3 + + def _set_clock_mode(self, value): + self._check_open() + if not 0 <= value < 4: + raise SPIInvalidClockMode("%d is not a valid SPI clock mode" % value) + self.pin_factory.connection.spi_close(self._handle) + self._spi_flags = (self._spi_flags & ~0x3) | value + self._handle = self.pin_factory.connection.spi_open( + self._device, self._baud, self._spi_flags) + + def _get_select_high(self): + return bool((self._spi_flags >> (2 + self._device)) & 0x1) + + def _set_select_high(self, value): + self._check_open() + self.pin_factory.connection.spi_close(self._handle) + self._spi_flags = (self._spi_flags & ~0x1c) | (bool(value) << (2 + self._device)) + self._handle = self.pin_factory.connection.spi_open( + self._device, self._baud, self._spi_flags) + + def _get_bits_per_word(self): + return (self._spi_flags >> 16) & 0x3f + + def _set_bits_per_word(self, value): + self._check_open() + self.pin_factory.connection.spi_close(self._handle) + self._spi_flags = (self._spi_flags & ~0x3f0000) | ((value & 0x3f) << 16) + self._handle = self.pin_factory.connection.spi_open( + self._device, self._baud, self._spi_flags) + + def _get_rate(self): + return self._baud + + def _set_rate(self, value): + self._check_open() + value = int(value) + self.pin_factory.connection.spi_close(self._handle) + self._baud = value + self._handle = self.pin_factory.connection.spi_open( + self._device, self._baud, self._spi_flags) + + def _get_lsb_first(self): + return bool((self._spi_flags >> 14) & 0x1) if self._port else False + + def _set_lsb_first(self, value): + if self._port: + self._check_open() + self.pin_factory.connection.spi_close(self._handle) + self._spi_flags = ( + (self._spi_flags & ~0xc000) + | (bool(value) << 14) + | (bool(value) << 15) + ) + self._handle = self.pin_factory.connection.spi_open( + self._device, self._baud, self._spi_flags) + else: + super(PiGPIOHardwareSPI, self)._set_lsb_first(value) + + def transfer(self, data): + self._check_open() + count, data = self.pin_factory.connection.spi_xfer(self._handle, data) + if count < 0: + raise IOError('SPI transfer error %d' % count) + # Convert returned bytearray to list of ints. XXX Not sure how non-byte + # sized words (aux intf only) are returned ... padded to 16/32-bits? + return [int(b) for b in data] + + +class PiGPIOSoftwareSPI(SPI): + """ + Software SPI implementation for the `pigpio`_ library. Uses the ``bb_spi_*`` + functions from the pigpio API. + + .. _pigpio: http://abyz.me.uk/rpi/pigpio/ + """ + def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + self._closed = True + self._select_pin = select_pin + self._clock_pin = clock_pin + self._mosi_pin = mosi_pin + self._miso_pin = miso_pin + super(PiGPIOSoftwareSPI, self).__init__(pin_factory=pin_factory) + # Can't "unreserve" MOSI/MISO on this implementation + self.pin_factory.reserve_pins( + self, + clock_pin, + mosi_pin, + miso_pin, + select_pin, + ) + self._spi_flags = 0 + self._baud = 100000 + try: + self.pin_factory.connection.bb_spi_open( + select_pin, miso_pin, mosi_pin, clock_pin, + self._baud, self._spi_flags) + # Only set after opening bb_spi; if that fails then close() will + # also fail if bb_spi_close is attempted on an un-open interface + self._closed = False + except: + self.close() + raise + + def _conflicts_with(self, other): + return not ( + isinstance(other, PiGPIOSoftwareSPI) and + (self._select_pin) != (other._select_pin) + ) + + def close(self): + try: + self.pin_factory._spis.remove(self) + except (ReferenceError, ValueError): + # If the factory has died already or we're not present in its + # internal list, ignore the error + pass + if not self._closed and self.pin_factory.connection: + self._closed = True + self.pin_factory.connection.bb_spi_close(self._select_pin) + self.pin_factory.release_all(self) + super(PiGPIOSoftwareSPI, self).close() + + @property + def closed(self): + return self._closed + + def __repr__(self): + try: + self._check_open() + return ( + 'SPI(clock_pin=%d, mosi_pin=%d, miso_pin=%d, select_pin=%d)' % ( + self._clock_pin, self._mosi_pin, self._miso_pin, self._select_pin + )) + except DeviceClosed: + return 'SPI(closed)' + + def _spi_flags(self): + return ( + self._mode << 0 | + self._select_high << 2 | + self._lsb_first << 14 | + self._lsb_first << 15 + ) + + def _get_clock_mode(self): + return self._spi_flags & 0x3 + + def _set_clock_mode(self, value): + self._check_open() + if not 0 <= value < 4: + raise SPIInvalidClockMode("%d is not a valid SPI clock mode" % value) + self.pin_factory.connection.bb_spi_close(self._select_pin) + self._spi_flags = (self._spi_flags & ~0x3) | value + self.pin_factory.connection.bb_spi_open( + self._select_pin, self._miso_pin, self._mosi_pin, self._clock_pin, + self._baud, self._spi_flags) + + def _get_select_high(self): + return bool(self._spi_flags & 0x4) + + def _set_select_high(self, value): + self._check_open() + self.pin_factory.connection.bb_spi_close(self._select_pin) + self._spi_flags = (self._spi_flags & ~0x4) | (bool(value) << 2) + self.pin_factory.connection.bb_spi_open( + self._select_pin, self._miso_pin, self._mosi_pin, self._clock_pin, + self._baud, self._spi_flags) + + def _get_lsb_first(self): + return bool(self._spi_flags & 0xc000) + + def _set_lsb_first(self, value): + self._check_open() + self.pin_factory.connection.bb_spi_close(self._select_pin) + self._spi_flags = ( + (self._spi_flags & ~0xc000) + | (bool(value) << 14) + | (bool(value) << 15) + ) + self.pin_factory.connection.bb_spi_open( + self._select_pin, self._miso_pin, self._mosi_pin, self._clock_pin, + self._baud, self._spi_flags) + + def _get_rate(self): + return self._baud + + def _set_rate(self, value): + self._check_open() + value = int(value) + self.pin_factory.connection.bb_spi_close(self._select_pin) + self._baud = value + self.pin_factory.connection.bb_spi_open( + self._select_pin, self._miso_pin, self._mosi_pin, self._clock_pin, + self._baud, self._spi_flags) + + def transfer(self, data): + self._check_open() + count, data = self.pin_factory.connection.bb_spi_xfer( + self._select_pin, data) + if count < 0: + raise IOError('SPI transfer error %d' % count) + # Convert returned bytearray to list of ints. bb_spi only supports + # byte-sized words so no issues here + return [int(b) for b in data] + + +class PiGPIOHardwareSPIShared(SharedMixin, PiGPIOHardwareSPI): + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + return (pin_factory.host, clock_pin, select_pin) + + +class PiGPIOSoftwareSPIShared(SharedMixin, PiGPIOSoftwareSPI): + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory): + return (pin_factory.host, clock_pin, select_pin) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/rpigpio.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/rpigpio.py new file mode 100644 index 0000000..aa55119 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/rpigpio.py @@ -0,0 +1,232 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + +import warnings + +from RPi import GPIO + +from .local import LocalPiFactory, LocalPiPin +from ..exc import ( + PinInvalidFunction, + PinSetInput, + PinFixedPull, + PinInvalidPull, + PinInvalidState, + PinInvalidBounce, + PinPWMFixedValue, + ) + + +class RPiGPIOFactory(LocalPiFactory): + """ + Extends :class:`~gpiozero.pins.local.LocalPiFactory`. Uses the `RPi.GPIO`_ + library to interface to the Pi's GPIO pins. This is the default pin + implementation if the RPi.GPIO library is installed. Supports all features + including PWM (via software). + + Because this is the default pin implementation you can use it simply by + specifying an integer number for the pin in most operations, e.g.:: + + from gpiozero import LED + + led = LED(12) + + However, you can also construct RPi.GPIO pins manually if you wish:: + + from gpiozero.pins.rpigpio import RPiGPIOFactory + from gpiozero import LED + + factory = RPiGPIOFactory() + led = LED(12, pin_factory=factory) + + .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO + """ + + def __init__(self): + super(RPiGPIOFactory, self).__init__() + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + self.pin_class = RPiGPIOPin + + def close(self): + super(RPiGPIOFactory, self).close() + GPIO.cleanup() + + +class RPiGPIOPin(LocalPiPin): + """ + Extends :class:`~gpiozero.pins.local.LocalPiPin`. Pin implementation for + the `RPi.GPIO`_ library. See :class:`RPiGPIOFactory` for more information. + + .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO + """ + GPIO_FUNCTIONS = { + 'input': GPIO.IN, + 'output': GPIO.OUT, + 'i2c': GPIO.I2C, + 'spi': GPIO.SPI, + 'pwm': GPIO.HARD_PWM, + 'serial': GPIO.SERIAL, + 'unknown': GPIO.UNKNOWN, + } + + GPIO_PULL_UPS = { + 'up': GPIO.PUD_UP, + 'down': GPIO.PUD_DOWN, + 'floating': GPIO.PUD_OFF, + } + + GPIO_EDGES = { + 'both': GPIO.BOTH, + 'rising': GPIO.RISING, + 'falling': GPIO.FALLING, + } + + GPIO_FUNCTION_NAMES = {v: k for (k, v) in GPIO_FUNCTIONS.items()} + GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()} + GPIO_EDGES_NAMES = {v: k for (k, v) in GPIO_EDGES.items()} + + def __init__(self, factory, number): + super(RPiGPIOPin, self).__init__(factory, number) + self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + self._pwm = None + self._frequency = None + self._duty_cycle = None + self._bounce = -666 + self._edges = GPIO.BOTH + GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[self._pull]) + + def close(self): + self.frequency = None + self.when_changed = None + GPIO.cleanup(self.number) + + def output_with_state(self, state): + self._pull = 'floating' + GPIO.setup(self.number, GPIO.OUT, initial=state) + + def input_with_pull(self, pull): + if pull != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[pull]) + self._pull = pull + except KeyError: + raise PinInvalidPull('invalid pull "%s" for pin %r' % (pull, self)) + + def _get_function(self): + return self.GPIO_FUNCTION_NAMES[GPIO.gpio_function(self.number)] + + def _set_function(self, value): + if value != 'input': + self._pull = 'floating' + if value in ('input', 'output') and value in self.GPIO_FUNCTIONS: + GPIO.setup(self.number, self.GPIO_FUNCTIONS[value], self.GPIO_PULL_UPS[self._pull]) + else: + raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self)) + + def _get_state(self): + if self._pwm: + return self._duty_cycle + else: + return GPIO.input(self.number) + + def _set_state(self, value): + if self._pwm: + try: + self._pwm.ChangeDutyCycle(value * 100) + except ValueError: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + self._duty_cycle = value + else: + try: + GPIO.output(self.number, value) + except ValueError: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + except RuntimeError: + raise PinSetInput('cannot set state of pin %r' % self) + + def _get_pull(self): + return self._pull + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[value]) + self._pull = value + except KeyError: + raise PinInvalidPull('invalid pull "%s" for pin %r' % (value, self)) + + def _get_frequency(self): + return self._frequency + + def _set_frequency(self, value): + if self._frequency is None and value is not None: + try: + self._pwm = GPIO.PWM(self.number, value) + except RuntimeError: + raise PinPWMFixedValue('cannot start PWM on pin %r' % self) + self._pwm.start(0) + self._duty_cycle = 0 + self._frequency = value + elif self._frequency is not None and value is not None: + self._pwm.ChangeFrequency(value) + self._frequency = value + elif self._frequency is not None and value is None: + self._pwm.stop() + self._pwm = None + self._duty_cycle = None + self._frequency = None + + def _get_bounce(self): + return None if self._bounce == -666 else (self._bounce / 1000) + + def _set_bounce(self, value): + if value is not None and value < 0: + raise PinInvalidBounce('bounce must be 0 or greater') + f = self.when_changed + self.when_changed = None + try: + self._bounce = -666 if value is None else int(value * 1000) + finally: + self.when_changed = f + + def _get_edges(self): + return self.GPIO_EDGES_NAMES[self._edges] + + def _set_edges(self, value): + f = self.when_changed + self.when_changed = None + try: + self._edges = self.GPIO_EDGES[value] + finally: + self.when_changed = f + + def _call_when_changed(self, channel): + super(RPiGPIOPin, self)._call_when_changed() + + def _enable_event_detect(self): + GPIO.add_event_detect( + self.number, self._edges, + callback=self._call_when_changed, + bouncetime=self._bounce) + + def _disable_event_detect(self): + GPIO.remove_event_detect(self.number) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/rpio.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/rpio.py new file mode 100644 index 0000000..095e4d0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/rpio.py @@ -0,0 +1,226 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2015-2021 Dave Jones +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, + ) +str = type('') + + +import warnings + +import RPIO +import RPIO.PWM +from RPIO.Exceptions import InvalidChannelException + +from .local import LocalPiPin, LocalPiFactory +from .data import pi_info +from ..exc import ( + PinInvalidFunction, + PinSetInput, + PinFixedPull, + PinInvalidPull, + PinInvalidBounce, + PinInvalidState, + PinPWMError, + ) + + +class RPIOFactory(LocalPiFactory): + """ + Extends :class:`~gpiozero.pins.local.LocalPiFactory`. Uses the `RPIO`_ + library to interface to the Pi's GPIO pins. This is the default pin + implementation if the RPi.GPIO library is not installed, but RPIO is. + Supports all features including PWM (hardware via DMA). + + .. note:: + + Please note that at the time of writing, RPIO is only compatible with + Pi 1's; the Raspberry Pi 2 Model B is *not* supported. Also note that + root access is required so scripts must typically be run with ``sudo``. + + You can construct RPIO pins manually like so:: + + from gpiozero.pins.rpio import RPIOFactory + from gpiozero import LED + + factory = RPIOFactory() + led = LED(12, pin_factory=factory) + + .. _RPIO: https://pythonhosted.org/RPIO/ + """ + def __init__(self): + super(RPIOFactory, self).__init__() + RPIO.setmode(RPIO.BCM) + RPIO.setwarnings(False) + RPIO.wait_for_interrupts(threaded=True) + RPIO.PWM.setup() + RPIO.PWM.init_channel(0, 10000) + self.pin_class = RPIOPin + + def close(self): + RPIO.PWM.cleanup() + RPIO.stop_waiting_for_interrupts() + RPIO.cleanup() + + +class RPIOPin(LocalPiPin): + """ + Extends :class:`~gpiozero.pins.local.LocalPiPin`. Pin implementation for + the `RPIO`_ library. See :class:`RPIOFactory` for more information. + + .. _RPIO: https://pythonhosted.org/RPIO/ + """ + GPIO_FUNCTIONS = { + 'input': RPIO.IN, + 'output': RPIO.OUT, + 'alt0': RPIO.ALT0, + } + + GPIO_PULL_UPS = { + 'up': RPIO.PUD_UP, + 'down': RPIO.PUD_DOWN, + 'floating': RPIO.PUD_OFF, + } + + GPIO_FUNCTION_NAMES = {v: k for (k, v) in GPIO_FUNCTIONS.items()} + GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()} + + def __init__(self, factory, number): + super(RPIOPin, self).__init__(factory, number) + self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' + self._pwm = False + self._duty_cycle = None + self._bounce = None + self._edges = 'both' + try: + RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[self._pull]) + except InvalidChannelException as e: + raise ValueError(e) + + def close(self): + self.frequency = None + self.when_changed = None + RPIO.setup(self.number, RPIO.IN, RPIO.PUD_OFF) + + def _get_function(self): + return self.GPIO_FUNCTION_NAMES[RPIO.gpio_function(self.number)] + + def _set_function(self, value): + if value != 'input': + self._pull = 'floating' + try: + RPIO.setup(self.number, self.GPIO_FUNCTIONS[value], self.GPIO_PULL_UPS[self._pull]) + except KeyError: + raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self)) + + def _get_state(self): + if self._pwm: + return self._duty_cycle + else: + return RPIO.input(self.number) + + def _set_state(self, value): + if not 0 <= value <= 1: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + if self._pwm: + RPIO.PWM.clear_channel_gpio(0, self.number) + if value == 0: + RPIO.output(self.number, False) + elif value == 1: + RPIO.output(self.number, True) + else: + RPIO.PWM.add_channel_pulse(0, self.number, start=0, width=int(1000 * value)) + self._duty_cycle = value + else: + try: + RPIO.output(self.number, value) + except ValueError: + raise PinInvalidState('invalid state "%s" for pin %r' % (value, self)) + except RuntimeError: + raise PinSetInput('cannot set state of pin %r' % self) + + def _get_pull(self): + return self._pull + + def _set_pull(self, value): + if self.function != 'input': + raise PinFixedPull('cannot set pull on non-input pin %r' % self) + if value != 'up' and self.factory.pi_info.pulled_up(repr(self)): + raise PinFixedPull('%r has a physical pull-up resistor' % self) + try: + RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[value]) + self._pull = value + except KeyError: + raise PinInvalidPull('invalid pull "%s" for pin %r' % (value, self)) + + def _get_frequency(self): + if self._pwm: + return 100 + else: + return None + + def _set_frequency(self, value): + if value is not None and value != 100: + raise PinPWMError( + 'RPIOPin implementation is currently limited to ' + '100Hz sub-cycles') + if not self._pwm and value is not None: + self._pwm = True + # Dirty hack to get RPIO's PWM support to setup, but do nothing, + # for a given GPIO pin + RPIO.PWM.add_channel_pulse(0, self.number, start=0, width=0) + RPIO.PWM.clear_channel_gpio(0, self.number) + elif self._pwm and value is None: + RPIO.PWM.clear_channel_gpio(0, self.number) + self._pwm = False + + def _get_bounce(self): + return None if self._bounce is None else (self._bounce / 1000) + + def _set_bounce(self, value): + if value is not None and value < 0: + raise PinInvalidBounce('bounce must be 0 or greater') + f = self.when_changed + self.when_changed = None + try: + self._bounce = None if value is None else int(value * 1000) + finally: + self.when_changed = f + + def _get_edges(self): + return self._edges + + def _set_edges(self, value): + f = self.when_changed + self.when_changed = None + try: + self._edges = value + finally: + self.when_changed = f + + def _call_when_changed(self, channel, value): + super(RPIOPin, self)._call_when_changed() + + def _enable_event_detect(self): + RPIO.add_interrupt_callback( + self.number, self._call_when_changed, self._edges, + self.GPIO_PULL_UPS[self._pull], self._bounce) + + def _disable_event_detect(self): + try: + RPIO.del_interrupt_callback(self.number) + except KeyError: + # Ignore this exception which occurs during shutdown; this + # simply means RPIO's built-in cleanup has already run and + # removed the handler + pass diff --git a/.venv/lib/python3.7/site-packages/gpiozero/pins/spi.py b/.venv/lib/python3.7/site-packages/gpiozero/pins/spi.py new file mode 100644 index 0000000..749936e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/pins/spi.py @@ -0,0 +1,104 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +str = type('') + + +import operator +from threading import RLock + +from ..devices import Device, SharedMixin +from ..input_devices import InputDevice +from ..output_devices import OutputDevice + + +class SPISoftwareBus(SharedMixin, Device): + def __init__(self, clock_pin, mosi_pin, miso_pin): + self.lock = None + self.clock = None + self.mosi = None + self.miso = None + super(SPISoftwareBus, self).__init__() + self.lock = RLock() + try: + self.clock = OutputDevice(clock_pin, active_high=True) + if mosi_pin is not None: + self.mosi = OutputDevice(mosi_pin) + if miso_pin is not None: + self.miso = InputDevice(miso_pin) + except: + self.close() + raise + + def close(self): + super(SPISoftwareBus, self).close() + if getattr(self, 'lock', None): + with self.lock: + if self.miso is not None: + self.miso.close() + self.miso = None + if self.mosi is not None: + self.mosi.close() + self.mosi = None + if self.clock is not None: + self.clock.close() + self.clock = None + self.lock = None + + @property + def closed(self): + return self.lock is None + + @classmethod + def _shared_key(cls, clock_pin, mosi_pin, miso_pin): + return (clock_pin, mosi_pin, miso_pin) + + def transfer(self, data, clock_phase=False, lsb_first=False, bits_per_word=8): + """ + Writes data (a list of integer words where each word is assumed to have + :attr:`bits_per_word` bits or less) to the SPI interface, and reads an + equivalent number of words, returning them as a list of integers. + """ + result = [] + with self.lock: + # See https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus + # (specifically the section "Example of bit-banging the master + # protocol") for a simpler C implementation of this which ignores + # clock polarity, phase, variable word-size, and multiple input + # words + if lsb_first: + shift = operator.lshift + init_mask = 1 + else: + shift = operator.rshift + init_mask = 1 << (bits_per_word - 1) + for write_word in data: + mask = init_mask + read_word = 0 + for _ in range(bits_per_word): + if self.mosi is not None: + self.mosi.value = bool(write_word & mask) + # read bit on clock activation + self.clock.on() + if not clock_phase: + if self.miso is not None and self.miso.value: + read_word |= mask + # read bit on clock deactivation + self.clock.off() + if clock_phase: + if self.miso is not None and self.miso.value: + read_word |= mask + mask = shift(mask, 1) + result.append(read_word) + return result diff --git a/.venv/lib/python3.7/site-packages/gpiozero/spi_devices.py b/.venv/lib/python3.7/site-packages/gpiozero/spi_devices.py new file mode 100644 index 0000000..b758259 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/spi_devices.py @@ -0,0 +1,557 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2020 Grzegorz Szymaszek +# Copyright (c) 2016-2019 Andrew Scheller +# Copyright (c) 2016-2018 Ben Nuttall +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +str = type('') + + +from math import log, ceil +from operator import or_ +try: + from functools import reduce +except ImportError: + pass # py2's reduce is built-in + +from .exc import DeviceClosed, SPIBadChannel, InputDeviceError +from .devices import Device + + +class SPIDevice(Device): + """ + Extends :class:`Device`. Represents a device that communicates via the SPI + protocol. + + See :ref:`spi_args` for information on the keyword arguments that can be + specified with the constructor. + """ + def __init__(self, **spi_args): + self._spi = None + super(SPIDevice, self).__init__( + pin_factory=spi_args.pop('pin_factory', None) + ) + self._spi = self.pin_factory.spi(**spi_args) + + def close(self): + if getattr(self, '_spi', None): + self._spi.close() + self._spi = None + super(SPIDevice, self).close() + + @property + def closed(self): + return self._spi is None + + def _int_to_words(self, pattern): + """ + Given a bit-pattern expressed an integer number, return a sequence of + the individual words that make up the pattern. The number of bits per + word will be obtained from the internal SPI interface. + """ + try: + bits_required = int(ceil(log(pattern, 2))) + 1 + except ValueError: + # pattern == 0 (technically speaking, no bits are required to + # transmit the value zero ;) + bits_required = 1 + shifts = range(0, bits_required, self._spi.bits_per_word)[::-1] + mask = 2 ** self._spi.bits_per_word - 1 + return [(pattern >> shift) & mask for shift in shifts] + + def _words_to_int(self, words, expected_bits=None): + """ + Given a sequence of words which each fit in the internal SPI + interface's number of bits per word, returns the value obtained by + concatenating each word into a single bit-string. + + If *expected_bits* is specified, it limits the size of the output to + the specified number of bits (by masking off bits above the expected + number). If unspecified, no limit will be applied. + """ + if expected_bits is None: + expected_bits = len(words) * self._spi.bits_per_word + shifts = range(0, expected_bits, self._spi.bits_per_word)[::-1] + mask = 2 ** expected_bits - 1 + return reduce(or_, (word << shift for word, shift in zip(words, shifts))) & mask + + def __repr__(self): + try: + self._check_open() + return "" % (self.__class__.__name__, self._spi) + except DeviceClosed: + return "" % self.__class__.__name__ + + +class AnalogInputDevice(SPIDevice): + """ + Represents an analog input device connected to SPI (serial interface). + + Typical analog input devices are `analog to digital converters`_ (ADCs). + Several classes are provided for specific ADC chips, including + :class:`MCP3004`, :class:`MCP3008`, :class:`MCP3204`, and :class:`MCP3208`. + + The following code demonstrates reading the first channel of an MCP3008 + chip attached to the Pi's SPI pins:: + + from gpiozero import MCP3008 + + pot = MCP3008(0) + print(pot.value) + + The :attr:`value` attribute is normalized such that its value is always + between 0.0 and 1.0 (or in special cases, such as differential sampling, + -1 to +1). Hence, you can use an analog input to control the brightness of + a :class:`PWMLED` like so:: + + from gpiozero import MCP3008, PWMLED + + pot = MCP3008(0) + led = PWMLED(17) + led.source = pot + + The :attr:`voltage` attribute reports values between 0.0 and *max_voltage* + (which defaults to 3.3, the logic level of the GPIO pins). + + .. _analog to digital converters: https://en.wikipedia.org/wiki/Analog-to-digital_converter + """ + + def __init__(self, bits, max_voltage=3.3, **spi_args): + if bits is None: + raise InputDeviceError('you must specify the bit resolution of the device') + self._bits = bits + self._min_value = -(2 ** bits) + self._range = 2 ** (bits + 1) - 1 + if max_voltage <= 0: + raise InputDeviceError('max_voltage must be positive') + self._max_voltage = float(max_voltage) + super(AnalogInputDevice, self).__init__(shared=True, **spi_args) + + @property + def bits(self): + """ + The bit-resolution of the device/channel. + """ + return self._bits + + def _read(self): + raise NotImplementedError + + @property + def value(self): + """ + The current value read from the device, scaled to a value between 0 and + 1 (or -1 to +1 for certain devices operating in differential mode). + """ + return (2 * (self._read() - self._min_value) / self._range) - 1 + + @property + def raw_value(self): + """ + The raw value as read from the device. + """ + return self._read() + + @property + def max_voltage(self): + """ + The voltage required to set the device's value to 1. + """ + return self._max_voltage + + @property + def voltage(self): + """ + The current voltage read from the device. This will be a value between + 0 and the *max_voltage* parameter specified in the constructor. + """ + return self.value * self._max_voltage + + +class MCP3xxx(AnalogInputDevice): + """ + Extends :class:`AnalogInputDevice` to implement an interface for all ADC + chips with a protocol similar to the Microchip MCP3xxx series of devices. + """ + + def __init__(self, channel=0, bits=10, differential=False, max_voltage=3.3, + **spi_args): + self._channel = channel + self._differential = bool(differential) + super(MCP3xxx, self).__init__(bits, max_voltage, **spi_args) + + @property + def channel(self): + """ + The channel to read data from. The MCP3008/3208/3304 have 8 channels + (0-7), while the MCP3004/3204/3302 have 4 channels (0-3), the + MCP3002/3202 have 2 channels (0-1), and the MCP3001/3201/3301 only + have 1 channel. + """ + return self._channel + + @property + def differential(self): + """ + If ``True``, the device is operated in differential mode. In this mode + one channel (specified by the channel attribute) is read relative to + the value of a second channel (implied by the chip's design). + + Please refer to the device data-sheet to determine which channel is + used as the relative base value (for example, when using an + :class:`MCP3008` in differential mode, channel 0 is read relative to + channel 1). + """ + return self._differential + + def _read(self): + return self._words_to_int( + self._spi.transfer(self._send())[-2:], self.bits + ) + + def _send(self): + # MCP3004/08 protocol looks like the following: + # + # Byte 0 1 2 + # ==== ======== ======== ======== + # Tx 00000001 MCCCxxxx xxxxxxxx + # Rx xxxxxxxx xxxxx0RR RRRRRRRR + # + # MCP3204/08 protocol looks like the following: + # + # Byte 0 1 2 + # ==== ======== ======== ======== + # Tx 000001MC CCxxxxxx xxxxxxxx + # Rx xxxxxxxx xxx0RRRR RRRRRRRR + # + # The transmit bits start with several preamble "0" bits, the number + # of which is determined by the amount required to align the last byte + # of the result with the final byte of output. A start "1" bit is then + # transmitted, followed by the single/differential bit (M); 1 for + # single-ended read, 0 for differential read. Next comes three bits for + # channel (C). + # + # Read-out begins with a don't care bit (x), then a null bit (0) + # followed by the result bits (R). All other bits are don't care (x). + # + # The 3x01 variant of the chips always operates in differential mode + # and effectively only has one channel (composed of an IN+ and IN-). As + # such it requires no input, just output. + return self._int_to_words( + (0b10000 | (not self.differential) << 3 | self.channel) << (self.bits + 2) + ) + + +class MCP3xx2(MCP3xxx): + def _send(self): + # MCP3002 protocol looks like the following: + # + # Byte 0 1 + # ==== ======== ======== + # Tx 01MCLxxx xxxxxxxx + # Rx xxxxx0RR RRRRRRRR for the 3002 + # + # MCP3202 protocol looks like the following: + # + # Byte 0 1 2 + # ==== ======== ======== ======== + # Tx 00000001 MCLxxxxx xxxxxxxx + # Rx xxxxxxxx xxx0RRRR RRRRRRRR + # + # The transmit bits start with several preamble "0" bits, the number of + # which is determined by the amount required to align the last byte of + # the result with the final byte of output. A start "1" bit is then + # transmitted, followed by the single/differential bit (M); 1 for + # single-ended read, 0 for differential read. Next comes a single bit + # for channel (C) then the MSBF bit (L) which selects whether the data + # will be read out in MSB form only (1) or whether LSB read-out will + # occur after MSB read-out (0). + # + # Read-out begins with a null bit (0) followed by the result bits (R). + # All other bits are don't care (x). + return self._int_to_words( + (0b1001 | (not self.differential) << 2 | self.channel << 1) << (self.bits + 1) + ) + + +class MCP30xx(MCP3xxx): + """ + Extends :class:`MCP3xxx` to implement an interface for all ADC + chips with a protocol similar to the Microchip MCP30xx series of devices. + """ + + def __init__(self, channel=0, differential=False, max_voltage=3.3, + **spi_args): + super(MCP30xx, self).__init__(channel, 10, differential, max_voltage, + **spi_args) + + +class MCP32xx(MCP3xxx): + """ + Extends :class:`MCP3xxx` to implement an interface for all ADC + chips with a protocol similar to the Microchip MCP32xx series of devices. + """ + + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + super(MCP32xx, self).__init__(channel, 12, differential, max_voltage, + **spi_args) + + +class MCP33xx(MCP3xxx): + """ + Extends :class:`MCP3xxx` with functionality specific to the MCP33xx family + of ADCs; specifically this handles the full differential capability of + these chips supporting the full 13-bit signed range of output values. + """ + + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + super(MCP33xx, self).__init__(channel, 12, differential, max_voltage, + **spi_args) + + def _read(self): + if self.differential: + result = self._words_to_int( + self._spi.transfer(self._send())[-2:], self.bits + 1) + # Account for the sign bit + if result > 4095: + return -(8192 - result) + else: + return result + else: + return super(MCP33xx, self)._read() + + def _send(self): + # MCP3302/04 protocol looks like the following: + # + # Byte 0 1 2 + # ==== ======== ======== ======== + # Tx 00001MCC Cxxxxxxx xxxxxxxx + # Rx xxxxxxxx xx0SRRRR RRRRRRRR + # + # The transmit bits start with 4 preamble bits "0000", a start bit "1" + # followed by the single/differential bit (M) which is 1 for + # single-ended read, and 0 for differential read, followed by 3-bits + # for the channel (C). The remainder of the transmission are "don't + # care" bits (x). + # + # The first byte received and the top 2 bits of the second byte are + # don't care bits (x). These are followed by a null bit (0), then the + # sign bit (S), and then the 12 result bits (R). + # + # In single read mode (the default) the sign bit is always zero and the + # result is effectively 12-bits. In differential mode, the sign bit is + # significant and the result is a two's-complement 13-bit value. + # + # The MCP3301 variant operates similarly to the other MCP3x01 variants; + # no input, just output and always differential. + return self._int_to_words( + (0b10000 | (not self.differential) << 3 | self.channel) << (self.bits + 3) + ) + + @property + def differential(self): + """ + If ``True``, the device is operated in differential mode. In this mode + one channel (specified by the channel attribute) is read relative to + the value of a second channel (implied by the chip's design). + + Please refer to the device data-sheet to determine which channel is + used as the relative base value (for example, when using an + :class:`MCP3304` in differential mode, channel 0 is read relative to + channel 1). + """ + return super(MCP33xx, self).differential + + @property + def value(self): + """ + The current value read from the device, scaled to a value between 0 and + 1 (or -1 to +1 for devices operating in differential mode). + """ + return super(MCP33xx, self).value + + +class MCP3001(MCP30xx): + """ + The `MCP3001`_ is a 10-bit analog to digital converter with 1 channel. + Please note that the MCP3001 always operates in differential mode, + measuring the value of IN+ relative to IN-. + + .. _MCP3001: http://www.farnell.com/datasheets/630400.pdf + """ + def __init__(self, max_voltage=3.3, **spi_args): + super(MCP3001, self).__init__(0, True, max_voltage, **spi_args) + + def _read(self): + # MCP3001 protocol looks like the following: + # + # Byte 0 1 + # ==== ======== ======== + # Rx xx0RRRRR RRRRRxxx + return self._words_to_int(self._spi.read(2), 13) >> 3 + + +class MCP3002(MCP30xx, MCP3xx2): + """ + The `MCP3002`_ is a 10-bit analog to digital converter with 2 channels + (0-1). + + .. _MCP3002: http://www.farnell.com/datasheets/1599363.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 2: + raise SPIBadChannel('channel must be 0 or 1') + super(MCP3002, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3004(MCP30xx): + """ + The `MCP3004`_ is a 10-bit analog to digital converter with 4 channels + (0-3). + + .. _MCP3004: http://www.farnell.com/datasheets/808965.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 4: + raise SPIBadChannel('channel must be between 0 and 3') + super(MCP3004, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3008(MCP30xx): + """ + The `MCP3008`_ is a 10-bit analog to digital converter with 8 channels + (0-7). + + .. _MCP3008: http://www.farnell.com/datasheets/808965.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 8: + raise SPIBadChannel('channel must be between 0 and 7') + super(MCP3008, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3201(MCP32xx): + """ + The `MCP3201`_ is a 12-bit analog to digital converter with 1 channel. + Please note that the MCP3201 always operates in differential mode, + measuring the value of IN+ relative to IN-. + + .. _MCP3201: http://www.farnell.com/datasheets/1669366.pdf + """ + def __init__(self, max_voltage=3.3, **spi_args): + super(MCP3201, self).__init__(0, True, max_voltage, **spi_args) + + def _read(self): + # MCP3201 protocol looks like the following: + # + # Byte 0 1 + # ==== ======== ======== + # Rx xx0RRRRR RRRRRRRx + return self._words_to_int(self._spi.read(2), 13) >> 1 + + +class MCP3202(MCP32xx, MCP3xx2): + """ + The `MCP3202`_ is a 12-bit analog to digital converter with 2 channels + (0-1). + + .. _MCP3202: http://www.farnell.com/datasheets/1669376.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 2: + raise SPIBadChannel('channel must be 0 or 1') + super(MCP3202, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3204(MCP32xx): + """ + The `MCP3204`_ is a 12-bit analog to digital converter with 4 channels + (0-3). + + .. _MCP3204: http://www.farnell.com/datasheets/808967.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 4: + raise SPIBadChannel('channel must be between 0 and 3') + super(MCP3204, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3208(MCP32xx): + """ + The `MCP3208`_ is a 12-bit analog to digital converter with 8 channels + (0-7). + + .. _MCP3208: http://www.farnell.com/datasheets/808967.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 8: + raise SPIBadChannel('channel must be between 0 and 7') + super(MCP3208, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3301(MCP33xx): + """ + The `MCP3301`_ is a signed 13-bit analog to digital converter. Please note + that the MCP3301 always operates in differential mode measuring the + difference between IN+ and IN-. Its output value is scaled from -1 to +1. + + .. _MCP3301: http://www.farnell.com/datasheets/1669397.pdf + """ + def __init__(self, max_voltage=3.3, **spi_args): + super(MCP3301, self).__init__(0, True, max_voltage, **spi_args) + + def _read(self): + # MCP3301 protocol looks like the following: + # + # Byte 0 1 + # ==== ======== ======== + # Rx xx0SRRRR RRRRRRRR + result = self._words_to_int(self._spi.read(2), 13) + # Account for the sign bit + if result > 4095: + return -(8192 - result) + else: + return result + + +class MCP3302(MCP33xx): + """ + The `MCP3302`_ is a 12/13-bit analog to digital converter with 4 channels + (0-3). When operated in differential mode, the device outputs a signed + 13-bit value which is scaled from -1 to +1. When operated in single-ended + mode (the default), the device outputs an unsigned 12-bit value scaled from + 0 to 1. + + .. _MCP3302: http://www.farnell.com/datasheets/1486116.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 4: + raise SPIBadChannel('channel must be between 0 and 4') + super(MCP3302, self).__init__(channel, differential, max_voltage, **spi_args) + + +class MCP3304(MCP33xx): + """ + The `MCP3304`_ is a 12/13-bit analog to digital converter with 8 channels + (0-7). When operated in differential mode, the device outputs a signed + 13-bit value which is scaled from -1 to +1. When operated in single-ended + mode (the default), the device outputs an unsigned 12-bit value scaled from + 0 to 1. + + .. _MCP3304: http://www.farnell.com/datasheets/1486116.pdf + """ + def __init__(self, channel=0, differential=False, max_voltage=3.3, **spi_args): + if not 0 <= channel < 8: + raise SPIBadChannel('channel must be between 0 and 7') + super(MCP3304, self).__init__(channel, differential, max_voltage, **spi_args) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/threads.py b/.venv/lib/python3.7/site-packages/gpiozero/threads.py new file mode 100644 index 0000000..7ffc877 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/threads.py @@ -0,0 +1,62 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, + ) +str = type('') + +from threading import Thread, Event + +from .exc import ZombieThread + + +_THREADS = set() +def _threads_shutdown(): + while _THREADS: + threads = _THREADS.copy() + # Optimization: instead of calling stop() which implicitly calls + # join(), set all the stopping events simultaneously, *then* join + # threads with a reasonable timeout + for t in threads: + t.stopping.set() + for t in threads: + t.join(10) + + +class GPIOThread(Thread): + def __init__(self, target, args=(), kwargs=None, name=None): + if kwargs is None: + kwargs = {} + self.stopping = Event() + super(GPIOThread, self).__init__(None, target, name, args, kwargs) + self.daemon = True + + def start(self): + self.stopping.clear() + _THREADS.add(self) + super(GPIOThread, self).start() + + def stop(self, timeout=10): + self.stopping.set() + self.join(timeout) + + def join(self, timeout=None): + super(GPIOThread, self).join(timeout) + if self.is_alive(): + assert timeout is not None + # timeout can't be None here because if it was, then join() + # wouldn't return until the thread was dead + raise ZombieThread( + "Thread failed to die within %d seconds" % timeout) + else: + _THREADS.discard(self) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/tones.py b/.venv/lib/python3.7/site-packages/gpiozero/tones.py new file mode 100644 index 0000000..1cb3c3b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/tones.py @@ -0,0 +1,250 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2019 Dave Jones +# Copyright (c) 2019 Ben Nuttall +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, +) +str = type('') + +import re +import warnings +from collections import namedtuple +try: + from math import log2 +except ImportError: + from .compat import log2 + +from .exc import AmbiguousTone + + +class Tone(float): + """ + Represents a frequency of sound in a variety of musical notations. + + :class:`Tone` class can be used with the :class:`~gpiozero.TonalBuzzer` + class to easily represent musical tones. The class can be constructed in a + variety of ways. For example as a straight frequency in `Hz`_ (which is the + internal storage format), as an integer MIDI note, or as a string + representation of a musical note. + + All the following constructors are equivalent ways to construct the typical + tuning note, `concert A`_ at 440Hz, which is MIDI note #69: + + >>> from gpiozero.tones import Tone + >>> Tone(440.0) + >>> Tone(69) + >>> Tone('A4') + + If you do not want the constructor to guess which format you are using + (there is some ambiguity between frequencies and MIDI notes at the bottom + end of the frequencies, from 128Hz down), you can use one of the explicit + constructors, :meth:`from_frequency`, :meth:`from_midi`, or + :meth:`from_note`, or you can specify a keyword argument when + constructing:: + + >>> Tone.from_frequency(440) + >>> Tone.from_midi(69) + >>> Tone.from_note('A4') + >>> Tone(frequency=440) + >>> Tone(midi=69) + >>> Tone(note='A4') + + Several attributes are provided to permit conversion to any of the + supported construction formats: :attr:`frequency`, :attr:`midi`, and + :attr:`note`. Methods are provided to step :meth:`up` or :meth:`down` to + adjacent MIDI notes. + + .. warning:: + + Currently :class:`Tone` derives from :class:`float` and can be used as + a floating point number in most circumstances (addition, subtraction, + etc). This part of the API is not yet considered "stable"; i.e. we may + decide to enhance / change this behaviour in future versions. + + .. _Hz: https://en.wikipedia.org/wiki/Hertz + .. _concert A: https://en.wikipedia.org/wiki/Concert_pitch + """ + + tones = 'CCDDEFFGGAAB' + semitones = { + 'â™­': -1, + 'b': -1, + 'â™®': 0, + '': 0, + '♯': 1, + '#': 1, + } + regex = re.compile( + r'(?P[A-G])' + r'(?P[%s]?)' + r'(?P[0-9])' % ''.join(semitones.keys())) + + def __new__(cls, value=None, **kwargs): + if value is None: + if len(kwargs) != 1: + raise TypeError('expected precisely one keyword argument') + key, value = kwargs.popitem() + try: + return { + 'frequency': cls.from_frequency, + 'midi': cls.from_midi, + 'note': cls.from_note, + }[key](value) + except KeyError: + raise TypeError('unexpected keyword argument %r' % key) + else: + if kwargs: + raise TypeError('cannot specify keywords with a value') + if isinstance(value, (int, float)): + if 0 <= value < 128: + if value > 0: + warnings.warn( + AmbiguousTone( + "Ambiguous tone specification; assuming you " + "want a MIDI note. To suppress this warning " + "use, e.g. Tone(midi=60), or to obtain a " + "frequency instead use, e.g. Tone(frequency=" + "60)")) + return cls.from_midi(value) + else: + return cls.from_frequency(value) + elif isinstance(value, (bytes, str)): + return cls.from_note(value) + else: + return cls.from_frequency(value) + + def __str__(self): + return self.note + + def __repr__(self): + try: + midi = self.midi + except ValueError: + midi = '' + else: + midi = ' midi=%r' % midi + try: + note = self.note + except ValueError: + note = '' + else: + note = ' note=%r' % note + return "" % (note, midi, self.frequency) + + @classmethod + def from_midi(cls, midi_note): + """ + Construct a :class:`Tone` from a MIDI note, which must be an integer + in the range 0 to 127. For reference, A4 (`concert A`_ typically used + for tuning) is MIDI note #69. + + .. _concert A: https://en.wikipedia.org/wiki/Concert_pitch + """ + midi = int(midi_note) + if 0 <= midi_note < 128: + A4_midi = 69 + A4_freq = 440 + return cls.from_frequency(A4_freq * 2 ** ((midi - A4_midi) / 12)) + raise ValueError('invalid MIDI note: %r' % midi) + + @classmethod + def from_note(cls, note): + """ + Construct a :class:`Tone` from a musical note which must consist of + a capital letter A through G, followed by an optional semi-tone + modifier ("b" for flat, "#" for sharp, or their Unicode equivalents), + followed by an octave number (0 through 9). + + For example `concert A`_, the typical tuning note at 440Hz, would be + represented as "A4". One semi-tone above this would be "A#4" or + alternatively "Bb4". Unicode representations of sharp and flat are also + accepted. + """ + if isinstance(note, bytes): + note = note.decode('ascii') + if isinstance(note, str): + match = Tone.regex.match(note) + if match: + octave = int(match.group('octave')) + 1 + return cls.from_midi( + Tone.tones.index(match.group('note')) + + Tone.semitones[match.group('semi')] + + octave * 12) + raise ValueError('invalid note specification: %r' % note) + + @classmethod + def from_frequency(cls, freq): + """ + Construct a :class:`Tone` from a frequency specified in `Hz`_ which + must be a positive floating-point value in the range 0 < freq <= 20000. + + .. _Hz: https://en.wikipedia.org/wiki/Hertz + """ + if 0 < freq <= 20000: + return super(Tone, cls).__new__(cls, freq) + raise ValueError('invalid frequency: %.2f' % freq) + + @property + def frequency(self): + """ + Return the frequency of the tone in `Hz`_. + + .. _Hz: https://en.wikipedia.org/wiki/Hertz + """ + return float(self) + + @property + def midi(self): + """ + Return the (nearest) MIDI note to the tone's frequency. This will be an + integer number in the range 0 to 127. If the frequency is outside the + range represented by MIDI notes (which is approximately 8Hz to 12.5KHz) + :exc:`ValueError` exception will be raised. + """ + result = int(round(12 * log2(self.frequency / 440) + 69)) + if 0 <= result < 128: + return result + raise ValueError('%f is outside the MIDI note range' % self.frequency) + + @property + def note(self): + """ + Return the (nearest) note to the tone's frequency. This will be a + string in the form accepted by :meth:`from_note`. If the frequency is + outside the range represented by this format ("A0" is approximately + 27.5Hz, and "G9" is approximately 12.5Khz) a :exc:`ValueError` + exception will be raised. + """ + offset = self.midi - 60 # self.midi - A4_midi + Tone.tones.index('A') + index = offset % 12 # offset % len(Tone.tones) + octave = 4 + offset // 12 + if 0 <= octave <= 9: + return ( + Tone.tones[index] + + ('#' if Tone.tones[index] == Tone.tones[index - 1] else '') + + str(octave) + ) + raise ValueError('%f is outside the notation range' % self.frequency) + + def up(self, n=1): + """ + Return the :class:`Tone` *n* semi-tones above this frequency (*n* + defaults to 1). + """ + return Tone.from_midi(self.midi + n) + + def down(self, n=1): + """ + Return the :class:`Tone` *n* semi-tones below this frequency (*n* + defaults to 1). + """ + return Tone.from_midi(self.midi - n) diff --git a/.venv/lib/python3.7/site-packages/gpiozero/tools.py b/.venv/lib/python3.7/site-packages/gpiozero/tools.py new file mode 100644 index 0000000..50f5aa6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/gpiozero/tools.py @@ -0,0 +1,755 @@ +# vim: set fileencoding=utf-8: +# +# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +# +# Copyright (c) 2016-2021 Dave Jones +# Copyright (c) 2016-2019 Ben Nuttall +# Copyright (c) 2016 Andrew Scheller +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import ( + unicode_literals, + print_function, + absolute_import, + division, +) +str = type('') + + +from random import random +from time import sleep +from .mixins import ValuesMixin +try: + from itertools import izip as zip +except ImportError: + pass +from itertools import cycle +from math import sin, cos, pi +try: + from statistics import mean +except ImportError: + from .compat import mean +try: + from math import isclose +except ImportError: + from .compat import isclose + + +def _normalize(values): + """ + If *values* is a ``ValuesMixin`` derivative, return ``values.values``, + otherwise return `values` as provided. Intended to allow support for:: + + led.source = foo(btn) + + and:: + + led.source = foo(btn.values) + + and:: + + led.source = foo(some_iterator) + """ + if isinstance(values, ValuesMixin): + return values.values + return values + + +def negated(values): + """ + Returns the negation of the supplied values (:data:`True` becomes + :data:`False`, and :data:`False` becomes :data:`True`). For example:: + + from gpiozero import Button, LED + from gpiozero.tools import negated + from signal import pause + + led = LED(4) + btn = Button(17) + + led.source = negated(btn) + + pause() + """ + values = _normalize(values) + for v in values: + yield not v + + +def inverted(values, input_min=0, input_max=1): + """ + Returns the inversion of the supplied values (*input_min* becomes + *input_max*, *input_max* becomes *input_min*, `input_min + 0.1` becomes + `input_max - 0.1`, etc.). All items in *values* are assumed to be between + *input_min* and *input_max* (which default to 0 and 1 respectively), and + the output will be in the same range. For example:: + + from gpiozero import MCP3008, PWMLED + from gpiozero.tools import inverted + from signal import pause + + led = PWMLED(4) + pot = MCP3008(channel=0) + + led.source = inverted(pot) + + pause() + """ + values = _normalize(values) + if input_min >= input_max: + raise ValueError('input_min must be smaller than input_max') + for v in values: + yield input_min + input_max - v + + +def scaled(values, output_min, output_max, input_min=0, input_max=1): + """ + Returns *values* scaled from *output_min* to *output_max*, assuming that + all items in *values* lie between *input_min* and *input_max* (which + default to 0 and 1 respectively). For example, to control the direction of + a motor (which is represented as a value between -1 and 1) using a + potentiometer (which typically provides values between 0 and 1):: + + from gpiozero import Motor, MCP3008 + from gpiozero.tools import scaled + from signal import pause + + motor = Motor(20, 21) + pot = MCP3008(channel=0) + + motor.source = scaled(pot, -1, 1) + + pause() + + .. warning:: + + If *values* contains elements that lie outside *input_min* to + *input_max* (inclusive) then the function will not produce values that + lie within *output_min* to *output_max* (inclusive). + """ + values = _normalize(values) + if input_min >= input_max: + raise ValueError('input_min must be smaller than input_max') + input_size = input_max - input_min + output_size = output_max - output_min + for v in values: + yield (((v - input_min) / input_size) * output_size) + output_min + + +def scaled_full(values): + """ + A convenience function that builds on :func:`scaled`. It converts a + "half-range" value (0..1) to a "full-range" value (-1..1). This is + equivalent to calling:: + + scaled(values, -1, 1, 0, 1) + """ + return scaled(values, -1, 1, 0, 1) + + +def scaled_half(values): + """ + A convenience function that builds on :func:`scaled`. It converts a + "full-range" value (-1..1) to a "half-range" value (0..1). This is + equivalent to calling:: + + scaled(values, 0, 1, -1, 1) + """ + return scaled(values, 0, 1, -1, 1) + + +def clamped(values, output_min=0, output_max=1): + """ + Returns *values* clamped from *output_min* to *output_max*, i.e. any items + less than *output_min* will be returned as *output_min* and any items + larger than *output_max* will be returned as *output_max* (these default to + 0 and 1 respectively). For example:: + + from gpiozero import PWMLED, MCP3008 + from gpiozero.tools import clamped + from signal import pause + + led = PWMLED(4) + pot = MCP3008(channel=0) + + led.source = clamped(pot, 0.5, 1.0) + + pause() + """ + values = _normalize(values) + if output_min >= output_max: + raise ValueError('output_min must be smaller than output_max') + for v in values: + yield min(max(v, output_min), output_max) + + +def absoluted(values): + """ + Returns *values* with all negative elements negated (so that they're + positive). For example:: + + from gpiozero import PWMLED, Motor, MCP3008 + from gpiozero.tools import absoluted, scaled + from signal import pause + + led = PWMLED(4) + motor = Motor(22, 27) + pot = MCP3008(channel=0) + + motor.source = scaled(pot, -1, 1) + led.source = absoluted(motor) + + pause() + """ + values = _normalize(values) + for v in values: + yield abs(v) + + +def quantized(values, steps, input_min=0, input_max=1): + """ + Returns *values* quantized to *steps* increments. All items in *values* are + assumed to be between *input_min* and *input_max* (which default to 0 and + 1 respectively), and the output will be in the same range. + + For example, to quantize values between 0 and 1 to 5 "steps" (0.0, 0.25, + 0.5, 0.75, 1.0):: + + from gpiozero import PWMLED, MCP3008 + from gpiozero.tools import quantized + from signal import pause + + led = PWMLED(4) + pot = MCP3008(channel=0) + + led.source = quantized(pot, 4) + + pause() + """ + values = _normalize(values) + if steps < 1: + raise ValueError("steps must be 1 or larger") + if input_min >= input_max: + raise ValueError('input_min must be smaller than input_max') + input_size = input_max - input_min + for v in scaled(values, 0, 1, input_min, input_max): + yield ((int(v * steps) / steps) * input_size) + input_min + + +def booleanized(values, min_value, max_value, hysteresis=0): + """ + Returns True for each item in *values* between *min_value* and + *max_value*, and False otherwise. *hysteresis* can optionally be used to + add `hysteresis`_ which prevents the output value rapidly flipping when + the input value is fluctuating near the *min_value* or *max_value* + thresholds. For example, to light an LED only when a potentiometer is + between ¼ and ¾ of its full range:: + + from gpiozero import LED, MCP3008 + from gpiozero.tools import booleanized + from signal import pause + + led = LED(4) + pot = MCP3008(channel=0) + + led.source = booleanized(pot, 0.25, 0.75) + + pause() + + .. _hysteresis: https://en.wikipedia.org/wiki/Hysteresis + """ + values = _normalize(values) + if min_value >= max_value: + raise ValueError('min_value must be smaller than max_value') + min_value = float(min_value) + max_value = float(max_value) + if hysteresis < 0: + raise ValueError("hysteresis must be 0 or larger") + else: + hysteresis = float(hysteresis) + if (max_value - min_value) <= hysteresis: + raise ValueError('The gap between min_value and max_value must be ' + 'larger than hysteresis') + last_state = None + for v in values: + if v < min_value: + new_state = 'below' + elif v > max_value: + new_state = 'above' + else: + new_state = 'in' + switch = False + if last_state == None or not hysteresis: + switch = True + elif new_state == last_state: + pass + else: # new_state != last_state + if last_state == 'below' and new_state == 'in': + switch = v >= min_value + hysteresis + elif last_state == 'in' and new_state == 'below': + switch = v < min_value - hysteresis + elif last_state == 'in' and new_state == 'above': + switch = v > max_value + hysteresis + elif last_state == 'above' and new_state == 'in': + switch = v <= max_value - hysteresis + else: # above->below or below->above + switch = True + if switch: + last_state = new_state + yield last_state == 'in' + + +def all_values(*values): + """ + Returns the `logical conjunction`_ of all supplied values (the result is + only :data:`True` if and only if all input values are simultaneously + :data:`True`). One or more *values* can be specified. For example, to light + an :class:`~gpiozero.LED` only when *both* buttons are pressed:: + + from gpiozero import LED, Button + from gpiozero.tools import all_values + from signal import pause + + led = LED(4) + btn1 = Button(20) + btn2 = Button(21) + + led.source = all_values(btn1, btn2) + + pause() + + .. _logical conjunction: https://en.wikipedia.org/wiki/Logical_conjunction + """ + values = [_normalize(v) for v in values] + for v in zip(*values): + yield all(v) + + +def any_values(*values): + """ + Returns the `logical disjunction`_ of all supplied values (the result is + :data:`True` if any of the input values are currently :data:`True`). One or + more *values* can be specified. For example, to light an + :class:`~gpiozero.LED` when *any* button is pressed:: + + from gpiozero import LED, Button + from gpiozero.tools import any_values + from signal import pause + + led = LED(4) + btn1 = Button(20) + btn2 = Button(21) + + led.source = any_values(btn1, btn2) + + pause() + + .. _logical disjunction: https://en.wikipedia.org/wiki/Logical_disjunction + """ + values = [_normalize(v) for v in values] + for v in zip(*values): + yield any(v) + + +def averaged(*values): + """ + Returns the mean of all supplied values. One or more *values* can be + specified. For example, to light a :class:`~gpiozero.PWMLED` as the average + of several potentiometers connected to an :class:`~gpiozero.MCP3008` ADC:: + + from gpiozero import MCP3008, PWMLED + from gpiozero.tools import averaged + from signal import pause + + pot1 = MCP3008(channel=0) + pot2 = MCP3008(channel=1) + pot3 = MCP3008(channel=2) + led = PWMLED(4) + + led.source = averaged(pot1, pot2, pot3) + + pause() + """ + values = [_normalize(v) for v in values] + for v in zip(*values): + yield mean(v) + + +def summed(*values): + """ + Returns the sum of all supplied values. One or more *values* can be + specified. For example, to light a :class:`~gpiozero.PWMLED` as the + (scaled) sum of several potentiometers connected to an + :class:`~gpiozero.MCP3008` ADC:: + + from gpiozero import MCP3008, PWMLED + from gpiozero.tools import summed, scaled + from signal import pause + + pot1 = MCP3008(channel=0) + pot2 = MCP3008(channel=1) + pot3 = MCP3008(channel=2) + led = PWMLED(4) + + led.source = scaled(summed(pot1, pot2, pot3), 0, 1, 0, 3) + + pause() + """ + values = [_normalize(v) for v in values] + for v in zip(*values): + yield sum(v) + + +def multiplied(*values): + """ + Returns the product of all supplied values. One or more *values* can be + specified. For example, to light a :class:`~gpiozero.PWMLED` as the product + (i.e. multiplication) of several potentiometers connected to an + :class:`~gpiozero.MCP3008` + ADC:: + + from gpiozero import MCP3008, PWMLED + from gpiozero.tools import multiplied + from signal import pause + + pot1 = MCP3008(channel=0) + pot2 = MCP3008(channel=1) + pot3 = MCP3008(channel=2) + led = PWMLED(4) + + led.source = multiplied(pot1, pot2, pot3) + + pause() + """ + values = [_normalize(v) for v in values] + def _product(it): + p = 1 + for n in it: + p *= n + return p + for v in zip(*values): + yield _product(v) + + +def queued(values, qsize): + """ + Queues up readings from *values* (the number of readings queued is + determined by *qsize*) and begins yielding values only when the queue is + full. For example, to "cascade" values along a sequence of LEDs:: + + from gpiozero import LEDBoard, Button + from gpiozero.tools import queued + from signal import pause + + leds = LEDBoard(5, 6, 13, 19, 26) + btn = Button(17) + + for i in range(4): + leds[i].source = queued(leds[i + 1], 5) + leds[i].source_delay = 0.01 + + leds[4].source = btn + + pause() + """ + values = [_normalize(v) for v in values] + if qsize < 1: + raise ValueError("qsize must be 1 or larger") + q = [] + it = iter(values) + try: + for i in range(qsize): + q.append(next(it)) + for i in cycle(range(qsize)): + yield q[i] + q[i] = next(it) + except StopIteration: + pass + + +def smoothed(values, qsize, average=mean): + """ + Queues up readings from *values* (the number of readings queued is + determined by *qsize*) and begins yielding the *average* of the last + *qsize* values when the queue is full. The larger the *qsize*, the more the + values are smoothed. For example, to smooth the analog values read from an + ADC:: + + from gpiozero import MCP3008 + from gpiozero.tools import smoothed + + adc = MCP3008(channel=0) + + for value in smoothed(adc, 5): + print(value) + """ + values = _normalize(values) + if qsize < 1: + raise ValueError("qsize must be 1 or larger") + q = [] + it = iter(values) + try: + for i in range(qsize): + q.append(next(it)) + for i in cycle(range(qsize)): + yield average(q) + q[i] = next(it) + except StopIteration: + pass + + +def pre_delayed(values, delay): + """ + Waits for *delay* seconds before returning each item from *values*. + """ + values = _normalize(values) + if delay < 0: + raise ValueError("delay must be 0 or larger") + for v in values: + sleep(delay) + yield v + + +def post_delayed(values, delay): + """ + Waits for *delay* seconds after returning each item from *values*. + """ + values = _normalize(values) + if delay < 0: + raise ValueError("delay must be 0 or larger") + for v in values: + yield v + sleep(delay) + + +def pre_periodic_filtered(values, block, repeat_after): + """ + Blocks the first *block* items from *values*, repeating the block after + every *repeat_after* items, if *repeat_after* is non-zero. For example, to + discard the first 50 values read from an ADC:: + + from gpiozero import MCP3008 + from gpiozero.tools import pre_periodic_filtered + + adc = MCP3008(channel=0) + + for value in pre_periodic_filtered(adc, 50, 0): + print(value) + + Or to only display every even item read from an ADC:: + + from gpiozero import MCP3008 + from gpiozero.tools import pre_periodic_filtered + + adc = MCP3008(channel=0) + + for value in pre_periodic_filtered(adc, 1, 1): + print(value) + """ + values = _normalize(values) + if block < 1: + raise ValueError("block must be 1 or larger") + if repeat_after < 0: + raise ValueError("repeat_after must be 0 or larger") + it = iter(values) + try: + if repeat_after == 0: + for _ in range(block): + next(it) + while True: + yield next(it) + else: + while True: + for _ in range(block): + next(it) + for _ in range(repeat_after): + yield next(it) + except StopIteration: + pass + + +def post_periodic_filtered(values, repeat_after, block): + """ + After every *repeat_after* items, blocks the next *block* items from + *values*. Note that unlike :func:`pre_periodic_filtered`, *repeat_after* + can't be 0. For example, to block every tenth item read from an ADC:: + + from gpiozero import MCP3008 + from gpiozero.tools import post_periodic_filtered + + adc = MCP3008(channel=0) + + for value in post_periodic_filtered(adc, 9, 1): + print(value) + """ + values = _normalize(values) + if repeat_after < 1: + raise ValueError("repeat_after must be 1 or larger") + if block < 1: + raise ValueError("block must be 1 or larger") + it = iter(values) + try: + while True: + for _ in range(repeat_after): + yield next(it) + for _ in range(block): + next(it) + except StopIteration: + pass + + +def random_values(): + """ + Provides an infinite source of random values between 0 and 1. For example, + to produce a "flickering candle" effect with an LED:: + + from gpiozero import PWMLED + from gpiozero.tools import random_values + from signal import pause + + led = PWMLED(4) + + led.source = random_values() + + pause() + + If you require a wider range than 0 to 1, see :func:`scaled`. + """ + while True: + yield random() + + +def sin_values(period=360): + """ + Provides an infinite source of values representing a sine wave (from -1 to + +1) which repeats every *period* values. For example, to produce a "siren" + effect with a couple of LEDs that repeats once a second:: + + from gpiozero import PWMLED + from gpiozero.tools import sin_values, scaled_half, inverted + from signal import pause + + red = PWMLED(2) + blue = PWMLED(3) + + red.source_delay = 0.01 + blue.source_delay = red.source_delay + red.source = scaled_half(sin_values(100)) + blue.source = inverted(red) + + pause() + + If you require a different range than -1 to +1, see :func:`scaled`. + """ + angles = (2 * pi * i / period for i in range(period)) + for a in cycle(angles): + yield sin(a) + + +def cos_values(period=360): + """ + Provides an infinite source of values representing a cosine wave (from -1 + to +1) which repeats every *period* values. For example, to produce a + "siren" effect with a couple of LEDs that repeats once a second:: + + from gpiozero import PWMLED + from gpiozero.tools import cos_values, scaled_half, inverted + from signal import pause + + red = PWMLED(2) + blue = PWMLED(3) + + red.source_delay = 0.01 + blue.source_delay = red.source_delay + red.source = scaled_half(cos_values(100)) + blue.source = inverted(red) + + pause() + + If you require a different range than -1 to +1, see :func:`scaled`. + """ + angles = (2 * pi * i / period for i in range(period)) + for a in cycle(angles): + yield cos(a) + + +def alternating_values(initial_value=False): + """ + Provides an infinite source of values alternating between :data:`True` and + :data:`False`, starting wth *initial_value* (which defaults to + :data:`False`). For example, to produce a flashing LED:: + + from gpiozero import LED + from gpiozero.tools import alternating_values + from signal import pause + + red = LED(2) + + red.source_delay = 0.5 + red.source = alternating_values() + + pause() + """ + value = initial_value + while True: + yield value + value = not value + + +def ramping_values(period=360): + """ + Provides an infinite source of values representing a triangle wave (from 0 + to 1 and back again) which repeats every *period* values. For example, to + pulse an LED once a second:: + + from gpiozero import PWMLED + from gpiozero.tools import ramping_values + from signal import pause + + red = PWMLED(2) + + red.source_delay = 0.01 + red.source = ramping_values(100) + + pause() + + If you require a wider range than 0 to 1, see :func:`scaled`. + """ + step = 2 / period + value = 0 + while True: + yield value + value += step + if isclose(value, 1, abs_tol=1e-9): + value = 1 + step *= -1 + elif isclose(value, 0, abs_tol=1e-9): + value = 0 + step *= -1 + elif value > 1 or value < 0: + step *= -1 + value += step + + +def zip_values(*devices): + """ + Provides a source constructed from the values of each item, for example:: + + from gpiozero import MCP3008, Robot + from gpiozero.tools import zip_values + from signal import pause + + robot = Robot(left=(4, 14), right=(17, 18)) + + left = MCP3008(0) + right = MCP3008(1) + + robot.source = zip_values(left, right) + + pause() + + ``zip_values(left, right)`` is equivalent to ``zip(left.values, + right.values)``. + """ + return zip(*[d.values for d in devices]) diff --git a/.venv/lib/python3.7/site-packages/gpiozerocli/__init__.py b/.venv/lib/python3.7/site-packages/gpiozerocli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0991eda7252ab80a77fedd30926fe2fa9b327d17 GIT binary patch literal 145 zcmZ?b<>g`k0 K1DW|5h#3IN1S2{C literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/pinout.cpython-37.pyc b/.venv/lib/python3.7/site-packages/gpiozerocli/__pycache__/pinout.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..126e4452df654c2690dc863a3e98e62aefb7cd20 GIT binary patch literal 2924 zcmZ`*O>f)C873)8qG(xm9Iw0S$L?%_HmksruSJk<<8HGH1BGqaDR#pPL32hn6@Fzn zj4iIyL!2IS>7gikvTyCBKcYWlj_qmxLND#}l2WXss00p&@4O!~@5l4buUA)H1HY}~ zzw-YK4C7z)vH01TJjPQ@F>u2(xXG>9Of1hzT3#!$Jv(W8ZIkG&xZ`!|ch~FIZ^v`$ zchBq9Z`X72w&Rtg@AXaNYlF9W=Z(QTV)d%!4aDHe@YZL!3X1$hNI7GN5&QaZ?||h|I?77Lq7;ltprR}tyWeBO#?aR5Wg3MU7d|uz z8N`KN3r>nGE|u`3B+sPMgIq?b@+V~)lB{-k^fD?i+aH>`n@2t=4oTnQ*TUp6p5o^i zgyETRjfJCGZw#-+9d7gX8`HCShj&3~*GKAU_b^Ja&!<@yhb9E+NAE74FY(k)R>ss+ z(Dl~5H2l`3F>Ot4Zt)iBBz^arpJ??UYukij7b(IhJ8eivk_{I|TF5l!IfqSc= zasy8O0iAD!iz1X!PA9Ldk*wU&NQ&nC+IcrKs@)^_d+|MHzY&w5jN$Zxsf-1sf{&F5 z)jJlJO;}h;DN@Ba6oz8h(l)Fq-Q|t2w$DVI!)jP{N24%{GpXG|Wm5P`mZEy|RVG8h z>IK0We3v84pP$U2u(rO<)R|b&&!ad-4uo;Z1>4;}-mB#x4Vx^QFj=NpWFW(dc4U=@y3S!9gxkN_BW)3<4d64nOw3Dg zY~|m-*ilKolSla|N(&Xl@#uvpPI%&1JEwV+RYGR(CSe?bv)*4m(~gg_iIneu3O&U( z2E(*X*Xm%j@ON%!t^cJ}cW-NDywJ2CTBHU)sy_m)x@!K6$t5cAxg)ozdQgYPAFO-E zD|5DWXVoHwbDp2RuIui)hO}v~u0i+G;`UqX20A{FhK{<%+WX&AiAx%)d*9_UJAL(#0lqT% zkbRekq6kjKD|cvVo7Qx9P8zQ0RxvBIjmW&zb`nIX+=346)?uT774j|-Ru=(&LP~Y- z$wesYYSy;6h?MR$peTO=W~AB2Btu#YZHhX`&G18_BWNLl?EAmOSFwq~FdcJ%aBZ0z ztxa>?w5-1QL2w$0_hREfu#U|?F;T`fVsc{wx6G*}f2{l<9lcf_EF7+jhF${P3F>y;bC=+e6G^LDM1W*wTT)#>1R4J+$627Nzk zx&-4o$g^SMUWg;dg0+JQ<2OQc(~`m1tU-hk_cjr)NObvM3RX8B0Wv z0%Okt#b#N_0x4LU0cOiIrFQtU&na()1(ES3}j95&f7@bCLAP2My zu%2VJwlmfj#6}YO@_Z;X0&;z}dxKNUCR(A@; zVMVvkC9XSqrD61`&Fb#nK?4!Qgf21%19_hWd+$_!fC=(5EdLfy@c@Hix@O1hTP`4B z6TsjC%{vYrfWyFCw>BF}3m~z!gx~~ULvw%FA%sbTM4b zY&_ +# Copyright (c) 2017 Ben Nuttall +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +A utility for querying Raspberry Pi GPIO pin-out information. +""" + +from __future__ import ( + unicode_literals, + absolute_import, + print_function, + division, +) + +import argparse +import sys +import textwrap +import warnings +import webbrowser + +from gpiozero import pi_info + + +class PinoutTool(object): + def __init__(self): + self.parser = argparse.ArgumentParser( + description=__doc__ + ) + self.parser.add_argument( + '-r', '--revision', + dest='revision', + default='', + help='RPi revision. Default is to autodetect revision of current device' + ) + self.parser.add_argument( + '-c', '--color', + action="store_true", + default=None, + help='Force colored output (by default, the output will include ANSI' + 'color codes if run in a color-capable terminal). See also --monochrome' + ) + self.parser.add_argument( + '-m', '--monochrome', + dest='color', + action='store_false', + help='Force monochrome output. See also --color' + ) + self.parser.add_argument( + '-x', '--xyz', + dest='xyz', + action='store_true', + help='Open pinout.xyz in the default web browser' + ) + + def __call__(self, args=None): + if args is None: + args = sys.argv[1:] + try: + return self.main(self.parser.parse_args(args)) or 0 + except argparse.ArgumentError as e: + # argparse errors are already nicely formatted, print to stderr and + # exit with code 2 + raise e + except Exception as e: + raise + # Output anything else nicely formatted on stderr and exit code 1 + self.parser.exit(1, '{prog}: error: {message}\n'.format( + prog=self.parser.prog, message=e)) + + def main(self, args): + warnings.simplefilter('ignore') + if args.xyz: + webbrowser.open('https://pinout.xyz') + else: + if args.revision == '': + try: + pi_info().pprint(color=args.color) + except ImportError: + formatter = self.parser._get_formatter() + formatter.add_text( + "Unable to initialize GPIO Zero. This usually means " + "that you are not running %(prog)s on a Raspberry Pi. " + "If you still wish to run %(prog)s, set the " + "GPIOZERO_PIN_FACTORY environment variable to 'mock' " + "and retry, or refer to the Remote GPIO section of " + "the manual* to configure your environment to " + "remotely access your Pi." + ) + formatter.add_text( + "* https://gpiozero.readthedocs.io/en/stable/" + "remote_gpio.html" + ) + sys.stderr.write(formatter.format_help()) + except IOError: + raise IOError('This device is not a Raspberry Pi') + else: + pi_info(args.revision).pprint(color=args.color) + formatter = self.parser._get_formatter() + formatter.add_text( + "For further information, please refer to " + "https://pinout.xyz/" + ) + sys.stdout.write('\n') + sys.stdout.write(formatter.format_help()) + + +main = PinoutTool() diff --git a/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/LICENSE.md b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/LICENSE.md new file mode 100644 index 0000000..b6f8732 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/LICENSE.md @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2013-2021, Kim Davies +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/METADATA b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/METADATA new file mode 100644 index 0000000..07f6193 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/METADATA @@ -0,0 +1,242 @@ +Metadata-Version: 2.1 +Name: idna +Version: 3.4 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.5 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna + +Internationalized Domain Names in Applications (IDNA) +===================================================== + +Support for the Internationalized Domain Names in +Applications (IDNA) protocol as specified in `RFC 5891 +`_. This is the latest version of +the protocol and is sometimes referred to as “IDNA 2008â€. + +This library also provides support for Unicode Technical +Standard 46, `Unicode IDNA Compatibility Processing +`_. + +This acts as a suitable replacement for the “encodings.idna†+module that comes with the Python standard library, but which +only supports the older superseded IDNA specification (`RFC 3490 +`_). + +Basic functions are simply executed: + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ăƒ‰ăƒ¡ă‚¤ăƒ³.ăƒ†ă‚¹ăƒˆ') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ăƒ‰ăƒ¡ă‚¤ăƒ³.ăƒ†ă‚¹ăƒˆ + + +Installation +------------ + +This package is available for installation from PyPI: + +.. code-block:: bash + + $ python3 -m pip install idna + + +Usage +----- + +For typical usage, the ``encode`` and ``decode`` functions will take a +domain name argument and perform a conversion to A-labels or U-labels +respectively. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ăƒ‰ăƒ¡ă‚¤ăƒ³.ăƒ†ă‚¹ăƒˆ') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ăƒ‰ăƒ¡ă‚¤ăƒ³.ăƒ†ă‚¹ăƒˆ + +You may use the codec encoding and decoding methods using the +``idna.codec`` module: + +.. code-block:: pycon + + >>> import idna.codec + >>> print('Đ´Đ¾Đ¼ĐµĐ½.иÑĐ¿Ñ‹Ñ‚Đ°Đ½Đ¸Đµ'.encode('idna')) + b'xn--d1acufc.xn--80akhbyknj4f' + >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna')) + Đ´Đ¾Đ¼ĐµĐ½.иÑĐ¿Ñ‹Ñ‚Đ°Đ½Đ¸Đµ + +Conversions can be applied at a per-label basis using the ``ulabel`` or +``alabel`` functions if necessary: + +.. code-block:: pycon + + >>> idna.alabel('测试') + b'xn--0zwm56d' + +Compatibility Mapping (UTS #46) ++++++++++++++++++++++++++++++++ + +As described in `RFC 5895 `_, the +IDNA specification does not normalize input from different potential +ways a user may input a domain name. This functionality, known as +a “mappingâ€, is considered by the specification to be a local +user-interface issue distinct from IDNA conversion functionality. + +This library provides one such mapping, that was developed by the +Unicode Consortium. Known as `Unicode IDNA Compatibility Processing +`_, it provides for both a regular +mapping for typical applications, as well as a transitional mapping to +help migrate from older IDNA 2003 applications. + +For example, “KönigsgĂ¤ĂŸchen†is not a permissible label as *LATIN +CAPITAL LETTER K* is not allowed (nor are capital letters in general). +UTS 46 will convert this into lower case prior to applying the IDNA +conversion. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('KönigsgĂ¤ĂŸchen') + ... + idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'KönigsgĂ¤ĂŸchen' not allowed + >>> idna.encode('KönigsgĂ¤ĂŸchen', uts46=True) + b'xn--knigsgchen-b4a3dun' + >>> print(idna.decode('xn--knigsgchen-b4a3dun')) + königsgĂ¤ĂŸchen + +Transitional processing provides conversions to help transition from +the older 2003 standard to the current standard. For example, in the +original IDNA specification, the *LATIN SMALL LETTER SHARP S* (ĂŸ) was +converted into two *LATIN SMALL LETTER S* (ss), whereas in the current +IDNA specification this conversion is not performed. + +.. code-block:: pycon + + >>> idna.encode('KönigsgĂ¤ĂŸchen', uts46=True, transitional=True) + 'xn--knigsgsschen-lcb0w' + +Implementors should use transitional processing with caution, only in +rare cases where conversion from legacy labels to current labels must be +performed (i.e. IDNA implementations that pre-date 2008). For typical +applications that just need to convert labels, transitional processing +is unlikely to be beneficial and could produce unexpected incompatible +results. + +``encodings.idna`` Compatibility +++++++++++++++++++++++++++++++++ + +Function calls from the Python built-in ``encodings.idna`` module are +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module. +Simply substitute the ``import`` clause in your code to refer to the new +module name. + +Exceptions +---------- + +All errors raised during the conversion following the specification +should raise an exception derived from the ``idna.IDNAError`` base +class. + +More specific exceptions that may be generated as ``idna.IDNABidiError`` +when the error reflects an illegal combination of left-to-right and +right-to-left characters in a label; ``idna.InvalidCodepoint`` when +a specific codepoint is an illegal character in an IDN label (i.e. +INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is +illegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ +but the contextual requirements are not satisfied.) + +Building and Diagnostics +------------------------ + +The IDNA and UTS 46 functionality relies upon pre-calculated lookup +tables for performance. These tables are derived from computing against +eligibility criteria in the respective standards. These tables are +computed using the command-line script ``tools/idna-data``. + +This tool will fetch relevant codepoint data from the Unicode repository +and perform the required calculations to identify eligibility. There are +three main modes: + +* ``idna-data make-libdata``. Generates ``idnadata.py`` and + ``uts46data.py``, the pre-calculated lookup tables using for IDNA and + UTS 46 conversions. Implementors who wish to track this library against + a different Unicode version may use this tool to manually generate a + different version of the ``idnadata.py`` and ``uts46data.py`` files. + +* ``idna-data make-table``. Generate a table of the IDNA disposition + (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix + B.1 of RFC 5892 and the pre-computed tables published by `IANA + `_. + +* ``idna-data U+0061``. Prints debugging output on the various + properties associated with an individual Unicode codepoint (in this + case, U+0061), that are used to assess the IDNA and UTS 46 status of a + codepoint. This is helpful in debugging or analysis. + +The tool accepts a number of arguments, described using ``idna-data +-h``. Most notably, the ``--version`` argument allows the specification +of the version of Unicode to use in computing the table data. For +example, ``idna-data --version 9.0.0 make-libdata`` will generate +library data against Unicode 9.0.0. + + +Additional Notes +---------------- + +* **Packages**. The latest tagged release version is published in the + `Python Package Index `_. + +* **Version support**. This library supports Python 3.5 and higher. + As this library serves as a low-level toolkit for a variety of + applications, many of which strive for broad compatibility with older + Python versions, there is no rush to remove older intepreter support. + Removing support for older versions should be well justified in that the + maintenance burden has become too high. + +* **Python 2**. Python 2 is supported by version 2.x of this library. + While active development of the version 2.x series has ended, notable + issues being corrected may be backported to 2.x. Use "idna<3" in your + requirements file if you need this library for a Python 2 application. + +* **Testing**. The library has a test suite based on each rule of the + IDNA specification, as well as tests that are provided as part of the + Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing + `_. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the technical standard IDNA 2008 and emoji domains are broadly phased + out across the domain industry due to associated security risks. For + now, applications that wish need to support these non-compliant labels + may wish to consider trying the encode/decode operation in this library + first, and then falling back to using `encodings.idna`. See `the Github + project `_ for more discussion. + diff --git a/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/RECORD b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/RECORD new file mode 100644 index 0000000..16483ff --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/RECORD @@ -0,0 +1,22 @@ +idna-3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-3.4.dist-info/LICENSE.md,sha256=otbk2UC9JNvnuWRc3hmpeSzFHbeuDVrNMBrIYMqj6DY,1523 +idna-3.4.dist-info/METADATA,sha256=8aLSf9MFS7oB26pZh2hprg7eJp0UJSc-3rpf_evp4DA,9830 +idna-3.4.dist-info/RECORD,, +idna-3.4.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81 +idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849 +idna/__pycache__/__init__.cpython-37.pyc,, +idna/__pycache__/codec.cpython-37.pyc,, +idna/__pycache__/compat.cpython-37.pyc,, +idna/__pycache__/core.cpython-37.pyc,, +idna/__pycache__/idnadata.cpython-37.pyc,, +idna/__pycache__/intranges.cpython-37.pyc,, +idna/__pycache__/package_data.cpython-37.pyc,, +idna/__pycache__/uts46data.cpython-37.pyc,, +idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374 +idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321 +idna/core.py,sha256=1JxchwKzkxBSn7R_oCE12oBu3eVux0VzdxolmIad24M,12950 +idna/idnadata.py,sha256=xUjqKqiJV8Ho_XzBpAtv5JFoVPSupK-SUXvtjygUHqw,44375 +idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881 +idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21 +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539 diff --git a/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/WHEEL new file mode 100644 index 0000000..668ba4d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna-3.4.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.7.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.7/site-packages/idna/__init__.py b/.venv/lib/python3.7/site-packages/idna/__init__.py new file mode 100644 index 0000000..a40eeaf --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/__init__.py @@ -0,0 +1,44 @@ +from .package_data import __version__ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .intranges import intranges_contain + +__all__ = [ + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18b7136f74985f42446756bd9a13330d5181c35c GIT binary patch literal 861 zcmbu7y^_-~5XbF&IB{&}!}+@54Z_TkhM{5@xP#)F8<^|VXcVtVM7*+3c5XNxglB+P zQcJ}vP@%Pf;tD8`$3N}b8}5ymXWge5p;W1O%FPT3S^Y=$XIan9zr zV2dVRH(%n4t(@J1J_Im;A%rl32x3TJ3=^2b3{sfG0+z7a&)FK*H{Ry#yYGtI_%`DF zPMS&;n)6L+ldIR)uPzj*H^vmkhUB*9^h)1}T)|}lvMiLY?fRi|S?F4RtZg82v6HzS zWe1rZ`Oby2lh!`mmj|hNakQ&eP+HYWz1l jT5wL6$@!D=-VUE*0jFHPpf;->JH-CmMcnQ9|9*Y~SJ&KO literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/codec.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/codec.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcbbf795700a40b9be87b312edffcb8250f5bda9 GIT binary patch literal 3220 zcmeHJ&2Jnv6d%ucK6bOaO*d&vp|nZ)oYHO(2g-p~rA>u;StJTn8dOG;wKq(dnccpb z6(r0`sOc5{f*z6^+&OT7f5g|Gdg_527kJN;-A&RUS_z2@9{Jh++2dzF|K78&H=A_> z)5`51MW<;PkEk(8Hdd}-&VNB648am3WdTdgz)Y>cN_oIjJFuA{OkpKX;ONo~Tr7Fw zrL~}z)`L1Tq`NaG>|GW#J~V_Q+y{nmrL)o8wt^-io~R*GL!^bsF+}QO4v{%T<`FrL zNJBIcY04&I?QI^k5o?KKh#k||0%8l;w9;YqwUrAKU~Oz+?Qu==!FzKN$@Zsl1PdMLfu&WYoZp&pVI4yZ_|Z zAD;ZSd$&g;C&|IeHO%=c3TXsP7=bA~Y2nAEEuFr38g2E^5|-c(Y_wAiQR=hy_1VI~ zK2Nx~_PVlf;F5dF$qR^kg>NY?q9Ve*&^mMFfGkFk^(@p#iAs+72IjnjqBI5j%7T*x zD&AqGxy!cMeO9vkEE%UTOKcYw$-apSc^BsJudQ>RX8CA196%w(lGe5KWt52|&eoUC ze>*!+3Zp z&hjEkl1ukwz9!OeYb6$0R0%qyUT3(eCnT2UnySoWEt4~DZZ))RI@PiM2PRMl_7C&4 zOF95Jj>5N~P4(&C_0B7?I2lRC_?ul-B<=c4AIPMrDK8AOD3xKT>S34;#3-S9BMk42 zqGYefLbia1b1Qpovyi#6;;cHCYJH^k@N&qu^h-|k@ys(dAf$(Rnx_1I6QK#er|h0^ zm_6ha2hjgq!I4t7YTwFwAXAy)N#E2y2*{bKVU*pE(YK(5v-U_kB~niDM-%yHto##^ zcaX%pY|I58+a-t3N-pfv=!(Ljwy>`lS-Z4yjbAZn1of;NV~j^*_nUW0zG~dPF!oAk zhZlC~ZR2drC|$T;y286`jNQ^L9Kxx7Pu#&sw&Rx0E-UR*#<-???W(uLmUgGwGrJR< zz&&br(zVBbVp6PAAv%D0+RHS{)O1`lW)^>6jSn1QlRg~TR3qQ9P1Sr60>IXAtI|*xHjtdC4`kD z(#-kWD2%D6)*1RMwsbZfYLN%CI%{cc-fFQ1+gg5_C!K?HcYO~|;>>W0#0w-&qfmTp zFi14x;UxkukeDq~*R<1}!4Aqf1u2gK)&F&luj>2d0LOu>@;}4(F&xg4Mb43+O9T#c z9F_=OCUKqw1q01!cm-=m6B=HnL9dZ`ox~d?C|H3{Vn&FAysbj*RUGoXyfvTV?cUi> zc{>T?NAeclqGeIkt!R7c;3{Xdy@(xGFi&Vp?E|zW>s_M(6jdjoSuhO0rfS?SKt|~u zhzki_yq6An(9A3|h4ggzg67-v6KX%N!jEMno>}1vDp=d6klJ|Z={o_d(^SLS4b1rx zio)1nf)(brv0-V6k-KmTxA27dJ-wf-uHy8d@Lk2}Zq!c+eFv&`JiC;tzy$}e>fk^% zFyf*0zSh>8v=G6q`8DO}M@p`0`YCcN!zU2kTr)j7!T_BYkPU(MwU3BXi>tYHiHg?o zl7!7Z4$A2{VPKdvnS-CHKX?x@|D@u*0qomM74Ef%&>ao$qEIH@3Qn;(#IRmbj7+E8 z-XI;uiG(E@NNZIuUf1DUil@V`Uj2~+_IQ4HXP0SKTI7*?^xm%?ELVxHIXU4OycIk) QZ`RHBVtcv0yvP^%UjU@0k^lez literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/compat.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8afeb5b589382b25a2fc562da33425797f146a2 GIT binary patch literal 700 zcma)3y^a$x5VrR(yU7JbqT#x27ZGxzqCn`vL6K&ggeF2lo1Foz~G2{SD5EVlpm??I#kzfD5)cYEC+W zSVVoijr(MqaE2*nko<}uh3sdt9btkQ=3k<7${gY&$SGc63YNGwAk4wxK#u&=K(!vCT<1_MP2u>d0&AmZ5AF zV8u;Fxj)Plr0(Vm*XxDu^t_YSHA2k4q1{3M`FhcTY>uK;y>8q~J^0Z^E!S78RT^f5 zVT_vz$^Tvg@WB#?6^gyM) z_w}-Tb#d{!1ckPg%9VT9iOymvn;x}6U23D8YL%c1J*|~n^;%$$(jj~>Mj1NS6KehM zrupf80DoF^Ms_vvNvjO{G{9(m<_6u#uO5W17JPs3x>| eFfV+QIh-ed(<|5ud>ek+hEUFPK8t4Yv-lp{sFl0` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/core.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e253dfdf6c468b47b72f624cdc8c17acbe66a24f GIT binary patch literal 9871 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/idnadata.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/idnadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8459a23ffec6b5219d5036272e6f2c44f87474e5 GIT binary patch literal 23263 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/intranges.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/intranges.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a851eb1a89a9001a85c00770a885603d59fd862c GIT binary patch literal 1931 zcmZuy&u~C6} zv=EaA==HA{6x(8oE0Oapj&G2QBG?Lwa4Y0Y2Rd3|I@FO0$6|%4=&evaHTPS%)zcCE zRR3+D&Zq$-b67)DM_zLtnhR-%gi`E(Y9WbMXI!%RwP{AEh{~q=J`Pk)w)RYT$*XIqb=>`rI|=OHT3|CQE6&D znmV}s#Mh`Ss;Sd3wz{&q*2bkSD-D^uT`k9@Ee5NrwM(tLy(YC$x8pV0t?&5tomdWs z!+0p4?^3*`eu=}$bbqRA@9O%?w3e^rvHL-0{B~)xNoLaAU-15Q#3Wr-X!*lxUQSkT z__*VEI5+|(Y%>;Z_yn0~qvz8q*F&r$%1qMstaejtM#!0OJ&XXDeTQEEfx)qc9r78U zu$fSN7QC{KJJIk%{2sAic4lD{Dsh>0vOQ*>G`tB{7>y(c%wn1C3HxOK8e{>`=Vt9D1{0|JsktLFfNS_&L z!oj9yqU&!5673j@pdAsImWH_3_Uh6)t=h=vp$&3v+Fn{!aM3O%ND_`ry1mGI zihGtSx}EO~6XFSI;=^nQc?#CNw3*W_&)UV&)LM|fbMP0l7hw6%t#wya>s40W%nXu{ z=QsCty`zfc^?IgEdOR4{`5aaU?FFQ?TP0XHk6xT?Rz!1{e2;&+}e@ntUfMShj{ zg}sEGIA|lE<~G26Yy{CrkO>-nse2|bVA9}Wx(8l9WMGomJd%+4fMa3l9DDgh;HCB= zEy+-#*WNAnYg7-n-C>kuYV-}z{b5U(&|&v!6c5;#-lbsEE<>J^)`vGA-UP>IbGrgb zcOqra9}8rZK1JpR)-&S%``Z8@LGA9=DI12o=3)@OYb01#YUmU3e04=SFsS7=UoX?vc|NgGsU-G-!yBFHAYuI0&p^L_4= zfOzR$nwhWRqNAS}@P(ic+AZ@?EP#YWM@yK*^X*)csB)Af_G)+JL50e-L>5a(w*fgO ss`~JKq;0rUmbrKENf@Wt_cw}CO>=#Z-r|}F7>Yh$5?3#s50=A!0cXg`k0{!3>DWX97F^B^Lj6jA15EpX*i4=w?h7`tN22G|aW@9}QKTXD4-0|^c zsYS(^`FZj2D;bKIfU3a6FJt|Z+yecA%mUrayyB9?oE+W4)Z(O+-1sW}%#^%D2vLxj hoSm4S8lRF_lBicud5gm)H$SB`C)EyQ?Pnln006gPCk_Ar literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/idna/__pycache__/uts46data.cpython-37.pyc b/.venv/lib/python3.7/site-packages/idna/__pycache__/uts46data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..390de23a5e0db8bc35953a75bbf341159261b05d GIT binary patch literal 187396 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 ZHVE>RMDtKQXZG-V Tuple[bytes, int]: + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return b"", 0 + + return encode(data), len(data) + + def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]: + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return '', 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return "", 0 + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result_str = '.'.join(result) + trailing_dot # type: ignore + size += len(trailing_dot) + return result_str, size + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return ('', 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = '.'.join(result) + trailing_dot + size += len(trailing_dot) + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def getregentry() -> codecs.CodecInfo: + # Compatibility as a search_function for codecs.register() + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, # type: ignore + decode=Codec().decode, # type: ignore + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/.venv/lib/python3.7/site-packages/idna/compat.py b/.venv/lib/python3.7/site-packages/idna/compat.py new file mode 100644 index 0000000..786e6bd --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/compat.py @@ -0,0 +1,13 @@ +from .core import * +from .codec import * +from typing import Any, Union + +def ToASCII(label: str) -> bytes: + return encode(label) + +def ToUnicode(label: Union[bytes, bytearray]) -> str: + return decode(label) + +def nameprep(s: Any) -> None: + raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol') + diff --git a/.venv/lib/python3.7/site-packages/idna/core.py b/.venv/lib/python3.7/site-packages/idna/core.py new file mode 100644 index 0000000..4f30037 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/core.py @@ -0,0 +1,400 @@ +from . import idnadata +import bisect +import unicodedata +import re +from typing import Union, Optional +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0: + if not unicodedata.name(chr(cp)): + raise ValueError('Unknown character in unicodedata') + return v + +def _is_script(cp: str, script: str) -> bool: + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s: str) -> bytes: + return s.encode('punycode') + +def _unot(s: int) -> str: + return 'U+{:04X}'.format(s) + + +def valid_label_length(label: Union[bytes, str]) -> bool: + if len(label) > 63: + return False + return True + + +def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool: + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label: str, check_ltr: bool = False) -> bool: + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = None # type: Optional[str] + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label: str) -> bool: + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label: str) -> bool: + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label: str) -> None: + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label: str, pos: int) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == '\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + return False + + +def check_label(label: Union[str, bytes, bytearray]) -> None: + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format( + _unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label: str) -> bytes: + try: + label_bytes = label.encode('ascii') + ulabel(label_bytes) + if not valid_label_length(label_bytes): + raise IDNAError('Label too long') + return label_bytes + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = str(label) + check_label(label) + label_bytes = _punycode(label) + label_bytes = _alabel_prefix + label_bytes + + if not valid_label_length(label_bytes): + raise IDNAError('Label too long') + + return label_bytes + + +def ulabel(label: Union[str, bytes, bytearray]) -> str: + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = label + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix):] + if not label_bytes: + raise IDNAError('Malformed A-label, no Punycode eligible content found') + if label_bytes.decode('ascii')[-1] == '-': + raise IDNAError('A-label must not end with a hyphen') + else: + check_label(label_bytes) + return label_bytes.decode('ascii') + + try: + label = label_bytes.decode('punycode') + except UnicodeError: + raise IDNAError('Invalid A-label') + check_label(label) + return label + + +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = '' + + for pos, char in enumerate(domain): + code_point = ord(char) + try: + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, 'Z')) - 1] + status = uts46row[1] + replacement = None # type: Optional[str] + if len(uts46row) == 3: + replacement = uts46row[2] # type: ignore + if (status == 'V' or + (status == 'D' and not transitional) or + (status == '3' and not std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == 'M' or + (status == '3' and not std3_rules) or + (status == 'D' and transitional)): + output += replacement + elif status != 'I': + raise IndexError() + except IndexError: + raise InvalidCodepoint( + 'Codepoint {} not allowed at position {} in {}'.format( + _unot(code_point), pos + 1, repr(domain))) + + return unicodedata.normalize('NFC', output) + + +def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False, transitional: bool = False) -> bytes: + if isinstance(s, (bytes, bytearray)): + try: + s = s.decode('ascii') + except UnicodeDecodeError: + raise IDNAError('should pass a unicode string to the function rather than a byte string.') + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False) -> str: + try: + if isinstance(s, (bytes, bytearray)): + s = s.decode('ascii') + except UnicodeDecodeError: + raise IDNAError('Invalid ASCII in A-label') + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split('.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append('') + return '.'.join(result) diff --git a/.venv/lib/python3.7/site-packages/idna/idnadata.py b/.venv/lib/python3.7/site-packages/idna/idnadata.py new file mode 100644 index 0000000..67db462 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/idnadata.py @@ -0,0 +1,2151 @@ +# This file is automatically generated by tools/idna-data + +__version__ = '15.0.0' +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004dc0, + 0x4e000000a000, + 0xf9000000fa6e, + 0xfa700000fada, + 0x16fe200016fe4, + 0x16ff000016ff2, + 0x200000002a6e0, + 0x2a7000002b73a, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + 0x300000003134b, + 0x31350000323b0, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5ef000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b120, + 0x1b1320001b133, + 0x1b1500001b153, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1aff00001aff4, + 0x1aff50001affc, + 0x1affd0001afff, + 0x1b0000001b001, + 0x1b1200001b123, + 0x1b1550001b156, + 0x1b1640001b168, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x605: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x70f: 84, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 82, + 0x857: 82, + 0x858: 82, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x870: 82, + 0x871: 82, + 0x872: 82, + 0x873: 82, + 0x874: 82, + 0x875: 82, + 0x876: 82, + 0x877: 82, + 0x878: 82, + 0x879: 82, + 0x87a: 82, + 0x87b: 82, + 0x87c: 82, + 0x87d: 82, + 0x87e: 82, + 0x87f: 82, + 0x880: 82, + 0x881: 82, + 0x882: 82, + 0x883: 67, + 0x884: 67, + 0x885: 67, + 0x886: 68, + 0x887: 85, + 0x888: 85, + 0x889: 68, + 0x88a: 68, + 0x88b: 68, + 0x88c: 68, + 0x88d: 68, + 0x88e: 82, + 0x890: 85, + 0x891: 85, + 0x8a0: 68, + 0x8a1: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x8ad: 85, + 0x8ae: 82, + 0x8af: 68, + 0x8b0: 68, + 0x8b1: 82, + 0x8b2: 82, + 0x8b3: 68, + 0x8b4: 68, + 0x8b5: 68, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 68, + 0x8be: 68, + 0x8bf: 68, + 0x8c0: 68, + 0x8c1: 68, + 0x8c2: 68, + 0x8c3: 68, + 0x8c4: 68, + 0x8c5: 68, + 0x8c6: 68, + 0x8c7: 68, + 0x8c8: 68, + 0x8e2: 85, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1878: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x10d00: 76, + 0x10d01: 68, + 0x10d02: 68, + 0x10d03: 68, + 0x10d04: 68, + 0x10d05: 68, + 0x10d06: 68, + 0x10d07: 68, + 0x10d08: 68, + 0x10d09: 68, + 0x10d0a: 68, + 0x10d0b: 68, + 0x10d0c: 68, + 0x10d0d: 68, + 0x10d0e: 68, + 0x10d0f: 68, + 0x10d10: 68, + 0x10d11: 68, + 0x10d12: 68, + 0x10d13: 68, + 0x10d14: 68, + 0x10d15: 68, + 0x10d16: 68, + 0x10d17: 68, + 0x10d18: 68, + 0x10d19: 68, + 0x10d1a: 68, + 0x10d1b: 68, + 0x10d1c: 68, + 0x10d1d: 68, + 0x10d1e: 68, + 0x10d1f: 68, + 0x10d20: 68, + 0x10d21: 68, + 0x10d22: 82, + 0x10d23: 68, + 0x10f30: 68, + 0x10f31: 68, + 0x10f32: 68, + 0x10f33: 82, + 0x10f34: 68, + 0x10f35: 68, + 0x10f36: 68, + 0x10f37: 68, + 0x10f38: 68, + 0x10f39: 68, + 0x10f3a: 68, + 0x10f3b: 68, + 0x10f3c: 68, + 0x10f3d: 68, + 0x10f3e: 68, + 0x10f3f: 68, + 0x10f40: 68, + 0x10f41: 68, + 0x10f42: 68, + 0x10f43: 68, + 0x10f44: 68, + 0x10f45: 85, + 0x10f51: 68, + 0x10f52: 68, + 0x10f53: 68, + 0x10f54: 82, + 0x10f70: 68, + 0x10f71: 68, + 0x10f72: 68, + 0x10f73: 68, + 0x10f74: 82, + 0x10f75: 82, + 0x10f76: 68, + 0x10f77: 68, + 0x10f78: 68, + 0x10f79: 68, + 0x10f7a: 68, + 0x10f7b: 68, + 0x10f7c: 68, + 0x10f7d: 68, + 0x10f7e: 68, + 0x10f7f: 68, + 0x10f80: 68, + 0x10f81: 68, + 0x10fb0: 68, + 0x10fb1: 85, + 0x10fb2: 68, + 0x10fb3: 68, + 0x10fb4: 82, + 0x10fb5: 82, + 0x10fb6: 82, + 0x10fb7: 85, + 0x10fb8: 68, + 0x10fb9: 82, + 0x10fba: 82, + 0x10fbb: 68, + 0x10fbc: 68, + 0x10fbd: 82, + 0x10fbe: 68, + 0x10fbf: 68, + 0x10fc0: 85, + 0x10fc1: 68, + 0x10fc2: 82, + 0x10fc3: 82, + 0x10fc4: 68, + 0x10fc5: 85, + 0x10fc6: 85, + 0x10fc7: 85, + 0x10fc8: 85, + 0x10fc9: 82, + 0x10fca: 68, + 0x10fcb: 76, + 0x110bd: 85, + 0x110cd: 85, + 0x1e900: 68, + 0x1e901: 68, + 0x1e902: 68, + 0x1e903: 68, + 0x1e904: 68, + 0x1e905: 68, + 0x1e906: 68, + 0x1e907: 68, + 0x1e908: 68, + 0x1e909: 68, + 0x1e90a: 68, + 0x1e90b: 68, + 0x1e90c: 68, + 0x1e90d: 68, + 0x1e90e: 68, + 0x1e90f: 68, + 0x1e910: 68, + 0x1e911: 68, + 0x1e912: 68, + 0x1e913: 68, + 0x1e914: 68, + 0x1e915: 68, + 0x1e916: 68, + 0x1e917: 68, + 0x1e918: 68, + 0x1e919: 68, + 0x1e91a: 68, + 0x1e91b: 68, + 0x1e91c: 68, + 0x1e91d: 68, + 0x1e91e: 68, + 0x1e91f: 68, + 0x1e920: 68, + 0x1e921: 68, + 0x1e922: 68, + 0x1e923: 68, + 0x1e924: 68, + 0x1e925: 68, + 0x1e926: 68, + 0x1e927: 68, + 0x1e928: 68, + 0x1e929: 68, + 0x1e92a: 68, + 0x1e92b: 68, + 0x1e92c: 68, + 0x1e92d: 68, + 0x1e92e: 68, + 0x1e92f: 68, + 0x1e930: 68, + 0x1e931: 68, + 0x1e932: 68, + 0x1e933: 68, + 0x1e934: 68, + 0x1e935: 68, + 0x1e936: 68, + 0x1e937: 68, + 0x1e938: 68, + 0x1e939: 68, + 0x1e93a: 68, + 0x1e93b: 68, + 0x1e93c: 68, + 0x1e93d: 68, + 0x1e93e: 68, + 0x1e93f: 68, + 0x1e940: 68, + 0x1e941: 68, + 0x1e942: 68, + 0x1e943: 68, + 0x1e94b: 84, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56000000587, + 0x58800000589, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5ef000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x7fd000007fe, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x87000000888, + 0x8890000088f, + 0x898000008e2, + 0x8e300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0x9fc000009fd, + 0x9fe000009ff, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xaf900000b00, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5500000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3c00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc5d00000c5e, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcdd00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf4, + 0xd0000000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8100000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8600000e8b, + 0xe8c00000ea4, + 0xea500000ea6, + 0xea700000eb3, + 0xeb400000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ecf, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x170000001716, + 0x171f00001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001879, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 0x1abf00001acf, + 0x1b0000001b4d, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfb, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c60, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x310500003130, + 0x31a0000031c0, + 0x31f000003200, + 0x340000004dc0, + 0x4e000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa6990000a69a, + 0xa69b0000a69c, + 0xa69e0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a790, + 0xa7910000a792, + 0xa7930000a796, + 0xa7970000a798, + 0xa7990000a79a, + 0xa79b0000a79c, + 0xa79d0000a79e, + 0xa79f0000a7a0, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7af0000a7b0, + 0xa7b50000a7b6, + 0xa7b70000a7b8, + 0xa7b90000a7ba, + 0xa7bb0000a7bc, + 0xa7bd0000a7be, + 0xa7bf0000a7c0, + 0xa7c10000a7c2, + 0xa7c30000a7c4, + 0xa7c80000a7c9, + 0xa7ca0000a7cb, + 0xa7d10000a7d2, + 0xa7d30000a7d4, + 0xa7d50000a7d6, + 0xa7d70000a7d8, + 0xa7d90000a7da, + 0xa7f20000a7f5, + 0xa7f60000a7f8, + 0xa7fa0000a828, + 0xa82c0000a82d, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab69, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe30, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x102e0000102e1, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x10597000105a2, + 0x105a3000105b2, + 0x105b3000105ba, + 0x105bb000105bd, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010786, + 0x10787000107b1, + 0x107b2000107bb, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a36, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x10d0000010d28, + 0x10d3000010d3a, + 0x10e8000010eaa, + 0x10eab00010ead, + 0x10eb000010eb2, + 0x10efd00010f1d, + 0x10f2700010f28, + 0x10f3000010f51, + 0x10f7000010f86, + 0x10fb000010fc5, + 0x10fe000010ff7, + 0x1100000011047, + 0x1106600011076, + 0x1107f000110bb, + 0x110c2000110c3, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111c9000111cd, + 0x111ce000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133b00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x1145e00011462, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b9, + 0x116c0000116ca, + 0x117000001171b, + 0x1171d0001172c, + 0x117300001173a, + 0x1174000011747, + 0x118000001183b, + 0x118c0000118ea, + 0x118ff00011907, + 0x119090001190a, + 0x1190c00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193b00011944, + 0x119500001195a, + 0x119a0000119a8, + 0x119aa000119d8, + 0x119da000119e2, + 0x119e3000119e5, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a9a, + 0x11a9d00011a9e, + 0x11ab000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x11d6000011d66, + 0x11d6700011d69, + 0x11d6a00011d8f, + 0x11d9000011d92, + 0x11d9300011d99, + 0x11da000011daa, + 0x11ee000011ef7, + 0x11f0000011f11, + 0x11f1200011f3b, + 0x11f3e00011f43, + 0x11f5000011f5a, + 0x11fb000011fb1, + 0x120000001239a, + 0x1248000012544, + 0x12f9000012ff1, + 0x1300000013430, + 0x1344000013456, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16a7000016abf, + 0x16ac000016aca, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16e6000016e80, + 0x16f0000016f4b, + 0x16f4f00016f88, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x16fe300016fe5, + 0x16ff000016ff2, + 0x17000000187f8, + 0x1880000018cd6, + 0x18d0000018d09, + 0x1aff00001aff4, + 0x1aff50001affc, + 0x1affd0001afff, + 0x1b0000001b123, + 0x1b1320001b133, + 0x1b1500001b153, + 0x1b1550001b156, + 0x1b1640001b168, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1cf000001cf2e, + 0x1cf300001cf47, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1df000001df1f, + 0x1df250001df2b, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e0300001e06e, + 0x1e08f0001e090, + 0x1e1000001e12d, + 0x1e1300001e13e, + 0x1e1400001e14a, + 0x1e14e0001e14f, + 0x1e2900001e2af, + 0x1e2c00001e2fa, + 0x1e4d00001e4fa, + 0x1e7e00001e7e7, + 0x1e7e80001e7ec, + 0x1e7ed0001e7ef, + 0x1e7f00001e7ff, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94c, + 0x1e9500001e95a, + 0x200000002a6e0, + 0x2a7000002b73a, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x300000003134b, + 0x31350000323b0, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/.venv/lib/python3.7/site-packages/idna/intranges.py b/.venv/lib/python3.7/site-packages/idna/intranges.py new file mode 100644 index 0000000..6a43b04 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/intranges.py @@ -0,0 +1,54 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect +from typing import List, Tuple + +def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + +def _decode_range(r: int) -> Tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/.venv/lib/python3.7/site-packages/idna/package_data.py b/.venv/lib/python3.7/site-packages/idna/package_data.py new file mode 100644 index 0000000..8501893 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '3.4' + diff --git a/.venv/lib/python3.7/site-packages/idna/py.typed b/.venv/lib/python3.7/site-packages/idna/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/idna/uts46data.py b/.venv/lib/python3.7/site-packages/idna/uts46data.py new file mode 100644 index 0000000..186796c --- /dev/null +++ b/.venv/lib/python3.7/site-packages/idna/uts46data.py @@ -0,0 +1,8600 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +from typing import List, Tuple, Union + + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = '15.0.0' +def _seg_0() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', 'a'), + (0x42, 'M', 'b'), + (0x43, 'M', 'c'), + (0x44, 'M', 'd'), + (0x45, 'M', 'e'), + (0x46, 'M', 'f'), + (0x47, 'M', 'g'), + (0x48, 'M', 'h'), + (0x49, 'M', 'i'), + (0x4A, 'M', 'j'), + (0x4B, 'M', 'k'), + (0x4C, 'M', 'l'), + (0x4D, 'M', 'm'), + (0x4E, 'M', 'n'), + (0x4F, 'M', 'o'), + (0x50, 'M', 'p'), + (0x51, 'M', 'q'), + (0x52, 'M', 'r'), + (0x53, 'M', 's'), + (0x54, 'M', 't'), + (0x55, 'M', 'u'), + (0x56, 'M', 'v'), + (0x57, 'M', 'w'), + (0x58, 'M', 'x'), + (0x59, 'M', 'y'), + (0x5A, 'M', 'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', ' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', ' ̀ˆ'), + (0xA9, 'V'), + (0xAA, 'M', 'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', ' ̀„'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', '2'), + (0xB3, 'M', '3'), + (0xB4, '3', ' ̀'), + (0xB5, 'M', 'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', ' ̀§'), + (0xB9, 'M', '1'), + (0xBA, 'M', 'o'), + (0xBB, 'V'), + (0xBC, 'M', '1â„4'), + (0xBD, 'M', '1â„2'), + (0xBE, 'M', '3â„4'), + (0xBF, 'V'), + (0xC0, 'M', 'Ă '), + (0xC1, 'M', 'Ă¡'), + (0xC2, 'M', 'Ă¢'), + (0xC3, 'M', 'Ă£'), + (0xC4, 'M', 'ä'), + (0xC5, 'M', 'Ă¥'), + (0xC6, 'M', 'æ'), + (0xC7, 'M', 'ç'), + ] + +def _seg_2() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC8, 'M', 'è'), + (0xC9, 'M', 'Ă©'), + (0xCA, 'M', 'Ăª'), + (0xCB, 'M', 'Ă«'), + (0xCC, 'M', 'ì'), + (0xCD, 'M', 'Ă­'), + (0xCE, 'M', 'Ă®'), + (0xCF, 'M', 'Ă¯'), + (0xD0, 'M', 'Ă°'), + (0xD1, 'M', 'ñ'), + (0xD2, 'M', 'Ă²'), + (0xD3, 'M', 'Ă³'), + (0xD4, 'M', 'Ă´'), + (0xD5, 'M', 'õ'), + (0xD6, 'M', 'ö'), + (0xD7, 'V'), + (0xD8, 'M', 'ø'), + (0xD9, 'M', 'Ă¹'), + (0xDA, 'M', 'Ăº'), + (0xDB, 'M', 'Ă»'), + (0xDC, 'M', 'Ă¼'), + (0xDD, 'M', 'Ă½'), + (0xDE, 'M', 'Ă¾'), + (0xDF, 'D', 'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', 'Ä'), + (0x101, 'V'), + (0x102, 'M', 'ă'), + (0x103, 'V'), + (0x104, 'M', 'Ä…'), + (0x105, 'V'), + (0x106, 'M', 'ć'), + (0x107, 'V'), + (0x108, 'M', 'ĉ'), + (0x109, 'V'), + (0x10A, 'M', 'Ä‹'), + (0x10B, 'V'), + (0x10C, 'M', 'Ä'), + (0x10D, 'V'), + (0x10E, 'M', 'Ä'), + (0x10F, 'V'), + (0x110, 'M', 'Ä‘'), + (0x111, 'V'), + (0x112, 'M', 'Ä“'), + (0x113, 'V'), + (0x114, 'M', 'Ä•'), + (0x115, 'V'), + (0x116, 'M', 'Ä—'), + (0x117, 'V'), + (0x118, 'M', 'Ä™'), + (0x119, 'V'), + (0x11A, 'M', 'Ä›'), + (0x11B, 'V'), + (0x11C, 'M', 'Ä'), + (0x11D, 'V'), + (0x11E, 'M', 'ÄŸ'), + (0x11F, 'V'), + (0x120, 'M', 'Ä¡'), + (0x121, 'V'), + (0x122, 'M', 'Ä£'), + (0x123, 'V'), + (0x124, 'M', 'Ä¥'), + (0x125, 'V'), + (0x126, 'M', 'ħ'), + (0x127, 'V'), + (0x128, 'M', 'Ä©'), + (0x129, 'V'), + (0x12A, 'M', 'Ä«'), + (0x12B, 'V'), + ] + +def _seg_3() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x12C, 'M', 'Ä­'), + (0x12D, 'V'), + (0x12E, 'M', 'į'), + (0x12F, 'V'), + (0x130, 'M', 'ì‡'), + (0x131, 'V'), + (0x132, 'M', 'ij'), + (0x134, 'M', 'ĵ'), + (0x135, 'V'), + (0x136, 'M', 'Ä·'), + (0x137, 'V'), + (0x139, 'M', 'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', 'ļ'), + (0x13C, 'V'), + (0x13D, 'M', 'ľ'), + (0x13E, 'V'), + (0x13F, 'M', 'l·'), + (0x141, 'M', 'Å‚'), + (0x142, 'V'), + (0x143, 'M', 'Å„'), + (0x144, 'V'), + (0x145, 'M', 'ņ'), + (0x146, 'V'), + (0x147, 'M', 'ň'), + (0x148, 'V'), + (0x149, 'M', 'ʼn'), + (0x14A, 'M', 'Å‹'), + (0x14B, 'V'), + (0x14C, 'M', 'Å'), + (0x14D, 'V'), + (0x14E, 'M', 'Å'), + (0x14F, 'V'), + (0x150, 'M', 'Å‘'), + (0x151, 'V'), + (0x152, 'M', 'Å“'), + (0x153, 'V'), + (0x154, 'M', 'Å•'), + (0x155, 'V'), + (0x156, 'M', 'Å—'), + (0x157, 'V'), + (0x158, 'M', 'Å™'), + (0x159, 'V'), + (0x15A, 'M', 'Å›'), + (0x15B, 'V'), + (0x15C, 'M', 'Å'), + (0x15D, 'V'), + (0x15E, 'M', 'ÅŸ'), + (0x15F, 'V'), + (0x160, 'M', 'Å¡'), + (0x161, 'V'), + (0x162, 'M', 'Å£'), + (0x163, 'V'), + (0x164, 'M', 'Å¥'), + (0x165, 'V'), + (0x166, 'M', 'ŧ'), + (0x167, 'V'), + (0x168, 'M', 'Å©'), + (0x169, 'V'), + (0x16A, 'M', 'Å«'), + (0x16B, 'V'), + (0x16C, 'M', 'Å­'), + (0x16D, 'V'), + (0x16E, 'M', 'ů'), + (0x16F, 'V'), + (0x170, 'M', 'ű'), + (0x171, 'V'), + (0x172, 'M', 'ų'), + (0x173, 'V'), + (0x174, 'M', 'ŵ'), + (0x175, 'V'), + (0x176, 'M', 'Å·'), + (0x177, 'V'), + (0x178, 'M', 'Ă¿'), + (0x179, 'M', 'ź'), + (0x17A, 'V'), + (0x17B, 'M', 'ż'), + (0x17C, 'V'), + (0x17D, 'M', 'ž'), + (0x17E, 'V'), + (0x17F, 'M', 's'), + (0x180, 'V'), + (0x181, 'M', 'É“'), + (0x182, 'M', 'ƃ'), + (0x183, 'V'), + (0x184, 'M', 'Æ…'), + (0x185, 'V'), + (0x186, 'M', 'É”'), + (0x187, 'M', 'ƈ'), + (0x188, 'V'), + (0x189, 'M', 'É–'), + (0x18A, 'M', 'É—'), + (0x18B, 'M', 'ÆŒ'), + (0x18C, 'V'), + (0x18E, 'M', 'Ç'), + (0x18F, 'M', 'É™'), + (0x190, 'M', 'É›'), + (0x191, 'M', 'Æ’'), + (0x192, 'V'), + (0x193, 'M', 'É '), + ] + +def _seg_4() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x194, 'M', 'É£'), + (0x195, 'V'), + (0x196, 'M', 'É©'), + (0x197, 'M', 'ɨ'), + (0x198, 'M', 'Æ™'), + (0x199, 'V'), + (0x19C, 'M', 'ɯ'), + (0x19D, 'M', 'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', 'ɵ'), + (0x1A0, 'M', 'Æ¡'), + (0x1A1, 'V'), + (0x1A2, 'M', 'Æ£'), + (0x1A3, 'V'), + (0x1A4, 'M', 'Æ¥'), + (0x1A5, 'V'), + (0x1A6, 'M', 'Ê€'), + (0x1A7, 'M', 'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', 'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', 'Æ­'), + (0x1AD, 'V'), + (0x1AE, 'M', 'ʈ'), + (0x1AF, 'M', 'Æ°'), + (0x1B0, 'V'), + (0x1B1, 'M', 'Ê'), + (0x1B2, 'M', 'Ê‹'), + (0x1B3, 'M', 'Æ´'), + (0x1B4, 'V'), + (0x1B5, 'M', 'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', 'Ê’'), + (0x1B8, 'M', 'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', 'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', 'dž'), + (0x1C7, 'M', 'lj'), + (0x1CA, 'M', 'nj'), + (0x1CD, 'M', 'Ç'), + (0x1CE, 'V'), + (0x1CF, 'M', 'Ç'), + (0x1D0, 'V'), + (0x1D1, 'M', 'Ç’'), + (0x1D2, 'V'), + (0x1D3, 'M', 'Ç”'), + (0x1D4, 'V'), + (0x1D5, 'M', 'Ç–'), + (0x1D6, 'V'), + (0x1D7, 'M', 'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', 'Ç'), + (0x1DA, 'V'), + (0x1DB, 'M', 'Çœ'), + (0x1DC, 'V'), + (0x1DE, 'M', 'ÇŸ'), + (0x1DF, 'V'), + (0x1E0, 'M', 'Ç¡'), + (0x1E1, 'V'), + (0x1E2, 'M', 'Ç£'), + (0x1E3, 'V'), + (0x1E4, 'M', 'Ç¥'), + (0x1E5, 'V'), + (0x1E6, 'M', 'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', 'Ç©'), + (0x1E9, 'V'), + (0x1EA, 'M', 'Ç«'), + (0x1EB, 'V'), + (0x1EC, 'M', 'Ç­'), + (0x1ED, 'V'), + (0x1EE, 'M', 'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', 'dz'), + (0x1F4, 'M', 'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', 'Æ•'), + (0x1F7, 'M', 'Æ¿'), + (0x1F8, 'M', 'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', 'Ç»'), + (0x1FB, 'V'), + (0x1FC, 'M', 'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', 'Ç¿'), + (0x1FF, 'V'), + (0x200, 'M', 'È'), + (0x201, 'V'), + (0x202, 'M', 'ȃ'), + (0x203, 'V'), + (0x204, 'M', 'È…'), + (0x205, 'V'), + (0x206, 'M', 'ȇ'), + (0x207, 'V'), + (0x208, 'M', 'ȉ'), + (0x209, 'V'), + (0x20A, 'M', 'È‹'), + (0x20B, 'V'), + (0x20C, 'M', 'È'), + ] + +def _seg_5() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x20D, 'V'), + (0x20E, 'M', 'È'), + (0x20F, 'V'), + (0x210, 'M', 'È‘'), + (0x211, 'V'), + (0x212, 'M', 'È“'), + (0x213, 'V'), + (0x214, 'M', 'È•'), + (0x215, 'V'), + (0x216, 'M', 'È—'), + (0x217, 'V'), + (0x218, 'M', 'È™'), + (0x219, 'V'), + (0x21A, 'M', 'È›'), + (0x21B, 'V'), + (0x21C, 'M', 'È'), + (0x21D, 'V'), + (0x21E, 'M', 'ÈŸ'), + (0x21F, 'V'), + (0x220, 'M', 'Æ'), + (0x221, 'V'), + (0x222, 'M', 'È£'), + (0x223, 'V'), + (0x224, 'M', 'È¥'), + (0x225, 'V'), + (0x226, 'M', 'ȧ'), + (0x227, 'V'), + (0x228, 'M', 'È©'), + (0x229, 'V'), + (0x22A, 'M', 'È«'), + (0x22B, 'V'), + (0x22C, 'M', 'È­'), + (0x22D, 'V'), + (0x22E, 'M', 'ȯ'), + (0x22F, 'V'), + (0x230, 'M', 'ȱ'), + (0x231, 'V'), + (0x232, 'M', 'ȳ'), + (0x233, 'V'), + (0x23A, 'M', 'â±¥'), + (0x23B, 'M', 'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', 'Æ'), + (0x23E, 'M', 'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', 'É‚'), + (0x242, 'V'), + (0x243, 'M', 'Æ€'), + (0x244, 'M', 'ʉ'), + (0x245, 'M', 'ÊŒ'), + (0x246, 'M', 'ɇ'), + (0x247, 'V'), + (0x248, 'M', 'ɉ'), + (0x249, 'V'), + (0x24A, 'M', 'É‹'), + (0x24B, 'V'), + (0x24C, 'M', 'É'), + (0x24D, 'V'), + (0x24E, 'M', 'É'), + (0x24F, 'V'), + (0x2B0, 'M', 'h'), + (0x2B1, 'M', 'ɦ'), + (0x2B2, 'M', 'j'), + (0x2B3, 'M', 'r'), + (0x2B4, 'M', 'ɹ'), + (0x2B5, 'M', 'É»'), + (0x2B6, 'M', 'Ê'), + (0x2B7, 'M', 'w'), + (0x2B8, 'M', 'y'), + (0x2B9, 'V'), + (0x2D8, '3', ' ̀†'), + (0x2D9, '3', ' ̀‡'), + (0x2DA, '3', ' ̀'), + (0x2DB, '3', ' ̀¨'), + (0x2DC, '3', ' ̀ƒ'), + (0x2DD, '3', ' ̀‹'), + (0x2DE, 'V'), + (0x2E0, 'M', 'É£'), + (0x2E1, 'M', 'l'), + (0x2E2, 'M', 's'), + (0x2E3, 'M', 'x'), + (0x2E4, 'M', 'Ê•'), + (0x2E5, 'V'), + (0x340, 'M', '̀€'), + (0x341, 'M', '̀'), + (0x342, 'V'), + (0x343, 'M', '̀“'), + (0x344, 'M', '̀ˆ̀'), + (0x345, 'M', 'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', 'ͱ'), + (0x371, 'V'), + (0x372, 'M', 'ͳ'), + (0x373, 'V'), + (0x374, 'M', 'ʹ'), + (0x375, 'V'), + (0x376, 'M', 'Í·'), + (0x377, 'V'), + ] + +def _seg_6() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x378, 'X'), + (0x37A, '3', ' ι'), + (0x37B, 'V'), + (0x37E, '3', ';'), + (0x37F, 'M', 'ϳ'), + (0x380, 'X'), + (0x384, '3', ' ̀'), + (0x385, '3', ' ̀ˆ̀'), + (0x386, 'M', 'ά'), + (0x387, 'M', '·'), + (0x388, 'M', 'έ'), + (0x389, 'M', 'ή'), + (0x38A, 'M', 'ί'), + (0x38B, 'X'), + (0x38C, 'M', 'ÏŒ'), + (0x38D, 'X'), + (0x38E, 'M', 'Ï'), + (0x38F, 'M', 'Ï'), + (0x390, 'V'), + (0x391, 'M', 'α'), + (0x392, 'M', 'β'), + (0x393, 'M', 'γ'), + (0x394, 'M', 'δ'), + (0x395, 'M', 'ε'), + (0x396, 'M', 'ζ'), + (0x397, 'M', 'η'), + (0x398, 'M', 'θ'), + (0x399, 'M', 'ι'), + (0x39A, 'M', 'κ'), + (0x39B, 'M', 'λ'), + (0x39C, 'M', 'μ'), + (0x39D, 'M', 'ν'), + (0x39E, 'M', 'ξ'), + (0x39F, 'M', 'ο'), + (0x3A0, 'M', 'Ï€'), + (0x3A1, 'M', 'Ï'), + (0x3A2, 'X'), + (0x3A3, 'M', 'σ'), + (0x3A4, 'M', 'Ï„'), + (0x3A5, 'M', 'Ï…'), + (0x3A6, 'M', 'φ'), + (0x3A7, 'M', 'χ'), + (0x3A8, 'M', 'ψ'), + (0x3A9, 'M', 'ω'), + (0x3AA, 'M', 'Ï'), + (0x3AB, 'M', 'Ï‹'), + (0x3AC, 'V'), + (0x3C2, 'D', 'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', 'Ï—'), + (0x3D0, 'M', 'β'), + (0x3D1, 'M', 'θ'), + (0x3D2, 'M', 'Ï…'), + (0x3D3, 'M', 'Ï'), + (0x3D4, 'M', 'Ï‹'), + (0x3D5, 'M', 'φ'), + (0x3D6, 'M', 'Ï€'), + (0x3D7, 'V'), + (0x3D8, 'M', 'Ï™'), + (0x3D9, 'V'), + (0x3DA, 'M', 'Ï›'), + (0x3DB, 'V'), + (0x3DC, 'M', 'Ï'), + (0x3DD, 'V'), + (0x3DE, 'M', 'ÏŸ'), + (0x3DF, 'V'), + (0x3E0, 'M', 'Ï¡'), + (0x3E1, 'V'), + (0x3E2, 'M', 'Ï£'), + (0x3E3, 'V'), + (0x3E4, 'M', 'Ï¥'), + (0x3E5, 'V'), + (0x3E6, 'M', 'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', 'Ï©'), + (0x3E9, 'V'), + (0x3EA, 'M', 'Ï«'), + (0x3EB, 'V'), + (0x3EC, 'M', 'Ï­'), + (0x3ED, 'V'), + (0x3EE, 'M', 'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', 'κ'), + (0x3F1, 'M', 'Ï'), + (0x3F2, 'M', 'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', 'θ'), + (0x3F5, 'M', 'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', 'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', 'σ'), + (0x3FA, 'M', 'Ï»'), + (0x3FB, 'V'), + (0x3FD, 'M', 'Í»'), + (0x3FE, 'M', 'ͼ'), + (0x3FF, 'M', 'ͽ'), + (0x400, 'M', 'Ñ'), + (0x401, 'M', 'Ñ‘'), + (0x402, 'M', 'Ñ’'), + ] + +def _seg_7() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x403, 'M', 'Ñ“'), + (0x404, 'M', 'Ñ”'), + (0x405, 'M', 'Ñ•'), + (0x406, 'M', 'Ñ–'), + (0x407, 'M', 'Ñ—'), + (0x408, 'M', 'ј'), + (0x409, 'M', 'Ñ™'), + (0x40A, 'M', 'Ñ'), + (0x40B, 'M', 'Ñ›'), + (0x40C, 'M', 'Ñœ'), + (0x40D, 'M', 'Ñ'), + (0x40E, 'M', 'Ñ'), + (0x40F, 'M', 'ÑŸ'), + (0x410, 'M', 'Đ°'), + (0x411, 'M', 'б'), + (0x412, 'M', 'Đ²'), + (0x413, 'M', 'Đ³'), + (0x414, 'M', 'Đ´'), + (0x415, 'M', 'е'), + (0x416, 'M', 'ж'), + (0x417, 'M', 'Đ·'), + (0x418, 'M', 'и'), + (0x419, 'M', 'Đ¹'), + (0x41A, 'M', 'Đº'), + (0x41B, 'M', 'Đ»'), + (0x41C, 'M', 'Đ¼'), + (0x41D, 'M', 'Đ½'), + (0x41E, 'M', 'Đ¾'), + (0x41F, 'M', 'Đ¿'), + (0x420, 'M', 'Ñ€'), + (0x421, 'M', 'Ñ'), + (0x422, 'M', 'Ñ‚'), + (0x423, 'M', 'у'), + (0x424, 'M', 'Ñ„'), + (0x425, 'M', 'Ñ…'), + (0x426, 'M', 'ц'), + (0x427, 'M', 'ч'), + (0x428, 'M', 'ш'), + (0x429, 'M', 'щ'), + (0x42A, 'M', 'Ñ'), + (0x42B, 'M', 'Ñ‹'), + (0x42C, 'M', 'ÑŒ'), + (0x42D, 'M', 'Ñ'), + (0x42E, 'M', 'Ñ'), + (0x42F, 'M', 'Ñ'), + (0x430, 'V'), + (0x460, 'M', 'Ñ¡'), + (0x461, 'V'), + (0x462, 'M', 'Ñ£'), + (0x463, 'V'), + (0x464, 'M', 'Ñ¥'), + (0x465, 'V'), + (0x466, 'M', 'ѧ'), + (0x467, 'V'), + (0x468, 'M', 'Ñ©'), + (0x469, 'V'), + (0x46A, 'M', 'Ñ«'), + (0x46B, 'V'), + (0x46C, 'M', 'Ñ­'), + (0x46D, 'V'), + (0x46E, 'M', 'ѯ'), + (0x46F, 'V'), + (0x470, 'M', 'ѱ'), + (0x471, 'V'), + (0x472, 'M', 'ѳ'), + (0x473, 'V'), + (0x474, 'M', 'ѵ'), + (0x475, 'V'), + (0x476, 'M', 'Ñ·'), + (0x477, 'V'), + (0x478, 'M', 'ѹ'), + (0x479, 'V'), + (0x47A, 'M', 'Ñ»'), + (0x47B, 'V'), + (0x47C, 'M', 'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', 'Ñ¿'), + (0x47F, 'V'), + (0x480, 'M', '̉'), + (0x481, 'V'), + (0x48A, 'M', '̉‹'), + (0x48B, 'V'), + (0x48C, 'M', '̉'), + (0x48D, 'V'), + (0x48E, 'M', '̉'), + (0x48F, 'V'), + (0x490, 'M', '̉‘'), + (0x491, 'V'), + (0x492, 'M', '̉“'), + (0x493, 'V'), + (0x494, 'M', '̉•'), + (0x495, 'V'), + (0x496, 'M', '̉—'), + (0x497, 'V'), + (0x498, 'M', '̉™'), + (0x499, 'V'), + (0x49A, 'M', '̉›'), + (0x49B, 'V'), + (0x49C, 'M', '̉'), + (0x49D, 'V'), + ] + +def _seg_8() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x49E, 'M', '̉Ÿ'), + (0x49F, 'V'), + (0x4A0, 'M', '̉¡'), + (0x4A1, 'V'), + (0x4A2, 'M', '̉£'), + (0x4A3, 'V'), + (0x4A4, 'M', '̉¥'), + (0x4A5, 'V'), + (0x4A6, 'M', '̉§'), + (0x4A7, 'V'), + (0x4A8, 'M', '̉©'), + (0x4A9, 'V'), + (0x4AA, 'M', '̉«'), + (0x4AB, 'V'), + (0x4AC, 'M', '̉­'), + (0x4AD, 'V'), + (0x4AE, 'M', '̉¯'), + (0x4AF, 'V'), + (0x4B0, 'M', '̉±'), + (0x4B1, 'V'), + (0x4B2, 'M', '̉³'), + (0x4B3, 'V'), + (0x4B4, 'M', '̉µ'), + (0x4B5, 'V'), + (0x4B6, 'M', '̉·'), + (0x4B7, 'V'), + (0x4B8, 'M', '̉¹'), + (0x4B9, 'V'), + (0x4BA, 'M', '̉»'), + (0x4BB, 'V'), + (0x4BC, 'M', '̉½'), + (0x4BD, 'V'), + (0x4BE, 'M', '̉¿'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', 'Ó‚'), + (0x4C2, 'V'), + (0x4C3, 'M', 'Ó„'), + (0x4C4, 'V'), + (0x4C5, 'M', 'Ó†'), + (0x4C6, 'V'), + (0x4C7, 'M', 'Óˆ'), + (0x4C8, 'V'), + (0x4C9, 'M', 'Ó'), + (0x4CA, 'V'), + (0x4CB, 'M', 'ÓŒ'), + (0x4CC, 'V'), + (0x4CD, 'M', 'Ó'), + (0x4CE, 'V'), + (0x4D0, 'M', 'Ó‘'), + (0x4D1, 'V'), + (0x4D2, 'M', 'Ó“'), + (0x4D3, 'V'), + (0x4D4, 'M', 'Ó•'), + (0x4D5, 'V'), + (0x4D6, 'M', 'Ó—'), + (0x4D7, 'V'), + (0x4D8, 'M', 'Ó™'), + (0x4D9, 'V'), + (0x4DA, 'M', 'Ó›'), + (0x4DB, 'V'), + (0x4DC, 'M', 'Ó'), + (0x4DD, 'V'), + (0x4DE, 'M', 'ÓŸ'), + (0x4DF, 'V'), + (0x4E0, 'M', 'Ó¡'), + (0x4E1, 'V'), + (0x4E2, 'M', 'Ó£'), + (0x4E3, 'V'), + (0x4E4, 'M', 'Ó¥'), + (0x4E5, 'V'), + (0x4E6, 'M', 'Ó§'), + (0x4E7, 'V'), + (0x4E8, 'M', 'Ó©'), + (0x4E9, 'V'), + (0x4EA, 'M', 'Ó«'), + (0x4EB, 'V'), + (0x4EC, 'M', 'Ó­'), + (0x4ED, 'V'), + (0x4EE, 'M', 'Ó¯'), + (0x4EF, 'V'), + (0x4F0, 'M', 'Ó±'), + (0x4F1, 'V'), + (0x4F2, 'M', 'Ó³'), + (0x4F3, 'V'), + (0x4F4, 'M', 'Óµ'), + (0x4F5, 'V'), + (0x4F6, 'M', 'Ó·'), + (0x4F7, 'V'), + (0x4F8, 'M', 'Ó¹'), + (0x4F9, 'V'), + (0x4FA, 'M', 'Ó»'), + (0x4FB, 'V'), + (0x4FC, 'M', 'Ó½'), + (0x4FD, 'V'), + (0x4FE, 'M', 'Ó¿'), + (0x4FF, 'V'), + (0x500, 'M', 'Ô'), + (0x501, 'V'), + (0x502, 'M', 'Ôƒ'), + ] + +def _seg_9() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x503, 'V'), + (0x504, 'M', 'Ô…'), + (0x505, 'V'), + (0x506, 'M', 'Ô‡'), + (0x507, 'V'), + (0x508, 'M', 'Ô‰'), + (0x509, 'V'), + (0x50A, 'M', 'Ô‹'), + (0x50B, 'V'), + (0x50C, 'M', 'Ô'), + (0x50D, 'V'), + (0x50E, 'M', 'Ô'), + (0x50F, 'V'), + (0x510, 'M', 'Ô‘'), + (0x511, 'V'), + (0x512, 'M', 'Ô“'), + (0x513, 'V'), + (0x514, 'M', 'Ô•'), + (0x515, 'V'), + (0x516, 'M', 'Ô—'), + (0x517, 'V'), + (0x518, 'M', 'Ô™'), + (0x519, 'V'), + (0x51A, 'M', 'Ô›'), + (0x51B, 'V'), + (0x51C, 'M', 'Ô'), + (0x51D, 'V'), + (0x51E, 'M', 'ÔŸ'), + (0x51F, 'V'), + (0x520, 'M', 'Ô¡'), + (0x521, 'V'), + (0x522, 'M', 'Ô£'), + (0x523, 'V'), + (0x524, 'M', 'Ô¥'), + (0x525, 'V'), + (0x526, 'M', 'Ô§'), + (0x527, 'V'), + (0x528, 'M', 'Ô©'), + (0x529, 'V'), + (0x52A, 'M', 'Ô«'), + (0x52B, 'V'), + (0x52C, 'M', 'Ô­'), + (0x52D, 'V'), + (0x52E, 'M', 'Ô¯'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', 'Ơ¡'), + (0x532, 'M', 'Ơ¢'), + (0x533, 'M', 'Ơ£'), + (0x534, 'M', 'Ơ¤'), + (0x535, 'M', 'Ơ¥'), + (0x536, 'M', 'Ơ¦'), + (0x537, 'M', 'Ơ§'), + (0x538, 'M', 'Ơ¨'), + (0x539, 'M', 'Ơ©'), + (0x53A, 'M', 'Ơª'), + (0x53B, 'M', 'Ơ«'), + (0x53C, 'M', 'Ơ¬'), + (0x53D, 'M', 'Ơ­'), + (0x53E, 'M', 'Ơ®'), + (0x53F, 'M', 'Ơ¯'), + (0x540, 'M', 'Ơ°'), + (0x541, 'M', 'Ơ±'), + (0x542, 'M', 'Ơ²'), + (0x543, 'M', 'Ơ³'), + (0x544, 'M', 'Ơ´'), + (0x545, 'M', 'Ơµ'), + (0x546, 'M', 'Ơ¶'), + (0x547, 'M', 'Ơ·'), + (0x548, 'M', 'Ơ¸'), + (0x549, 'M', 'Ơ¹'), + (0x54A, 'M', 'Ơº'), + (0x54B, 'M', 'Ơ»'), + (0x54C, 'M', 'Ơ¼'), + (0x54D, 'M', 'Ơ½'), + (0x54E, 'M', 'Ơ¾'), + (0x54F, 'M', 'Ơ¿'), + (0x550, 'M', 'Ö€'), + (0x551, 'M', 'Ö'), + (0x552, 'M', 'Ö‚'), + (0x553, 'M', 'Öƒ'), + (0x554, 'M', 'Ö„'), + (0x555, 'M', 'Ö…'), + (0x556, 'M', 'Ö†'), + (0x557, 'X'), + (0x559, 'V'), + (0x587, 'M', 'Ơ¥Ö‚'), + (0x588, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5EF, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61D, 'V'), + ] + +def _seg_10() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x675, 'M', 'اٴ'), + (0x676, 'M', 'وٴ'), + (0x677, 'M', 'Û‡Ù´'), + (0x678, 'M', 'ÙÙ´'), + (0x679, 'V'), + (0x6DD, 'X'), + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x7FD, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x860, 'V'), + (0x86B, 'X'), + (0x870, 'V'), + (0x88F, 'X'), + (0x898, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', 'क़'), + (0x959, 'M', 'ख़'), + (0x95A, 'M', 'ग़'), + (0x95B, 'M', 'ज़'), + (0x95C, 'M', 'ड़'), + (0x95D, 'M', 'ढ़'), + (0x95E, 'M', 'फ़'), + (0x95F, 'M', 'य़'), + (0x960, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', 'ড়'), + (0x9DD, 'M', 'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', 'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FF, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', 'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', 'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + (0xA59, 'M', 'ਖ਼'), + (0xA5A, 'M', 'ਗ਼'), + (0xA5B, 'M', 'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + ] + +def _seg_11() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA5E, 'M', 'ਫ਼'), + (0xA5F, 'X'), + (0xA66, 'V'), + (0xA77, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xAF9, 'V'), + (0xB00, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB55, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', 'ଡ଼'), + (0xB5D, 'M', 'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC00, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + ] + +def _seg_12() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC3A, 'X'), + (0xC3C, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC5D, 'V'), + (0xC5E, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC77, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDD, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF4, 'X'), + (0xD00, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD50, 'X'), + (0xD54, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD80, 'X'), + (0xD81, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDE6, 'V'), + (0xDF0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', 'à¹à¸²'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE86, 'V'), + (0xE8B, 'X'), + (0xE8C, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEB3, 'M', 'à»àº²'), + (0xEB4, 'V'), + ] + +def _seg_13() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECF, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', 'ຫນ'), + (0xEDD, 'M', 'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', '་'), + (0xF0D, 'V'), + (0xF43, 'M', 'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', 'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', 'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', 'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', 'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', 'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', 'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', 'ཱུ'), + (0xF76, 'M', 'ྲྀ'), + (0xF77, 'M', 'ྲཱྀ'), + (0xF78, 'M', 'ླྀ'), + (0xF79, 'M', 'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', 'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', 'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', 'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', 'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', 'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', 'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', 'à¾à¾µ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', 'â´§'), + (0x10C8, 'X'), + (0x10CD, 'M', 'â´­'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', 'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + (0x1258, 'V'), + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + ] + +def _seg_14() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', 'á°'), + (0x13F9, 'M', 'á±'), + (0x13FA, 'M', 'á²'), + (0x13FB, 'M', 'á³'), + (0x13FC, 'M', 'á´'), + (0x13FD, 'M', 'áµ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x1716, 'X'), + (0x171F, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x180F, 'I'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1879, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191F, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1ACF, 'X'), + (0x1B00, 'V'), + (0x1B4D, 'X'), + (0x1B50, 'V'), + (0x1B7F, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'M', 'Đ²'), + ] + +def _seg_15() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1C81, 'M', 'Đ´'), + (0x1C82, 'M', 'Đ¾'), + (0x1C83, 'M', 'Ñ'), + (0x1C84, 'M', 'Ñ‚'), + (0x1C86, 'M', 'Ñ'), + (0x1C87, 'M', 'Ñ£'), + (0x1C88, 'M', 'ꙋ'), + (0x1C89, 'X'), + (0x1C90, 'M', 'áƒ'), + (0x1C91, 'M', 'ბ'), + (0x1C92, 'M', 'გ'), + (0x1C93, 'M', 'დ'), + (0x1C94, 'M', 'ე'), + (0x1C95, 'M', 'ვ'), + (0x1C96, 'M', 'ზ'), + (0x1C97, 'M', 'თ'), + (0x1C98, 'M', 'ი'), + (0x1C99, 'M', 'კ'), + (0x1C9A, 'M', 'áƒ'), + (0x1C9B, 'M', 'მ'), + (0x1C9C, 'M', 'ნ'), + (0x1C9D, 'M', 'áƒ'), + (0x1C9E, 'M', 'áƒ'), + (0x1C9F, 'M', 'ჟ'), + (0x1CA0, 'M', 'რ'), + (0x1CA1, 'M', 'ს'), + (0x1CA2, 'M', 'ტ'), + (0x1CA3, 'M', 'უ'), + (0x1CA4, 'M', 'ფ'), + (0x1CA5, 'M', 'ქ'), + (0x1CA6, 'M', 'ღ'), + (0x1CA7, 'M', 'ყ'), + (0x1CA8, 'M', 'შ'), + (0x1CA9, 'M', 'ჩ'), + (0x1CAA, 'M', 'ც'), + (0x1CAB, 'M', 'ძ'), + (0x1CAC, 'M', 'წ'), + (0x1CAD, 'M', 'ჭ'), + (0x1CAE, 'M', 'ხ'), + (0x1CAF, 'M', 'ჯ'), + (0x1CB0, 'M', 'ჰ'), + (0x1CB1, 'M', 'ჱ'), + (0x1CB2, 'M', 'ჲ'), + (0x1CB3, 'M', 'ჳ'), + (0x1CB4, 'M', 'ჴ'), + (0x1CB5, 'M', 'ჵ'), + (0x1CB6, 'M', 'ჶ'), + (0x1CB7, 'M', 'ჷ'), + (0x1CB8, 'M', 'ჸ'), + (0x1CB9, 'M', 'ჹ'), + (0x1CBA, 'M', 'ჺ'), + (0x1CBB, 'X'), + (0x1CBD, 'M', 'ჽ'), + (0x1CBE, 'M', 'ჾ'), + (0x1CBF, 'M', 'ჿ'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFB, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', 'a'), + (0x1D2D, 'M', 'æ'), + (0x1D2E, 'M', 'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', 'd'), + (0x1D31, 'M', 'e'), + (0x1D32, 'M', 'Ç'), + (0x1D33, 'M', 'g'), + (0x1D34, 'M', 'h'), + (0x1D35, 'M', 'i'), + (0x1D36, 'M', 'j'), + (0x1D37, 'M', 'k'), + (0x1D38, 'M', 'l'), + (0x1D39, 'M', 'm'), + (0x1D3A, 'M', 'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', 'o'), + (0x1D3D, 'M', 'È£'), + (0x1D3E, 'M', 'p'), + (0x1D3F, 'M', 'r'), + (0x1D40, 'M', 't'), + (0x1D41, 'M', 'u'), + (0x1D42, 'M', 'w'), + (0x1D43, 'M', 'a'), + (0x1D44, 'M', 'É'), + (0x1D45, 'M', 'É‘'), + (0x1D46, 'M', 'á´‚'), + (0x1D47, 'M', 'b'), + (0x1D48, 'M', 'd'), + (0x1D49, 'M', 'e'), + (0x1D4A, 'M', 'É™'), + (0x1D4B, 'M', 'É›'), + (0x1D4C, 'M', 'Éœ'), + (0x1D4D, 'M', 'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', 'k'), + (0x1D50, 'M', 'm'), + (0x1D51, 'M', 'Å‹'), + (0x1D52, 'M', 'o'), + (0x1D53, 'M', 'É”'), + ] + +def _seg_16() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D54, 'M', 'á´–'), + (0x1D55, 'M', 'á´—'), + (0x1D56, 'M', 'p'), + (0x1D57, 'M', 't'), + (0x1D58, 'M', 'u'), + (0x1D59, 'M', 'á´'), + (0x1D5A, 'M', 'ɯ'), + (0x1D5B, 'M', 'v'), + (0x1D5C, 'M', 'á´¥'), + (0x1D5D, 'M', 'β'), + (0x1D5E, 'M', 'γ'), + (0x1D5F, 'M', 'δ'), + (0x1D60, 'M', 'φ'), + (0x1D61, 'M', 'χ'), + (0x1D62, 'M', 'i'), + (0x1D63, 'M', 'r'), + (0x1D64, 'M', 'u'), + (0x1D65, 'M', 'v'), + (0x1D66, 'M', 'β'), + (0x1D67, 'M', 'γ'), + (0x1D68, 'M', 'Ï'), + (0x1D69, 'M', 'φ'), + (0x1D6A, 'M', 'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', 'Đ½'), + (0x1D79, 'V'), + (0x1D9B, 'M', 'É’'), + (0x1D9C, 'M', 'c'), + (0x1D9D, 'M', 'É•'), + (0x1D9E, 'M', 'Ă°'), + (0x1D9F, 'M', 'Éœ'), + (0x1DA0, 'M', 'f'), + (0x1DA1, 'M', 'ÉŸ'), + (0x1DA2, 'M', 'É¡'), + (0x1DA3, 'M', 'É¥'), + (0x1DA4, 'M', 'ɨ'), + (0x1DA5, 'M', 'É©'), + (0x1DA6, 'M', 'ɪ'), + (0x1DA7, 'M', 'áµ»'), + (0x1DA8, 'M', 'Ê'), + (0x1DA9, 'M', 'É­'), + (0x1DAA, 'M', 'ᶅ'), + (0x1DAB, 'M', 'ÊŸ'), + (0x1DAC, 'M', 'ɱ'), + (0x1DAD, 'M', 'É°'), + (0x1DAE, 'M', 'ɲ'), + (0x1DAF, 'M', 'ɳ'), + (0x1DB0, 'M', 'É´'), + (0x1DB1, 'M', 'ɵ'), + (0x1DB2, 'M', 'ɸ'), + (0x1DB3, 'M', 'Ê‚'), + (0x1DB4, 'M', 'ʃ'), + (0x1DB5, 'M', 'Æ«'), + (0x1DB6, 'M', 'ʉ'), + (0x1DB7, 'M', 'Ê'), + (0x1DB8, 'M', 'á´œ'), + (0x1DB9, 'M', 'Ê‹'), + (0x1DBA, 'M', 'ÊŒ'), + (0x1DBB, 'M', 'z'), + (0x1DBC, 'M', 'Ê'), + (0x1DBD, 'M', 'Ê‘'), + (0x1DBE, 'M', 'Ê’'), + (0x1DBF, 'M', 'θ'), + (0x1DC0, 'V'), + (0x1E00, 'M', 'á¸'), + (0x1E01, 'V'), + (0x1E02, 'M', 'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', 'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', 'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', 'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', 'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', 'á¸'), + (0x1E0D, 'V'), + (0x1E0E, 'M', 'á¸'), + (0x1E0F, 'V'), + (0x1E10, 'M', 'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', 'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', 'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', 'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', 'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', 'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', 'á¸'), + (0x1E1D, 'V'), + (0x1E1E, 'M', 'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', 'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', 'ḣ'), + (0x1E23, 'V'), + ] + +def _seg_17() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E24, 'M', 'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', 'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', 'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', 'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', 'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', 'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', 'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', 'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', 'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', 'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', 'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', 'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', 'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', 'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', 'á¹'), + (0x1E41, 'V'), + (0x1E42, 'M', 'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', 'á¹…'), + (0x1E45, 'V'), + (0x1E46, 'M', 'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', 'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', 'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', 'á¹'), + (0x1E4D, 'V'), + (0x1E4E, 'M', 'á¹'), + (0x1E4F, 'V'), + (0x1E50, 'M', 'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', 'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', 'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', 'á¹—'), + (0x1E57, 'V'), + (0x1E58, 'M', 'á¹™'), + (0x1E59, 'V'), + (0x1E5A, 'M', 'á¹›'), + (0x1E5B, 'V'), + (0x1E5C, 'M', 'á¹'), + (0x1E5D, 'V'), + (0x1E5E, 'M', 'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', 'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', 'á¹£'), + (0x1E63, 'V'), + (0x1E64, 'M', 'á¹¥'), + (0x1E65, 'V'), + (0x1E66, 'M', 'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', 'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', 'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', 'á¹­'), + (0x1E6D, 'V'), + (0x1E6E, 'M', 'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', 'á¹±'), + (0x1E71, 'V'), + (0x1E72, 'M', 'á¹³'), + (0x1E73, 'V'), + (0x1E74, 'M', 'á¹µ'), + (0x1E75, 'V'), + (0x1E76, 'M', 'á¹·'), + (0x1E77, 'V'), + (0x1E78, 'M', 'á¹¹'), + (0x1E79, 'V'), + (0x1E7A, 'M', 'á¹»'), + (0x1E7B, 'V'), + (0x1E7C, 'M', 'á¹½'), + (0x1E7D, 'V'), + (0x1E7E, 'M', 'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', 'áº'), + (0x1E81, 'V'), + (0x1E82, 'M', 'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', 'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', 'ẇ'), + (0x1E87, 'V'), + ] + +def _seg_18() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E88, 'M', 'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', 'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', 'áº'), + (0x1E8D, 'V'), + (0x1E8E, 'M', 'áº'), + (0x1E8F, 'V'), + (0x1E90, 'M', 'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', 'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', 'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', 'aʾ'), + (0x1E9B, 'M', 'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', 'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', 'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', 'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', 'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', 'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', 'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', 'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', 'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', 'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', 'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', 'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', 'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', 'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', 'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', 'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', 'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', 'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', 'á»'), + (0x1EC1, 'V'), + (0x1EC2, 'M', 'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', 'á»…'), + (0x1EC5, 'V'), + (0x1EC6, 'M', 'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', 'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', 'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', 'á»'), + (0x1ECD, 'V'), + (0x1ECE, 'M', 'á»'), + (0x1ECF, 'V'), + (0x1ED0, 'M', 'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', 'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', 'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', 'á»—'), + (0x1ED7, 'V'), + (0x1ED8, 'M', 'á»™'), + (0x1ED9, 'V'), + (0x1EDA, 'M', 'á»›'), + (0x1EDB, 'V'), + (0x1EDC, 'M', 'á»'), + (0x1EDD, 'V'), + (0x1EDE, 'M', 'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', 'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', 'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', 'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', 'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', 'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', 'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', 'á»­'), + (0x1EED, 'V'), + (0x1EEE, 'M', 'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', 'á»±'), + ] + +def _seg_19() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EF1, 'V'), + (0x1EF2, 'M', 'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', 'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', 'á»·'), + (0x1EF7, 'V'), + (0x1EF8, 'M', 'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', 'á»»'), + (0x1EFB, 'V'), + (0x1EFC, 'M', 'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', 'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', 'á¼€'), + (0x1F09, 'M', 'á¼'), + (0x1F0A, 'M', 'ἂ'), + (0x1F0B, 'M', 'ἃ'), + (0x1F0C, 'M', 'ἄ'), + (0x1F0D, 'M', 'á¼…'), + (0x1F0E, 'M', 'ἆ'), + (0x1F0F, 'M', 'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', 'á¼'), + (0x1F19, 'M', 'ἑ'), + (0x1F1A, 'M', 'á¼’'), + (0x1F1B, 'M', 'ἓ'), + (0x1F1C, 'M', 'á¼”'), + (0x1F1D, 'M', 'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', 'á¼ '), + (0x1F29, 'M', 'ἡ'), + (0x1F2A, 'M', 'á¼¢'), + (0x1F2B, 'M', 'á¼£'), + (0x1F2C, 'M', 'ἤ'), + (0x1F2D, 'M', 'á¼¥'), + (0x1F2E, 'M', 'ἦ'), + (0x1F2F, 'M', 'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', 'á¼°'), + (0x1F39, 'M', 'á¼±'), + (0x1F3A, 'M', 'á¼²'), + (0x1F3B, 'M', 'á¼³'), + (0x1F3C, 'M', 'á¼´'), + (0x1F3D, 'M', 'á¼µ'), + (0x1F3E, 'M', 'ἶ'), + (0x1F3F, 'M', 'á¼·'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', 'á½€'), + (0x1F49, 'M', 'á½'), + (0x1F4A, 'M', 'ὂ'), + (0x1F4B, 'M', 'ὃ'), + (0x1F4C, 'M', 'ὄ'), + (0x1F4D, 'M', 'á½…'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', 'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', 'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', 'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', 'á½—'), + (0x1F60, 'V'), + (0x1F68, 'M', 'á½ '), + (0x1F69, 'M', 'ὡ'), + (0x1F6A, 'M', 'á½¢'), + (0x1F6B, 'M', 'á½£'), + (0x1F6C, 'M', 'ὤ'), + (0x1F6D, 'M', 'á½¥'), + (0x1F6E, 'M', 'ὦ'), + (0x1F6F, 'M', 'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', 'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', 'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', 'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', 'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', 'ÏŒ'), + (0x1F7A, 'V'), + (0x1F7B, 'M', 'Ï'), + (0x1F7C, 'V'), + (0x1F7D, 'M', 'Ï'), + (0x1F7E, 'X'), + (0x1F80, 'M', 'ἀι'), + (0x1F81, 'M', 'á¼Î¹'), + (0x1F82, 'M', 'ἂι'), + (0x1F83, 'M', 'ἃι'), + (0x1F84, 'M', 'ἄι'), + (0x1F85, 'M', 'ἅι'), + (0x1F86, 'M', 'ἆι'), + (0x1F87, 'M', 'ἇι'), + ] + +def _seg_20() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F88, 'M', 'ἀι'), + (0x1F89, 'M', 'á¼Î¹'), + (0x1F8A, 'M', 'ἂι'), + (0x1F8B, 'M', 'ἃι'), + (0x1F8C, 'M', 'ἄι'), + (0x1F8D, 'M', 'ἅι'), + (0x1F8E, 'M', 'ἆι'), + (0x1F8F, 'M', 'ἇι'), + (0x1F90, 'M', 'ἠι'), + (0x1F91, 'M', 'ἡι'), + (0x1F92, 'M', 'ἢι'), + (0x1F93, 'M', 'ἣι'), + (0x1F94, 'M', 'ἤι'), + (0x1F95, 'M', 'ἥι'), + (0x1F96, 'M', 'ἦι'), + (0x1F97, 'M', 'ἧι'), + (0x1F98, 'M', 'ἠι'), + (0x1F99, 'M', 'ἡι'), + (0x1F9A, 'M', 'ἢι'), + (0x1F9B, 'M', 'ἣι'), + (0x1F9C, 'M', 'ἤι'), + (0x1F9D, 'M', 'ἥι'), + (0x1F9E, 'M', 'ἦι'), + (0x1F9F, 'M', 'ἧι'), + (0x1FA0, 'M', 'ὠι'), + (0x1FA1, 'M', 'ὡι'), + (0x1FA2, 'M', 'ὢι'), + (0x1FA3, 'M', 'ὣι'), + (0x1FA4, 'M', 'ὤι'), + (0x1FA5, 'M', 'ὥι'), + (0x1FA6, 'M', 'ὦι'), + (0x1FA7, 'M', 'ὧι'), + (0x1FA8, 'M', 'ὠι'), + (0x1FA9, 'M', 'ὡι'), + (0x1FAA, 'M', 'ὢι'), + (0x1FAB, 'M', 'ὣι'), + (0x1FAC, 'M', 'ὤι'), + (0x1FAD, 'M', 'ὥι'), + (0x1FAE, 'M', 'ὦι'), + (0x1FAF, 'M', 'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', 'ὰι'), + (0x1FB3, 'M', 'αι'), + (0x1FB4, 'M', 'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', 'ᾶι'), + (0x1FB8, 'M', 'á¾°'), + (0x1FB9, 'M', 'á¾±'), + (0x1FBA, 'M', 'á½°'), + (0x1FBB, 'M', 'ά'), + (0x1FBC, 'M', 'αι'), + (0x1FBD, '3', ' ̀“'), + (0x1FBE, 'M', 'ι'), + (0x1FBF, '3', ' ̀“'), + (0x1FC0, '3', ' Í‚'), + (0x1FC1, '3', ' ̀ˆÍ‚'), + (0x1FC2, 'M', 'ὴι'), + (0x1FC3, 'M', 'ηι'), + (0x1FC4, 'M', 'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', 'ῆι'), + (0x1FC8, 'M', 'á½²'), + (0x1FC9, 'M', 'έ'), + (0x1FCA, 'M', 'á½´'), + (0x1FCB, 'M', 'ή'), + (0x1FCC, 'M', 'ηι'), + (0x1FCD, '3', ' ̀“̀€'), + (0x1FCE, '3', ' ̀“̀'), + (0x1FCF, '3', ' ̀“Í‚'), + (0x1FD0, 'V'), + (0x1FD3, 'M', 'Î'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', 'á¿'), + (0x1FD9, 'M', 'á¿‘'), + (0x1FDA, 'M', 'ὶ'), + (0x1FDB, 'M', 'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', ' ̀”̀€'), + (0x1FDE, '3', ' ̀”̀'), + (0x1FDF, '3', ' ̀”Í‚'), + (0x1FE0, 'V'), + (0x1FE3, 'M', 'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', 'á¿ '), + (0x1FE9, 'M', 'á¿¡'), + (0x1FEA, 'M', 'ὺ'), + (0x1FEB, 'M', 'Ï'), + (0x1FEC, 'M', 'á¿¥'), + (0x1FED, '3', ' ̀ˆ̀€'), + (0x1FEE, '3', ' ̀ˆ̀'), + (0x1FEF, '3', '`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', 'ὼι'), + (0x1FF3, 'M', 'ωι'), + (0x1FF4, 'M', 'Ïι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + ] + +def _seg_21() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FF7, 'M', 'ῶι'), + (0x1FF8, 'M', 'ὸ'), + (0x1FF9, 'M', 'ÏŒ'), + (0x1FFA, 'M', 'á½¼'), + (0x1FFB, 'M', 'Ï'), + (0x1FFC, 'M', 'ωι'), + (0x1FFD, '3', ' ̀'), + (0x1FFE, '3', ' ̀”'), + (0x1FFF, 'X'), + (0x2000, '3', ' '), + (0x200B, 'I'), + (0x200C, 'D', ''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', 'â€'), + (0x2012, 'V'), + (0x2017, '3', ' ̀³'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', ' '), + (0x2030, 'V'), + (0x2033, 'M', '′′'), + (0x2034, 'M', '′′′'), + (0x2035, 'V'), + (0x2036, 'M', '‵‵'), + (0x2037, 'M', '‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', '!!'), + (0x203D, 'V'), + (0x203E, '3', ' ̀…'), + (0x203F, 'V'), + (0x2047, '3', '??'), + (0x2048, '3', '?!'), + (0x2049, '3', '!?'), + (0x204A, 'V'), + (0x2057, 'M', '′′′′'), + (0x2058, 'V'), + (0x205F, '3', ' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', '0'), + (0x2071, 'M', 'i'), + (0x2072, 'X'), + (0x2074, 'M', '4'), + (0x2075, 'M', '5'), + (0x2076, 'M', '6'), + (0x2077, 'M', '7'), + (0x2078, 'M', '8'), + (0x2079, 'M', '9'), + (0x207A, '3', '+'), + (0x207B, 'M', '−'), + (0x207C, '3', '='), + (0x207D, '3', '('), + (0x207E, '3', ')'), + (0x207F, 'M', 'n'), + (0x2080, 'M', '0'), + (0x2081, 'M', '1'), + (0x2082, 'M', '2'), + (0x2083, 'M', '3'), + (0x2084, 'M', '4'), + (0x2085, 'M', '5'), + (0x2086, 'M', '6'), + (0x2087, 'M', '7'), + (0x2088, 'M', '8'), + (0x2089, 'M', '9'), + (0x208A, '3', '+'), + (0x208B, 'M', '−'), + (0x208C, '3', '='), + (0x208D, '3', '('), + (0x208E, '3', ')'), + (0x208F, 'X'), + (0x2090, 'M', 'a'), + (0x2091, 'M', 'e'), + (0x2092, 'M', 'o'), + (0x2093, 'M', 'x'), + (0x2094, 'M', 'É™'), + (0x2095, 'M', 'h'), + (0x2096, 'M', 'k'), + (0x2097, 'M', 'l'), + (0x2098, 'M', 'm'), + (0x2099, 'M', 'n'), + (0x209A, 'M', 'p'), + (0x209B, 'M', 's'), + (0x209C, 'M', 't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', 'rs'), + (0x20A9, 'V'), + (0x20C1, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', 'a/c'), + (0x2101, '3', 'a/s'), + (0x2102, 'M', 'c'), + (0x2103, 'M', '°c'), + (0x2104, 'V'), + ] + +def _seg_22() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2105, '3', 'c/o'), + (0x2106, '3', 'c/u'), + (0x2107, 'M', 'É›'), + (0x2108, 'V'), + (0x2109, 'M', '°f'), + (0x210A, 'M', 'g'), + (0x210B, 'M', 'h'), + (0x210F, 'M', 'ħ'), + (0x2110, 'M', 'i'), + (0x2112, 'M', 'l'), + (0x2114, 'V'), + (0x2115, 'M', 'n'), + (0x2116, 'M', 'no'), + (0x2117, 'V'), + (0x2119, 'M', 'p'), + (0x211A, 'M', 'q'), + (0x211B, 'M', 'r'), + (0x211E, 'V'), + (0x2120, 'M', 'sm'), + (0x2121, 'M', 'tel'), + (0x2122, 'M', 'tm'), + (0x2123, 'V'), + (0x2124, 'M', 'z'), + (0x2125, 'V'), + (0x2126, 'M', 'ω'), + (0x2127, 'V'), + (0x2128, 'M', 'z'), + (0x2129, 'V'), + (0x212A, 'M', 'k'), + (0x212B, 'M', 'Ă¥'), + (0x212C, 'M', 'b'), + (0x212D, 'M', 'c'), + (0x212E, 'V'), + (0x212F, 'M', 'e'), + (0x2131, 'M', 'f'), + (0x2132, 'X'), + (0x2133, 'M', 'm'), + (0x2134, 'M', 'o'), + (0x2135, 'M', '×'), + (0x2136, 'M', 'ב'), + (0x2137, 'M', '×’'), + (0x2138, 'M', 'ד'), + (0x2139, 'M', 'i'), + (0x213A, 'V'), + (0x213B, 'M', 'fax'), + (0x213C, 'M', 'Ï€'), + (0x213D, 'M', 'γ'), + (0x213F, 'M', 'Ï€'), + (0x2140, 'M', '∑'), + (0x2141, 'V'), + (0x2145, 'M', 'd'), + (0x2147, 'M', 'e'), + (0x2148, 'M', 'i'), + (0x2149, 'M', 'j'), + (0x214A, 'V'), + (0x2150, 'M', '1â„7'), + (0x2151, 'M', '1â„9'), + (0x2152, 'M', '1â„10'), + (0x2153, 'M', '1â„3'), + (0x2154, 'M', '2â„3'), + (0x2155, 'M', '1â„5'), + (0x2156, 'M', '2â„5'), + (0x2157, 'M', '3â„5'), + (0x2158, 'M', '4â„5'), + (0x2159, 'M', '1â„6'), + (0x215A, 'M', '5â„6'), + (0x215B, 'M', '1â„8'), + (0x215C, 'M', '3â„8'), + (0x215D, 'M', '5â„8'), + (0x215E, 'M', '7â„8'), + (0x215F, 'M', '1â„'), + (0x2160, 'M', 'i'), + (0x2161, 'M', 'ii'), + (0x2162, 'M', 'iii'), + (0x2163, 'M', 'iv'), + (0x2164, 'M', 'v'), + (0x2165, 'M', 'vi'), + (0x2166, 'M', 'vii'), + (0x2167, 'M', 'viii'), + (0x2168, 'M', 'ix'), + (0x2169, 'M', 'x'), + (0x216A, 'M', 'xi'), + (0x216B, 'M', 'xii'), + (0x216C, 'M', 'l'), + (0x216D, 'M', 'c'), + (0x216E, 'M', 'd'), + (0x216F, 'M', 'm'), + (0x2170, 'M', 'i'), + (0x2171, 'M', 'ii'), + (0x2172, 'M', 'iii'), + (0x2173, 'M', 'iv'), + (0x2174, 'M', 'v'), + (0x2175, 'M', 'vi'), + (0x2176, 'M', 'vii'), + (0x2177, 'M', 'viii'), + (0x2178, 'M', 'ix'), + (0x2179, 'M', 'x'), + (0x217A, 'M', 'xi'), + (0x217B, 'M', 'xii'), + (0x217C, 'M', 'l'), + ] + +def _seg_23() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x217D, 'M', 'c'), + (0x217E, 'M', 'd'), + (0x217F, 'M', 'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', '0â„3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', '∫∫'), + (0x222D, 'M', '∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', '∮∮'), + (0x2230, 'M', '∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', 'ă€ˆ'), + (0x232A, 'M', '〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', '1'), + (0x2461, 'M', '2'), + (0x2462, 'M', '3'), + (0x2463, 'M', '4'), + (0x2464, 'M', '5'), + (0x2465, 'M', '6'), + (0x2466, 'M', '7'), + (0x2467, 'M', '8'), + (0x2468, 'M', '9'), + (0x2469, 'M', '10'), + (0x246A, 'M', '11'), + (0x246B, 'M', '12'), + (0x246C, 'M', '13'), + (0x246D, 'M', '14'), + (0x246E, 'M', '15'), + (0x246F, 'M', '16'), + (0x2470, 'M', '17'), + (0x2471, 'M', '18'), + (0x2472, 'M', '19'), + (0x2473, 'M', '20'), + (0x2474, '3', '(1)'), + (0x2475, '3', '(2)'), + (0x2476, '3', '(3)'), + (0x2477, '3', '(4)'), + (0x2478, '3', '(5)'), + (0x2479, '3', '(6)'), + (0x247A, '3', '(7)'), + (0x247B, '3', '(8)'), + (0x247C, '3', '(9)'), + (0x247D, '3', '(10)'), + (0x247E, '3', '(11)'), + (0x247F, '3', '(12)'), + (0x2480, '3', '(13)'), + (0x2481, '3', '(14)'), + (0x2482, '3', '(15)'), + (0x2483, '3', '(16)'), + (0x2484, '3', '(17)'), + (0x2485, '3', '(18)'), + (0x2486, '3', '(19)'), + (0x2487, '3', '(20)'), + (0x2488, 'X'), + (0x249C, '3', '(a)'), + (0x249D, '3', '(b)'), + (0x249E, '3', '(c)'), + (0x249F, '3', '(d)'), + (0x24A0, '3', '(e)'), + (0x24A1, '3', '(f)'), + (0x24A2, '3', '(g)'), + (0x24A3, '3', '(h)'), + (0x24A4, '3', '(i)'), + (0x24A5, '3', '(j)'), + (0x24A6, '3', '(k)'), + (0x24A7, '3', '(l)'), + (0x24A8, '3', '(m)'), + (0x24A9, '3', '(n)'), + (0x24AA, '3', '(o)'), + (0x24AB, '3', '(p)'), + (0x24AC, '3', '(q)'), + (0x24AD, '3', '(r)'), + (0x24AE, '3', '(s)'), + (0x24AF, '3', '(t)'), + (0x24B0, '3', '(u)'), + (0x24B1, '3', '(v)'), + (0x24B2, '3', '(w)'), + (0x24B3, '3', '(x)'), + (0x24B4, '3', '(y)'), + (0x24B5, '3', '(z)'), + (0x24B6, 'M', 'a'), + (0x24B7, 'M', 'b'), + (0x24B8, 'M', 'c'), + (0x24B9, 'M', 'd'), + (0x24BA, 'M', 'e'), + (0x24BB, 'M', 'f'), + (0x24BC, 'M', 'g'), + ] + +def _seg_24() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x24BD, 'M', 'h'), + (0x24BE, 'M', 'i'), + (0x24BF, 'M', 'j'), + (0x24C0, 'M', 'k'), + (0x24C1, 'M', 'l'), + (0x24C2, 'M', 'm'), + (0x24C3, 'M', 'n'), + (0x24C4, 'M', 'o'), + (0x24C5, 'M', 'p'), + (0x24C6, 'M', 'q'), + (0x24C7, 'M', 'r'), + (0x24C8, 'M', 's'), + (0x24C9, 'M', 't'), + (0x24CA, 'M', 'u'), + (0x24CB, 'M', 'v'), + (0x24CC, 'M', 'w'), + (0x24CD, 'M', 'x'), + (0x24CE, 'M', 'y'), + (0x24CF, 'M', 'z'), + (0x24D0, 'M', 'a'), + (0x24D1, 'M', 'b'), + (0x24D2, 'M', 'c'), + (0x24D3, 'M', 'd'), + (0x24D4, 'M', 'e'), + (0x24D5, 'M', 'f'), + (0x24D6, 'M', 'g'), + (0x24D7, 'M', 'h'), + (0x24D8, 'M', 'i'), + (0x24D9, 'M', 'j'), + (0x24DA, 'M', 'k'), + (0x24DB, 'M', 'l'), + (0x24DC, 'M', 'm'), + (0x24DD, 'M', 'n'), + (0x24DE, 'M', 'o'), + (0x24DF, 'M', 'p'), + (0x24E0, 'M', 'q'), + (0x24E1, 'M', 'r'), + (0x24E2, 'M', 's'), + (0x24E3, 'M', 't'), + (0x24E4, 'M', 'u'), + (0x24E5, 'M', 'v'), + (0x24E6, 'M', 'w'), + (0x24E7, 'M', 'x'), + (0x24E8, 'M', 'y'), + (0x24E9, 'M', 'z'), + (0x24EA, 'M', '0'), + (0x24EB, 'V'), + (0x2A0C, 'M', '∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', '::='), + (0x2A75, '3', '=='), + (0x2A76, '3', '==='), + (0x2A77, 'V'), + (0x2ADC, 'M', 'â«̀¸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B97, 'V'), + (0x2C00, 'M', 'â°°'), + (0x2C01, 'M', 'â°±'), + (0x2C02, 'M', 'â°²'), + (0x2C03, 'M', 'â°³'), + (0x2C04, 'M', 'â°´'), + (0x2C05, 'M', 'â°µ'), + (0x2C06, 'M', 'â°¶'), + (0x2C07, 'M', 'â°·'), + (0x2C08, 'M', 'â°¸'), + (0x2C09, 'M', 'â°¹'), + (0x2C0A, 'M', 'â°º'), + (0x2C0B, 'M', 'â°»'), + (0x2C0C, 'M', 'â°¼'), + (0x2C0D, 'M', 'â°½'), + (0x2C0E, 'M', 'â°¾'), + (0x2C0F, 'M', 'â°¿'), + (0x2C10, 'M', 'â±€'), + (0x2C11, 'M', 'â±'), + (0x2C12, 'M', 'ⱂ'), + (0x2C13, 'M', 'ⱃ'), + (0x2C14, 'M', 'ⱄ'), + (0x2C15, 'M', 'â±…'), + (0x2C16, 'M', 'ⱆ'), + (0x2C17, 'M', 'ⱇ'), + (0x2C18, 'M', 'ⱈ'), + (0x2C19, 'M', 'ⱉ'), + (0x2C1A, 'M', 'â±'), + (0x2C1B, 'M', 'ⱋ'), + (0x2C1C, 'M', 'ⱌ'), + (0x2C1D, 'M', 'â±'), + (0x2C1E, 'M', 'â±'), + (0x2C1F, 'M', 'â±'), + (0x2C20, 'M', 'â±'), + (0x2C21, 'M', 'ⱑ'), + (0x2C22, 'M', 'â±’'), + (0x2C23, 'M', 'ⱓ'), + (0x2C24, 'M', 'â±”'), + (0x2C25, 'M', 'ⱕ'), + (0x2C26, 'M', 'â±–'), + (0x2C27, 'M', 'â±—'), + (0x2C28, 'M', 'ⱘ'), + ] + +def _seg_25() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2C29, 'M', 'â±™'), + (0x2C2A, 'M', 'â±'), + (0x2C2B, 'M', 'â±›'), + (0x2C2C, 'M', 'ⱜ'), + (0x2C2D, 'M', 'â±'), + (0x2C2E, 'M', 'â±'), + (0x2C2F, 'M', 'ⱟ'), + (0x2C30, 'V'), + (0x2C60, 'M', 'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', 'É«'), + (0x2C63, 'M', 'áµ½'), + (0x2C64, 'M', 'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', 'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', 'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', 'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', 'É‘'), + (0x2C6E, 'M', 'ɱ'), + (0x2C6F, 'M', 'É'), + (0x2C70, 'M', 'É’'), + (0x2C71, 'V'), + (0x2C72, 'M', 'â±³'), + (0x2C73, 'V'), + (0x2C75, 'M', 'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', 'j'), + (0x2C7D, 'M', 'v'), + (0x2C7E, 'M', 'È¿'), + (0x2C7F, 'M', 'É€'), + (0x2C80, 'M', 'â²'), + (0x2C81, 'V'), + (0x2C82, 'M', 'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', 'â²…'), + (0x2C85, 'V'), + (0x2C86, 'M', 'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', 'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', 'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', 'â²'), + (0x2C8D, 'V'), + (0x2C8E, 'M', 'â²'), + (0x2C8F, 'V'), + (0x2C90, 'M', 'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', 'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', 'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', 'â²—'), + (0x2C97, 'V'), + (0x2C98, 'M', 'â²™'), + (0x2C99, 'V'), + (0x2C9A, 'M', 'â²›'), + (0x2C9B, 'V'), + (0x2C9C, 'M', 'â²'), + (0x2C9D, 'V'), + (0x2C9E, 'M', 'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', 'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', 'â²£'), + (0x2CA3, 'V'), + (0x2CA4, 'M', 'â²¥'), + (0x2CA5, 'V'), + (0x2CA6, 'M', 'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', 'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', 'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', 'â²­'), + (0x2CAD, 'V'), + (0x2CAE, 'M', 'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', 'â²±'), + (0x2CB1, 'V'), + (0x2CB2, 'M', 'â²³'), + (0x2CB3, 'V'), + (0x2CB4, 'M', 'â²µ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', 'â²·'), + (0x2CB7, 'V'), + (0x2CB8, 'M', 'â²¹'), + (0x2CB9, 'V'), + (0x2CBA, 'M', 'â²»'), + (0x2CBB, 'V'), + (0x2CBC, 'M', 'â²½'), + (0x2CBD, 'V'), + (0x2CBE, 'M', 'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', 'â³'), + (0x2CC1, 'V'), + (0x2CC2, 'M', 'ⳃ'), + ] + +def _seg_26() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2CC3, 'V'), + (0x2CC4, 'M', 'â³…'), + (0x2CC5, 'V'), + (0x2CC6, 'M', 'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', 'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', 'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', 'â³'), + (0x2CCD, 'V'), + (0x2CCE, 'M', 'â³'), + (0x2CCF, 'V'), + (0x2CD0, 'M', 'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', 'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', 'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', 'â³—'), + (0x2CD7, 'V'), + (0x2CD8, 'M', 'â³™'), + (0x2CD9, 'V'), + (0x2CDA, 'M', 'â³›'), + (0x2CDB, 'V'), + (0x2CDC, 'M', 'â³'), + (0x2CDD, 'V'), + (0x2CDE, 'M', 'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', 'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', 'â³£'), + (0x2CE3, 'V'), + (0x2CEB, 'M', 'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', 'â³®'), + (0x2CEE, 'V'), + (0x2CF2, 'M', 'â³³'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', 'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E5E, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', 'æ¯'), + (0x2EA0, 'V'), + (0x2EF3, 'M', '龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', '一'), + (0x2F01, 'M', '丨'), + (0x2F02, 'M', '丶'), + (0x2F03, 'M', '丿'), + (0x2F04, 'M', 'ä¹™'), + (0x2F05, 'M', '亅'), + (0x2F06, 'M', '二'), + (0x2F07, 'M', '亠'), + (0x2F08, 'M', '人'), + (0x2F09, 'M', 'å„¿'), + (0x2F0A, 'M', 'å…¥'), + (0x2F0B, 'M', 'å…«'), + (0x2F0C, 'M', '冂'), + (0x2F0D, 'M', '冖'), + (0x2F0E, 'M', '冫'), + (0x2F0F, 'M', '几'), + (0x2F10, 'M', '凵'), + (0x2F11, 'M', '刀'), + (0x2F12, 'M', 'å›'), + (0x2F13, 'M', '勹'), + (0x2F14, 'M', '匕'), + (0x2F15, 'M', 'åŒ'), + ] + +def _seg_27() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F16, 'M', '匸'), + (0x2F17, 'M', 'å'), + (0x2F18, 'M', 'åœ'), + (0x2F19, 'M', 'å©'), + (0x2F1A, 'M', 'å‚'), + (0x2F1B, 'M', 'å¶'), + (0x2F1C, 'M', 'åˆ'), + (0x2F1D, 'M', 'å£'), + (0x2F1E, 'M', 'å›—'), + (0x2F1F, 'M', '土'), + (0x2F20, 'M', '士'), + (0x2F21, 'M', '夂'), + (0x2F22, 'M', 'å¤'), + (0x2F23, 'M', '夕'), + (0x2F24, 'M', '大'), + (0x2F25, 'M', '女'), + (0x2F26, 'M', 'å­'), + (0x2F27, 'M', '宀'), + (0x2F28, 'M', '寸'), + (0x2F29, 'M', 'å°'), + (0x2F2A, 'M', 'å°¢'), + (0x2F2B, 'M', 'å°¸'), + (0x2F2C, 'M', 'å±®'), + (0x2F2D, 'M', 'å±±'), + (0x2F2E, 'M', 'å·›'), + (0x2F2F, 'M', 'å·¥'), + (0x2F30, 'M', 'å·±'), + (0x2F31, 'M', 'å·¾'), + (0x2F32, 'M', 'å¹²'), + (0x2F33, 'M', '幺'), + (0x2F34, 'M', '广'), + (0x2F35, 'M', 'å»´'), + (0x2F36, 'M', '廾'), + (0x2F37, 'M', '弋'), + (0x2F38, 'M', '弓'), + (0x2F39, 'M', 'å½'), + (0x2F3A, 'M', '彡'), + (0x2F3B, 'M', 'å½³'), + (0x2F3C, 'M', '心'), + (0x2F3D, 'M', '戈'), + (0x2F3E, 'M', '戶'), + (0x2F3F, 'M', '手'), + (0x2F40, 'M', '支'), + (0x2F41, 'M', 'æ”´'), + (0x2F42, 'M', 'æ–‡'), + (0x2F43, 'M', 'æ–—'), + (0x2F44, 'M', 'æ–¤'), + (0x2F45, 'M', 'æ–¹'), + (0x2F46, 'M', 'æ— '), + (0x2F47, 'M', 'æ—¥'), + (0x2F48, 'M', 'æ›°'), + (0x2F49, 'M', '月'), + (0x2F4A, 'M', '木'), + (0x2F4B, 'M', '欠'), + (0x2F4C, 'M', 'æ­¢'), + (0x2F4D, 'M', 'æ­¹'), + (0x2F4E, 'M', '殳'), + (0x2F4F, 'M', '毋'), + (0x2F50, 'M', '比'), + (0x2F51, 'M', '毛'), + (0x2F52, 'M', 'æ°'), + (0x2F53, 'M', 'æ°”'), + (0x2F54, 'M', 'æ°´'), + (0x2F55, 'M', 'ç«'), + (0x2F56, 'M', '爪'), + (0x2F57, 'M', '父'), + (0x2F58, 'M', '爻'), + (0x2F59, 'M', '爿'), + (0x2F5A, 'M', '片'), + (0x2F5B, 'M', '牙'), + (0x2F5C, 'M', '牛'), + (0x2F5D, 'M', 'ç¬'), + (0x2F5E, 'M', 'ç„'), + (0x2F5F, 'M', 'ç‰'), + (0x2F60, 'M', 'ç“œ'), + (0x2F61, 'M', '瓦'), + (0x2F62, 'M', '甘'), + (0x2F63, 'M', '生'), + (0x2F64, 'M', '用'), + (0x2F65, 'M', 'ç”°'), + (0x2F66, 'M', 'ç–‹'), + (0x2F67, 'M', 'ç–’'), + (0x2F68, 'M', '癶'), + (0x2F69, 'M', '白'), + (0x2F6A, 'M', 'ç®'), + (0x2F6B, 'M', 'ç¿'), + (0x2F6C, 'M', 'ç›®'), + (0x2F6D, 'M', '矛'), + (0x2F6E, 'M', '矢'), + (0x2F6F, 'M', '石'), + (0x2F70, 'M', '示'), + (0x2F71, 'M', '禸'), + (0x2F72, 'M', '禾'), + (0x2F73, 'M', 'ç©´'), + (0x2F74, 'M', 'ç«‹'), + (0x2F75, 'M', '竹'), + (0x2F76, 'M', 'ç±³'), + (0x2F77, 'M', '糸'), + (0x2F78, 'M', '缶'), + (0x2F79, 'M', '网'), + ] + +def _seg_28() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F7A, 'M', 'ç¾'), + (0x2F7B, 'M', 'ç¾½'), + (0x2F7C, 'M', 'è€'), + (0x2F7D, 'M', '而'), + (0x2F7E, 'M', '耒'), + (0x2F7F, 'M', '耳'), + (0x2F80, 'M', 'è¿'), + (0x2F81, 'M', '肉'), + (0x2F82, 'M', '臣'), + (0x2F83, 'M', '自'), + (0x2F84, 'M', '至'), + (0x2F85, 'M', '臼'), + (0x2F86, 'M', '舌'), + (0x2F87, 'M', '舛'), + (0x2F88, 'M', '舟'), + (0x2F89, 'M', '艮'), + (0x2F8A, 'M', '色'), + (0x2F8B, 'M', '艸'), + (0x2F8C, 'M', 'è™'), + (0x2F8D, 'M', '虫'), + (0x2F8E, 'M', 'è¡€'), + (0x2F8F, 'M', 'è¡Œ'), + (0x2F90, 'M', 'è¡£'), + (0x2F91, 'M', '襾'), + (0x2F92, 'M', '見'), + (0x2F93, 'M', '角'), + (0x2F94, 'M', '言'), + (0x2F95, 'M', 'è°·'), + (0x2F96, 'M', '豆'), + (0x2F97, 'M', '豕'), + (0x2F98, 'M', '豸'), + (0x2F99, 'M', 'è²'), + (0x2F9A, 'M', '赤'), + (0x2F9B, 'M', 'èµ°'), + (0x2F9C, 'M', '足'), + (0x2F9D, 'M', '身'), + (0x2F9E, 'M', 'è»'), + (0x2F9F, 'M', 'è¾›'), + (0x2FA0, 'M', 'è¾°'), + (0x2FA1, 'M', 'è¾µ'), + (0x2FA2, 'M', 'é‚‘'), + (0x2FA3, 'M', 'é…‰'), + (0x2FA4, 'M', '釆'), + (0x2FA5, 'M', '里'), + (0x2FA6, 'M', '金'), + (0x2FA7, 'M', 'é•·'), + (0x2FA8, 'M', 'é–€'), + (0x2FA9, 'M', '阜'), + (0x2FAA, 'M', 'é¶'), + (0x2FAB, 'M', 'é¹'), + (0x2FAC, 'M', '雨'), + (0x2FAD, 'M', 'é‘'), + (0x2FAE, 'M', 'é'), + (0x2FAF, 'M', 'é¢'), + (0x2FB0, 'M', 'é©'), + (0x2FB1, 'M', '韋'), + (0x2FB2, 'M', '韭'), + (0x2FB3, 'M', '音'), + (0x2FB4, 'M', 'é '), + (0x2FB5, 'M', '風'), + (0x2FB6, 'M', '飛'), + (0x2FB7, 'M', '食'), + (0x2FB8, 'M', '首'), + (0x2FB9, 'M', '香'), + (0x2FBA, 'M', '馬'), + (0x2FBB, 'M', '骨'), + (0x2FBC, 'M', '高'), + (0x2FBD, 'M', 'é«Ÿ'), + (0x2FBE, 'M', '鬥'), + (0x2FBF, 'M', '鬯'), + (0x2FC0, 'M', '鬲'), + (0x2FC1, 'M', '鬼'), + (0x2FC2, 'M', 'é­'), + (0x2FC3, 'M', 'é³¥'), + (0x2FC4, 'M', 'é¹µ'), + (0x2FC5, 'M', '鹿'), + (0x2FC6, 'M', '麥'), + (0x2FC7, 'M', '麻'), + (0x2FC8, 'M', '黃'), + (0x2FC9, 'M', 'é»'), + (0x2FCA, 'M', '黑'), + (0x2FCB, 'M', '黹'), + (0x2FCC, 'M', '黽'), + (0x2FCD, 'M', 'é¼'), + (0x2FCE, 'M', '鼓'), + (0x2FCF, 'M', 'é¼ '), + (0x2FD0, 'M', 'é¼»'), + (0x2FD1, 'M', 'é½'), + (0x2FD2, 'M', 'é½’'), + (0x2FD3, 'M', 'é¾'), + (0x2FD4, 'M', '龜'), + (0x2FD5, 'M', 'é¾ '), + (0x2FD6, 'X'), + (0x3000, '3', ' '), + (0x3001, 'V'), + (0x3002, 'M', '.'), + (0x3003, 'V'), + (0x3036, 'M', '〒'), + (0x3037, 'V'), + (0x3038, 'M', 'å'), + ] + +def _seg_29() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3039, 'M', 'å„'), + (0x303A, 'M', 'å…'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', ' ă‚™'), + (0x309C, '3', ' ă‚'), + (0x309D, 'V'), + (0x309F, 'M', 'ă‚ˆă‚'), + (0x30A0, 'V'), + (0x30FF, 'M', 'ă‚³ăƒˆ'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x3130, 'X'), + (0x3131, 'M', 'á„€'), + (0x3132, 'M', 'á„'), + (0x3133, 'M', 'ᆪ'), + (0x3134, 'M', 'á„‚'), + (0x3135, 'M', 'ᆬ'), + (0x3136, 'M', 'ᆭ'), + (0x3137, 'M', 'ᄃ'), + (0x3138, 'M', 'á„„'), + (0x3139, 'M', 'á„…'), + (0x313A, 'M', 'ᆰ'), + (0x313B, 'M', 'ᆱ'), + (0x313C, 'M', 'ᆲ'), + (0x313D, 'M', 'ᆳ'), + (0x313E, 'M', 'ᆴ'), + (0x313F, 'M', 'ᆵ'), + (0x3140, 'M', 'á„'), + (0x3141, 'M', 'ᄆ'), + (0x3142, 'M', 'ᄇ'), + (0x3143, 'M', 'ᄈ'), + (0x3144, 'M', 'á„¡'), + (0x3145, 'M', 'ᄉ'), + (0x3146, 'M', 'á„'), + (0x3147, 'M', 'á„‹'), + (0x3148, 'M', 'á„Œ'), + (0x3149, 'M', 'á„'), + (0x314A, 'M', 'á„'), + (0x314B, 'M', 'á„'), + (0x314C, 'M', 'á„'), + (0x314D, 'M', 'á„‘'), + (0x314E, 'M', 'á„’'), + (0x314F, 'M', 'á…¡'), + (0x3150, 'M', 'á…¢'), + (0x3151, 'M', 'á…£'), + (0x3152, 'M', 'á…¤'), + (0x3153, 'M', 'á…¥'), + (0x3154, 'M', 'á…¦'), + (0x3155, 'M', 'á…§'), + (0x3156, 'M', 'á…¨'), + (0x3157, 'M', 'á…©'), + (0x3158, 'M', 'á…ª'), + (0x3159, 'M', 'á…«'), + (0x315A, 'M', 'á…¬'), + (0x315B, 'M', 'á…­'), + (0x315C, 'M', 'á…®'), + (0x315D, 'M', 'á…¯'), + (0x315E, 'M', 'á…°'), + (0x315F, 'M', 'á…±'), + (0x3160, 'M', 'á…²'), + (0x3161, 'M', 'á…³'), + (0x3162, 'M', 'á…´'), + (0x3163, 'M', 'á…µ'), + (0x3164, 'X'), + (0x3165, 'M', 'á„”'), + (0x3166, 'M', 'á„•'), + (0x3167, 'M', 'ᇇ'), + (0x3168, 'M', 'ᇈ'), + (0x3169, 'M', 'ᇌ'), + (0x316A, 'M', 'á‡'), + (0x316B, 'M', 'ᇓ'), + (0x316C, 'M', 'ᇗ'), + (0x316D, 'M', 'ᇙ'), + (0x316E, 'M', 'á„œ'), + (0x316F, 'M', 'á‡'), + (0x3170, 'M', 'ᇟ'), + (0x3171, 'M', 'á„'), + (0x3172, 'M', 'á„'), + (0x3173, 'M', 'á„ '), + (0x3174, 'M', 'á„¢'), + (0x3175, 'M', 'á„£'), + (0x3176, 'M', 'ᄧ'), + (0x3177, 'M', 'á„©'), + (0x3178, 'M', 'á„«'), + (0x3179, 'M', 'ᄬ'), + (0x317A, 'M', 'á„­'), + (0x317B, 'M', 'á„®'), + (0x317C, 'M', 'ᄯ'), + (0x317D, 'M', 'ᄲ'), + (0x317E, 'M', 'ᄶ'), + (0x317F, 'M', 'á…€'), + (0x3180, 'M', 'á…‡'), + (0x3181, 'M', 'á…Œ'), + (0x3182, 'M', 'ᇱ'), + (0x3183, 'M', 'ᇲ'), + (0x3184, 'M', 'á…—'), + ] + +def _seg_30() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3185, 'M', 'á…˜'), + (0x3186, 'M', 'á…™'), + (0x3187, 'M', 'ᆄ'), + (0x3188, 'M', 'ᆅ'), + (0x3189, 'M', 'ᆈ'), + (0x318A, 'M', 'ᆑ'), + (0x318B, 'M', 'ᆒ'), + (0x318C, 'M', 'ᆔ'), + (0x318D, 'M', 'á†'), + (0x318E, 'M', 'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', '一'), + (0x3193, 'M', '二'), + (0x3194, 'M', '三'), + (0x3195, 'M', 'å››'), + (0x3196, 'M', 'ä¸'), + (0x3197, 'M', '中'), + (0x3198, 'M', '下'), + (0x3199, 'M', '甲'), + (0x319A, 'M', 'ä¹™'), + (0x319B, 'M', '丙'), + (0x319C, 'M', 'ä¸'), + (0x319D, 'M', '天'), + (0x319E, 'M', '地'), + (0x319F, 'M', '人'), + (0x31A0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', '(á„€)'), + (0x3201, '3', '(á„‚)'), + (0x3202, '3', '(ᄃ)'), + (0x3203, '3', '(á„…)'), + (0x3204, '3', '(ᄆ)'), + (0x3205, '3', '(ᄇ)'), + (0x3206, '3', '(ᄉ)'), + (0x3207, '3', '(á„‹)'), + (0x3208, '3', '(á„Œ)'), + (0x3209, '3', '(á„)'), + (0x320A, '3', '(á„)'), + (0x320B, '3', '(á„)'), + (0x320C, '3', '(á„‘)'), + (0x320D, '3', '(á„’)'), + (0x320E, '3', '(ê°€)'), + (0x320F, '3', '(나)'), + (0x3210, '3', '(다)'), + (0x3211, '3', '(ë¼)'), + (0x3212, '3', '(마)'), + (0x3213, '3', '(ë°”)'), + (0x3214, '3', '(́‚¬)'), + (0x3215, '3', '(́•„)'), + (0x3216, '3', '(́)'), + (0x3217, '3', '(́°¨)'), + (0x3218, '3', '(́¹´)'), + (0x3219, '3', '(타)'), + (0x321A, '3', '(파)'), + (0x321B, '3', '(하)'), + (0x321C, '3', '(́£¼)'), + (0x321D, '3', '(́˜¤́ „)'), + (0x321E, '3', '(́˜¤í›„)'), + (0x321F, 'X'), + (0x3220, '3', '(一)'), + (0x3221, '3', '(二)'), + (0x3222, '3', '(三)'), + (0x3223, '3', '(å››)'), + (0x3224, '3', '(五)'), + (0x3225, '3', '(å…­)'), + (0x3226, '3', '(七)'), + (0x3227, '3', '(å…«)'), + (0x3228, '3', '(ä¹)'), + (0x3229, '3', '(å)'), + (0x322A, '3', '(月)'), + (0x322B, '3', '(ç«)'), + (0x322C, '3', '(æ°´)'), + (0x322D, '3', '(木)'), + (0x322E, '3', '(金)'), + (0x322F, '3', '(土)'), + (0x3230, '3', '(æ—¥)'), + (0x3231, '3', '(æ ª)'), + (0x3232, '3', '(有)'), + (0x3233, '3', '(社)'), + (0x3234, '3', '(å)'), + (0x3235, '3', '(特)'), + (0x3236, '3', '(財)'), + (0x3237, '3', '(ç¥)'), + (0x3238, '3', '(å´)'), + (0x3239, '3', '(代)'), + (0x323A, '3', '(呼)'), + (0x323B, '3', '(å­¦)'), + (0x323C, '3', '(監)'), + (0x323D, '3', '(ä¼)'), + (0x323E, '3', '(資)'), + (0x323F, '3', '(å”)'), + (0x3240, '3', '(祭)'), + (0x3241, '3', '(休)'), + (0x3242, '3', '(自)'), + (0x3243, '3', '(至)'), + (0x3244, 'M', 'å•'), + (0x3245, 'M', 'å¹¼'), + (0x3246, 'M', 'æ–‡'), + ] + +def _seg_31() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3247, 'M', 'ç®'), + (0x3248, 'V'), + (0x3250, 'M', 'pte'), + (0x3251, 'M', '21'), + (0x3252, 'M', '22'), + (0x3253, 'M', '23'), + (0x3254, 'M', '24'), + (0x3255, 'M', '25'), + (0x3256, 'M', '26'), + (0x3257, 'M', '27'), + (0x3258, 'M', '28'), + (0x3259, 'M', '29'), + (0x325A, 'M', '30'), + (0x325B, 'M', '31'), + (0x325C, 'M', '32'), + (0x325D, 'M', '33'), + (0x325E, 'M', '34'), + (0x325F, 'M', '35'), + (0x3260, 'M', 'á„€'), + (0x3261, 'M', 'á„‚'), + (0x3262, 'M', 'ᄃ'), + (0x3263, 'M', 'á„…'), + (0x3264, 'M', 'ᄆ'), + (0x3265, 'M', 'ᄇ'), + (0x3266, 'M', 'ᄉ'), + (0x3267, 'M', 'á„‹'), + (0x3268, 'M', 'á„Œ'), + (0x3269, 'M', 'á„'), + (0x326A, 'M', 'á„'), + (0x326B, 'M', 'á„'), + (0x326C, 'M', 'á„‘'), + (0x326D, 'M', 'á„’'), + (0x326E, 'M', 'ê°€'), + (0x326F, 'M', '나'), + (0x3270, 'M', '다'), + (0x3271, 'M', 'ë¼'), + (0x3272, 'M', '마'), + (0x3273, 'M', 'ë°”'), + (0x3274, 'M', '́‚¬'), + (0x3275, 'M', '́•„'), + (0x3276, 'M', '́'), + (0x3277, 'M', '́°¨'), + (0x3278, 'M', '́¹´'), + (0x3279, 'M', '타'), + (0x327A, 'M', '파'), + (0x327B, 'M', '하'), + (0x327C, 'M', '́°¸ê³ '), + (0x327D, 'M', '́£¼́˜'), + (0x327E, 'M', '́°'), + (0x327F, 'V'), + (0x3280, 'M', '一'), + (0x3281, 'M', '二'), + (0x3282, 'M', '三'), + (0x3283, 'M', 'å››'), + (0x3284, 'M', '五'), + (0x3285, 'M', 'å…­'), + (0x3286, 'M', '七'), + (0x3287, 'M', 'å…«'), + (0x3288, 'M', 'ä¹'), + (0x3289, 'M', 'å'), + (0x328A, 'M', '月'), + (0x328B, 'M', 'ç«'), + (0x328C, 'M', 'æ°´'), + (0x328D, 'M', '木'), + (0x328E, 'M', '金'), + (0x328F, 'M', '土'), + (0x3290, 'M', 'æ—¥'), + (0x3291, 'M', 'æ ª'), + (0x3292, 'M', '有'), + (0x3293, 'M', '社'), + (0x3294, 'M', 'å'), + (0x3295, 'M', '特'), + (0x3296, 'M', '財'), + (0x3297, 'M', 'ç¥'), + (0x3298, 'M', 'å´'), + (0x3299, 'M', '秘'), + (0x329A, 'M', 'ç”·'), + (0x329B, 'M', '女'), + (0x329C, 'M', 'é©'), + (0x329D, 'M', '優'), + (0x329E, 'M', 'å°'), + (0x329F, 'M', '注'), + (0x32A0, 'M', 'é …'), + (0x32A1, 'M', '休'), + (0x32A2, 'M', '写'), + (0x32A3, 'M', 'æ­£'), + (0x32A4, 'M', 'ä¸'), + (0x32A5, 'M', '中'), + (0x32A6, 'M', '下'), + (0x32A7, 'M', 'å·¦'), + (0x32A8, 'M', 'å³'), + (0x32A9, 'M', '医'), + (0x32AA, 'M', 'å®—'), + (0x32AB, 'M', 'å­¦'), + (0x32AC, 'M', '監'), + (0x32AD, 'M', 'ä¼'), + (0x32AE, 'M', '資'), + (0x32AF, 'M', 'å”'), + (0x32B0, 'M', '夜'), + (0x32B1, 'M', '36'), + ] + +def _seg_32() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x32B2, 'M', '37'), + (0x32B3, 'M', '38'), + (0x32B4, 'M', '39'), + (0x32B5, 'M', '40'), + (0x32B6, 'M', '41'), + (0x32B7, 'M', '42'), + (0x32B8, 'M', '43'), + (0x32B9, 'M', '44'), + (0x32BA, 'M', '45'), + (0x32BB, 'M', '46'), + (0x32BC, 'M', '47'), + (0x32BD, 'M', '48'), + (0x32BE, 'M', '49'), + (0x32BF, 'M', '50'), + (0x32C0, 'M', '1月'), + (0x32C1, 'M', '2月'), + (0x32C2, 'M', '3月'), + (0x32C3, 'M', '4月'), + (0x32C4, 'M', '5月'), + (0x32C5, 'M', '6月'), + (0x32C6, 'M', '7月'), + (0x32C7, 'M', '8月'), + (0x32C8, 'M', '9月'), + (0x32C9, 'M', '10月'), + (0x32CA, 'M', '11月'), + (0x32CB, 'M', '12月'), + (0x32CC, 'M', 'hg'), + (0x32CD, 'M', 'erg'), + (0x32CE, 'M', 'ev'), + (0x32CF, 'M', 'ltd'), + (0x32D0, 'M', 'ă‚¢'), + (0x32D1, 'M', 'イ'), + (0x32D2, 'M', 'ウ'), + (0x32D3, 'M', 'エ'), + (0x32D4, 'M', 'ă‚ª'), + (0x32D5, 'M', 'ă‚«'), + (0x32D6, 'M', 'ă‚­'), + (0x32D7, 'M', 'ă‚¯'), + (0x32D8, 'M', 'ケ'), + (0x32D9, 'M', 'ă‚³'), + (0x32DA, 'M', 'サ'), + (0x32DB, 'M', 'ă‚·'), + (0x32DC, 'M', 'ă‚¹'), + (0x32DD, 'M', 'ă‚»'), + (0x32DE, 'M', 'ă‚½'), + (0x32DF, 'M', 'ă‚¿'), + (0x32E0, 'M', 'ăƒ'), + (0x32E1, 'M', 'ăƒ„'), + (0x32E2, 'M', 'ăƒ†'), + (0x32E3, 'M', 'ăƒˆ'), + (0x32E4, 'M', 'ăƒ'), + (0x32E5, 'M', 'ăƒ‹'), + (0x32E6, 'M', 'ăƒŒ'), + (0x32E7, 'M', 'ăƒ'), + (0x32E8, 'M', 'ăƒ'), + (0x32E9, 'M', 'ăƒ'), + (0x32EA, 'M', 'ăƒ’'), + (0x32EB, 'M', 'ăƒ•'), + (0x32EC, 'M', 'ăƒ˜'), + (0x32ED, 'M', 'ăƒ›'), + (0x32EE, 'M', 'ăƒ'), + (0x32EF, 'M', 'ăƒŸ'), + (0x32F0, 'M', 'ăƒ '), + (0x32F1, 'M', 'ăƒ¡'), + (0x32F2, 'M', 'ăƒ¢'), + (0x32F3, 'M', 'ăƒ¤'), + (0x32F4, 'M', 'ăƒ¦'), + (0x32F5, 'M', 'ăƒ¨'), + (0x32F6, 'M', 'ăƒ©'), + (0x32F7, 'M', 'ăƒª'), + (0x32F8, 'M', 'ăƒ«'), + (0x32F9, 'M', 'ăƒ¬'), + (0x32FA, 'M', 'ăƒ­'), + (0x32FB, 'M', 'ăƒ¯'), + (0x32FC, 'M', 'ăƒ°'), + (0x32FD, 'M', 'ăƒ±'), + (0x32FE, 'M', 'ăƒ²'), + (0x32FF, 'M', '令和'), + (0x3300, 'M', 'ă‚¢ăƒ‘ăƒ¼ăƒˆ'), + (0x3301, 'M', 'ă‚¢ăƒ«ăƒ•ă‚¡'), + (0x3302, 'M', 'ă‚¢ăƒ³ăƒă‚¢'), + (0x3303, 'M', 'ă‚¢ăƒ¼ăƒ«'), + (0x3304, 'M', 'ă‚¤ăƒ‹ăƒ³ă‚°'), + (0x3305, 'M', 'ă‚¤ăƒ³ăƒ'), + (0x3306, 'M', 'ă‚¦ă‚©ăƒ³'), + (0x3307, 'M', 'ă‚¨ă‚¹ă‚¯ăƒ¼ăƒ‰'), + (0x3308, 'M', 'ă‚¨ăƒ¼ă‚«ăƒ¼'), + (0x3309, 'M', 'ă‚ªăƒ³ă‚¹'), + (0x330A, 'M', 'ă‚ªăƒ¼ăƒ '), + (0x330B, 'M', 'ă‚«ă‚¤ăƒª'), + (0x330C, 'M', 'ă‚«ăƒ©ăƒƒăƒˆ'), + (0x330D, 'M', 'ă‚«ăƒ­ăƒªăƒ¼'), + (0x330E, 'M', 'ă‚¬ăƒ­ăƒ³'), + (0x330F, 'M', 'ă‚¬ăƒ³ăƒ'), + (0x3310, 'M', 'ギガ'), + (0x3311, 'M', 'ă‚®ăƒ‹ăƒ¼'), + (0x3312, 'M', 'ă‚­ăƒ¥ăƒªăƒ¼'), + (0x3313, 'M', 'ă‚®ăƒ«ăƒ€ăƒ¼'), + (0x3314, 'M', 'ă‚­ăƒ­'), + (0x3315, 'M', 'ă‚­ăƒ­ă‚°ăƒ©ăƒ '), + ] + +def _seg_33() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3316, 'M', 'ă‚­ăƒ­ăƒ¡ăƒ¼ăƒˆăƒ«'), + (0x3317, 'M', 'ă‚­ăƒ­ăƒ¯ăƒƒăƒˆ'), + (0x3318, 'M', 'ă‚°ăƒ©ăƒ '), + (0x3319, 'M', 'ă‚°ăƒ©ăƒ ăƒˆăƒ³'), + (0x331A, 'M', 'ă‚¯ăƒ«ă‚¼ă‚¤ăƒ­'), + (0x331B, 'M', 'ă‚¯ăƒ­ăƒ¼ăƒ'), + (0x331C, 'M', 'ă‚±ăƒ¼ă‚¹'), + (0x331D, 'M', 'ă‚³ăƒ«ăƒ'), + (0x331E, 'M', 'ă‚³ăƒ¼ăƒ'), + (0x331F, 'M', 'ă‚µă‚¤ă‚¯ăƒ«'), + (0x3320, 'M', 'ă‚µăƒ³ăƒăƒ¼ăƒ '), + (0x3321, 'M', 'ă‚·ăƒªăƒ³ă‚°'), + (0x3322, 'M', 'ă‚»ăƒ³ăƒ'), + (0x3323, 'M', 'ă‚»ăƒ³ăƒˆ'), + (0x3324, 'M', 'ăƒ€ăƒ¼ă‚¹'), + (0x3325, 'M', 'ăƒ‡ă‚·'), + (0x3326, 'M', 'ăƒ‰ăƒ«'), + (0x3327, 'M', 'ăƒˆăƒ³'), + (0x3328, 'M', 'ăƒăƒ'), + (0x3329, 'M', 'ăƒăƒƒăƒˆ'), + (0x332A, 'M', 'ăƒă‚¤ăƒ„'), + (0x332B, 'M', 'ăƒ‘ăƒ¼ă‚»ăƒ³ăƒˆ'), + (0x332C, 'M', 'ăƒ‘ăƒ¼ăƒ„'), + (0x332D, 'M', 'ăƒăƒ¼ăƒ¬ăƒ«'), + (0x332E, 'M', 'ăƒ”ă‚¢ă‚¹ăƒˆăƒ«'), + (0x332F, 'M', 'ăƒ”ă‚¯ăƒ«'), + (0x3330, 'M', 'ăƒ”ă‚³'), + (0x3331, 'M', 'ăƒ“ăƒ«'), + (0x3332, 'M', 'ăƒ•ă‚¡ăƒ©ăƒƒăƒ‰'), + (0x3333, 'M', 'ăƒ•ă‚£ăƒ¼ăƒˆ'), + (0x3334, 'M', 'ăƒ–ăƒƒă‚·ă‚§ăƒ«'), + (0x3335, 'M', 'ăƒ•ăƒ©ăƒ³'), + (0x3336, 'M', 'ăƒ˜ă‚¯ă‚¿ăƒ¼ăƒ«'), + (0x3337, 'M', 'ăƒă‚½'), + (0x3338, 'M', 'ăƒăƒ‹ăƒ’'), + (0x3339, 'M', 'ăƒ˜ăƒ«ăƒ„'), + (0x333A, 'M', 'ăƒăƒ³ă‚¹'), + (0x333B, 'M', 'ăƒăƒ¼ă‚¸'), + (0x333C, 'M', 'ăƒ™ăƒ¼ă‚¿'), + (0x333D, 'M', 'ăƒă‚¤ăƒ³ăƒˆ'), + (0x333E, 'M', 'ăƒœăƒ«ăƒˆ'), + (0x333F, 'M', 'ăƒ›ăƒ³'), + (0x3340, 'M', 'ăƒăƒ³ăƒ‰'), + (0x3341, 'M', 'ăƒ›ăƒ¼ăƒ«'), + (0x3342, 'M', 'ăƒ›ăƒ¼ăƒ³'), + (0x3343, 'M', 'ăƒă‚¤ă‚¯ăƒ­'), + (0x3344, 'M', 'ăƒă‚¤ăƒ«'), + (0x3345, 'M', 'ăƒăƒƒăƒ'), + (0x3346, 'M', 'ăƒăƒ«ă‚¯'), + (0x3347, 'M', 'ăƒăƒ³ă‚·ăƒ§ăƒ³'), + (0x3348, 'M', 'ăƒŸă‚¯ăƒ­ăƒ³'), + (0x3349, 'M', 'ăƒŸăƒª'), + (0x334A, 'M', 'ăƒŸăƒªăƒăƒ¼ăƒ«'), + (0x334B, 'M', 'ăƒ¡ă‚¬'), + (0x334C, 'M', 'ăƒ¡ă‚¬ăƒˆăƒ³'), + (0x334D, 'M', 'ăƒ¡ăƒ¼ăƒˆăƒ«'), + (0x334E, 'M', 'ăƒ¤ăƒ¼ăƒ‰'), + (0x334F, 'M', 'ăƒ¤ăƒ¼ăƒ«'), + (0x3350, 'M', 'ăƒ¦ă‚¢ăƒ³'), + (0x3351, 'M', 'ăƒªăƒƒăƒˆăƒ«'), + (0x3352, 'M', 'ăƒªăƒ©'), + (0x3353, 'M', 'ăƒ«ăƒ”ăƒ¼'), + (0x3354, 'M', 'ăƒ«ăƒ¼ăƒ–ăƒ«'), + (0x3355, 'M', 'ăƒ¬ăƒ '), + (0x3356, 'M', 'ăƒ¬ăƒ³ăƒˆă‚²ăƒ³'), + (0x3357, 'M', 'ăƒ¯ăƒƒăƒˆ'), + (0x3358, 'M', '0点'), + (0x3359, 'M', '1点'), + (0x335A, 'M', '2点'), + (0x335B, 'M', '3点'), + (0x335C, 'M', '4点'), + (0x335D, 'M', '5点'), + (0x335E, 'M', '6点'), + (0x335F, 'M', '7点'), + (0x3360, 'M', '8点'), + (0x3361, 'M', '9点'), + (0x3362, 'M', '10点'), + (0x3363, 'M', '11点'), + (0x3364, 'M', '12点'), + (0x3365, 'M', '13点'), + (0x3366, 'M', '14点'), + (0x3367, 'M', '15点'), + (0x3368, 'M', '16点'), + (0x3369, 'M', '17点'), + (0x336A, 'M', '18点'), + (0x336B, 'M', '19点'), + (0x336C, 'M', '20点'), + (0x336D, 'M', '21点'), + (0x336E, 'M', '22点'), + (0x336F, 'M', '23点'), + (0x3370, 'M', '24点'), + (0x3371, 'M', 'hpa'), + (0x3372, 'M', 'da'), + (0x3373, 'M', 'au'), + (0x3374, 'M', 'bar'), + (0x3375, 'M', 'ov'), + (0x3376, 'M', 'pc'), + (0x3377, 'M', 'dm'), + (0x3378, 'M', 'dm2'), + (0x3379, 'M', 'dm3'), + ] + +def _seg_34() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x337A, 'M', 'iu'), + (0x337B, 'M', 'å¹³æˆ'), + (0x337C, 'M', '昭和'), + (0x337D, 'M', '大正'), + (0x337E, 'M', 'æ˜æ²»'), + (0x337F, 'M', 'æ ªå¼ä¼ç¤¾'), + (0x3380, 'M', 'pa'), + (0x3381, 'M', 'na'), + (0x3382, 'M', 'μa'), + (0x3383, 'M', 'ma'), + (0x3384, 'M', 'ka'), + (0x3385, 'M', 'kb'), + (0x3386, 'M', 'mb'), + (0x3387, 'M', 'gb'), + (0x3388, 'M', 'cal'), + (0x3389, 'M', 'kcal'), + (0x338A, 'M', 'pf'), + (0x338B, 'M', 'nf'), + (0x338C, 'M', 'μf'), + (0x338D, 'M', 'μg'), + (0x338E, 'M', 'mg'), + (0x338F, 'M', 'kg'), + (0x3390, 'M', 'hz'), + (0x3391, 'M', 'khz'), + (0x3392, 'M', 'mhz'), + (0x3393, 'M', 'ghz'), + (0x3394, 'M', 'thz'), + (0x3395, 'M', 'μl'), + (0x3396, 'M', 'ml'), + (0x3397, 'M', 'dl'), + (0x3398, 'M', 'kl'), + (0x3399, 'M', 'fm'), + (0x339A, 'M', 'nm'), + (0x339B, 'M', 'μm'), + (0x339C, 'M', 'mm'), + (0x339D, 'M', 'cm'), + (0x339E, 'M', 'km'), + (0x339F, 'M', 'mm2'), + (0x33A0, 'M', 'cm2'), + (0x33A1, 'M', 'm2'), + (0x33A2, 'M', 'km2'), + (0x33A3, 'M', 'mm3'), + (0x33A4, 'M', 'cm3'), + (0x33A5, 'M', 'm3'), + (0x33A6, 'M', 'km3'), + (0x33A7, 'M', 'm∕s'), + (0x33A8, 'M', 'm∕s2'), + (0x33A9, 'M', 'pa'), + (0x33AA, 'M', 'kpa'), + (0x33AB, 'M', 'mpa'), + (0x33AC, 'M', 'gpa'), + (0x33AD, 'M', 'rad'), + (0x33AE, 'M', 'rad∕s'), + (0x33AF, 'M', 'rad∕s2'), + (0x33B0, 'M', 'ps'), + (0x33B1, 'M', 'ns'), + (0x33B2, 'M', 'μs'), + (0x33B3, 'M', 'ms'), + (0x33B4, 'M', 'pv'), + (0x33B5, 'M', 'nv'), + (0x33B6, 'M', 'μv'), + (0x33B7, 'M', 'mv'), + (0x33B8, 'M', 'kv'), + (0x33B9, 'M', 'mv'), + (0x33BA, 'M', 'pw'), + (0x33BB, 'M', 'nw'), + (0x33BC, 'M', 'μw'), + (0x33BD, 'M', 'mw'), + (0x33BE, 'M', 'kw'), + (0x33BF, 'M', 'mw'), + (0x33C0, 'M', 'kω'), + (0x33C1, 'M', 'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', 'bq'), + (0x33C4, 'M', 'cc'), + (0x33C5, 'M', 'cd'), + (0x33C6, 'M', 'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', 'db'), + (0x33C9, 'M', 'gy'), + (0x33CA, 'M', 'ha'), + (0x33CB, 'M', 'hp'), + (0x33CC, 'M', 'in'), + (0x33CD, 'M', 'kk'), + (0x33CE, 'M', 'km'), + (0x33CF, 'M', 'kt'), + (0x33D0, 'M', 'lm'), + (0x33D1, 'M', 'ln'), + (0x33D2, 'M', 'log'), + (0x33D3, 'M', 'lx'), + (0x33D4, 'M', 'mb'), + (0x33D5, 'M', 'mil'), + (0x33D6, 'M', 'mol'), + (0x33D7, 'M', 'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', 'ppm'), + (0x33DA, 'M', 'pr'), + (0x33DB, 'M', 'sr'), + (0x33DC, 'M', 'sv'), + (0x33DD, 'M', 'wb'), + ] + +def _seg_35() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x33DE, 'M', 'v∕m'), + (0x33DF, 'M', 'a∕m'), + (0x33E0, 'M', '1æ—¥'), + (0x33E1, 'M', '2æ—¥'), + (0x33E2, 'M', '3æ—¥'), + (0x33E3, 'M', '4æ—¥'), + (0x33E4, 'M', '5æ—¥'), + (0x33E5, 'M', '6æ—¥'), + (0x33E6, 'M', '7æ—¥'), + (0x33E7, 'M', '8æ—¥'), + (0x33E8, 'M', '9æ—¥'), + (0x33E9, 'M', '10æ—¥'), + (0x33EA, 'M', '11æ—¥'), + (0x33EB, 'M', '12æ—¥'), + (0x33EC, 'M', '13æ—¥'), + (0x33ED, 'M', '14æ—¥'), + (0x33EE, 'M', '15æ—¥'), + (0x33EF, 'M', '16æ—¥'), + (0x33F0, 'M', '17æ—¥'), + (0x33F1, 'M', '18æ—¥'), + (0x33F2, 'M', '19æ—¥'), + (0x33F3, 'M', '20æ—¥'), + (0x33F4, 'M', '21æ—¥'), + (0x33F5, 'M', '22æ—¥'), + (0x33F6, 'M', '23æ—¥'), + (0x33F7, 'M', '24æ—¥'), + (0x33F8, 'M', '25æ—¥'), + (0x33F9, 'M', '26æ—¥'), + (0x33FA, 'M', '27æ—¥'), + (0x33FB, 'M', '28æ—¥'), + (0x33FC, 'M', '29æ—¥'), + (0x33FD, 'M', '30æ—¥'), + (0x33FE, 'M', '31æ—¥'), + (0x33FF, 'M', 'gal'), + (0x3400, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', 'ê™'), + (0xA641, 'V'), + (0xA642, 'M', 'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', 'ê™…'), + (0xA645, 'V'), + (0xA646, 'M', 'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', 'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', 'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', 'ê™'), + (0xA64D, 'V'), + (0xA64E, 'M', 'ê™'), + (0xA64F, 'V'), + (0xA650, 'M', 'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', 'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', 'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', 'ê™—'), + (0xA657, 'V'), + (0xA658, 'M', 'ê™™'), + (0xA659, 'V'), + (0xA65A, 'M', 'ê™›'), + (0xA65B, 'V'), + (0xA65C, 'M', 'ê™'), + (0xA65D, 'V'), + (0xA65E, 'M', 'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', 'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', 'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', 'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', 'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', 'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', 'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', 'ê™­'), + (0xA66D, 'V'), + (0xA680, 'M', 'ê'), + (0xA681, 'V'), + (0xA682, 'M', 'êƒ'), + (0xA683, 'V'), + (0xA684, 'M', 'ê…'), + (0xA685, 'V'), + (0xA686, 'M', 'ê‡'), + (0xA687, 'V'), + (0xA688, 'M', 'ê‰'), + (0xA689, 'V'), + (0xA68A, 'M', 'ê‹'), + (0xA68B, 'V'), + (0xA68C, 'M', 'ê'), + (0xA68D, 'V'), + ] + +def _seg_36() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA68E, 'M', 'ê'), + (0xA68F, 'V'), + (0xA690, 'M', 'ê‘'), + (0xA691, 'V'), + (0xA692, 'M', 'ê“'), + (0xA693, 'V'), + (0xA694, 'M', 'ê•'), + (0xA695, 'V'), + (0xA696, 'M', 'ê—'), + (0xA697, 'V'), + (0xA698, 'M', 'ê™'), + (0xA699, 'V'), + (0xA69A, 'M', 'ê›'), + (0xA69B, 'V'), + (0xA69C, 'M', 'Ñ'), + (0xA69D, 'M', 'ÑŒ'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', 'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', 'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', 'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', 'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', 'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', 'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', 'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', 'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', 'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', 'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', 'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', 'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', 'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', 'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', 'ê'), + (0xA741, 'V'), + (0xA742, 'M', 'êƒ'), + (0xA743, 'V'), + (0xA744, 'M', 'ê…'), + (0xA745, 'V'), + (0xA746, 'M', 'ê‡'), + (0xA747, 'V'), + (0xA748, 'M', 'ê‰'), + (0xA749, 'V'), + (0xA74A, 'M', 'ê‹'), + (0xA74B, 'V'), + (0xA74C, 'M', 'ê'), + (0xA74D, 'V'), + (0xA74E, 'M', 'ê'), + (0xA74F, 'V'), + (0xA750, 'M', 'ê‘'), + (0xA751, 'V'), + (0xA752, 'M', 'ê“'), + (0xA753, 'V'), + (0xA754, 'M', 'ê•'), + (0xA755, 'V'), + (0xA756, 'M', 'ê—'), + (0xA757, 'V'), + (0xA758, 'M', 'ê™'), + (0xA759, 'V'), + (0xA75A, 'M', 'ê›'), + (0xA75B, 'V'), + (0xA75C, 'M', 'ê'), + (0xA75D, 'V'), + (0xA75E, 'M', 'êŸ'), + (0xA75F, 'V'), + (0xA760, 'M', 'ê¡'), + (0xA761, 'V'), + (0xA762, 'M', 'ê£'), + (0xA763, 'V'), + (0xA764, 'M', 'ê¥'), + (0xA765, 'V'), + (0xA766, 'M', 'ê§'), + (0xA767, 'V'), + (0xA768, 'M', 'ê©'), + (0xA769, 'V'), + (0xA76A, 'M', 'ê«'), + (0xA76B, 'V'), + (0xA76C, 'M', 'ê­'), + (0xA76D, 'V'), + (0xA76E, 'M', 'ê¯'), + (0xA76F, 'V'), + (0xA770, 'M', 'ê¯'), + (0xA771, 'V'), + (0xA779, 'M', 'êº'), + (0xA77A, 'V'), + (0xA77B, 'M', 'ê¼'), + ] + +def _seg_37() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA77C, 'V'), + (0xA77D, 'M', 'áµ¹'), + (0xA77E, 'M', 'ê¿'), + (0xA77F, 'V'), + (0xA780, 'M', 'ê'), + (0xA781, 'V'), + (0xA782, 'M', 'êƒ'), + (0xA783, 'V'), + (0xA784, 'M', 'ê…'), + (0xA785, 'V'), + (0xA786, 'M', 'ê‡'), + (0xA787, 'V'), + (0xA78B, 'M', 'êŒ'), + (0xA78C, 'V'), + (0xA78D, 'M', 'É¥'), + (0xA78E, 'V'), + (0xA790, 'M', 'ê‘'), + (0xA791, 'V'), + (0xA792, 'M', 'ê“'), + (0xA793, 'V'), + (0xA796, 'M', 'ê—'), + (0xA797, 'V'), + (0xA798, 'M', 'ê™'), + (0xA799, 'V'), + (0xA79A, 'M', 'ê›'), + (0xA79B, 'V'), + (0xA79C, 'M', 'ê'), + (0xA79D, 'V'), + (0xA79E, 'M', 'êŸ'), + (0xA79F, 'V'), + (0xA7A0, 'M', 'ê¡'), + (0xA7A1, 'V'), + (0xA7A2, 'M', 'ê£'), + (0xA7A3, 'V'), + (0xA7A4, 'M', 'ê¥'), + (0xA7A5, 'V'), + (0xA7A6, 'M', 'ê§'), + (0xA7A7, 'V'), + (0xA7A8, 'M', 'ê©'), + (0xA7A9, 'V'), + (0xA7AA, 'M', 'ɦ'), + (0xA7AB, 'M', 'Éœ'), + (0xA7AC, 'M', 'É¡'), + (0xA7AD, 'M', 'ɬ'), + (0xA7AE, 'M', 'ɪ'), + (0xA7AF, 'V'), + (0xA7B0, 'M', 'Ê'), + (0xA7B1, 'M', 'ʇ'), + (0xA7B2, 'M', 'Ê'), + (0xA7B3, 'M', 'ê­“'), + (0xA7B4, 'M', 'êµ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', 'ê·'), + (0xA7B7, 'V'), + (0xA7B8, 'M', 'ê¹'), + (0xA7B9, 'V'), + (0xA7BA, 'M', 'ê»'), + (0xA7BB, 'V'), + (0xA7BC, 'M', 'ê½'), + (0xA7BD, 'V'), + (0xA7BE, 'M', 'ê¿'), + (0xA7BF, 'V'), + (0xA7C0, 'M', 'êŸ'), + (0xA7C1, 'V'), + (0xA7C2, 'M', 'ꟃ'), + (0xA7C3, 'V'), + (0xA7C4, 'M', 'ê”'), + (0xA7C5, 'M', 'Ê‚'), + (0xA7C6, 'M', 'á¶'), + (0xA7C7, 'M', 'ꟈ'), + (0xA7C8, 'V'), + (0xA7C9, 'M', 'êŸ'), + (0xA7CA, 'V'), + (0xA7CB, 'X'), + (0xA7D0, 'M', 'ꟑ'), + (0xA7D1, 'V'), + (0xA7D2, 'X'), + (0xA7D3, 'V'), + (0xA7D4, 'X'), + (0xA7D5, 'V'), + (0xA7D6, 'M', 'ꟗ'), + (0xA7D7, 'V'), + (0xA7D8, 'M', 'ꟙ'), + (0xA7D9, 'V'), + (0xA7DA, 'X'), + (0xA7F2, 'M', 'c'), + (0xA7F3, 'M', 'f'), + (0xA7F4, 'M', 'q'), + (0xA7F5, 'M', 'ꟶ'), + (0xA7F6, 'V'), + (0xA7F8, 'M', 'ħ'), + (0xA7F9, 'M', 'Å“'), + (0xA7FA, 'V'), + (0xA82D, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + ] + +def _seg_38() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9FF, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xAB30, 'V'), + (0xAB5C, 'M', 'ꜧ'), + (0xAB5D, 'M', 'ꬷ'), + (0xAB5E, 'M', 'É«'), + (0xAB5F, 'M', 'ê­’'), + (0xAB60, 'V'), + (0xAB69, 'M', 'Ê'), + (0xAB6A, 'V'), + (0xAB6C, 'X'), + (0xAB70, 'M', 'á '), + (0xAB71, 'M', 'á¡'), + (0xAB72, 'M', 'á¢'), + (0xAB73, 'M', 'á£'), + (0xAB74, 'M', 'á¤'), + (0xAB75, 'M', 'á¥'), + (0xAB76, 'M', 'á¦'), + (0xAB77, 'M', 'á§'), + (0xAB78, 'M', 'á¨'), + (0xAB79, 'M', 'á©'), + (0xAB7A, 'M', 'áª'), + (0xAB7B, 'M', 'á«'), + (0xAB7C, 'M', 'á¬'), + (0xAB7D, 'M', 'á­'), + (0xAB7E, 'M', 'á®'), + (0xAB7F, 'M', 'á¯'), + (0xAB80, 'M', 'á°'), + (0xAB81, 'M', 'á±'), + (0xAB82, 'M', 'á²'), + (0xAB83, 'M', 'á³'), + (0xAB84, 'M', 'á´'), + (0xAB85, 'M', 'áµ'), + (0xAB86, 'M', 'á¶'), + (0xAB87, 'M', 'á·'), + (0xAB88, 'M', 'á¸'), + (0xAB89, 'M', 'á¹'), + (0xAB8A, 'M', 'áº'), + (0xAB8B, 'M', 'á»'), + (0xAB8C, 'M', 'á¼'), + (0xAB8D, 'M', 'á½'), + (0xAB8E, 'M', 'á¾'), + (0xAB8F, 'M', 'á¿'), + (0xAB90, 'M', 'á€'), + (0xAB91, 'M', 'á'), + (0xAB92, 'M', 'á‚'), + (0xAB93, 'M', 'áƒ'), + (0xAB94, 'M', 'á„'), + (0xAB95, 'M', 'á…'), + (0xAB96, 'M', 'á†'), + (0xAB97, 'M', 'á‡'), + (0xAB98, 'M', 'áˆ'), + (0xAB99, 'M', 'á‰'), + (0xAB9A, 'M', 'á'), + (0xAB9B, 'M', 'á‹'), + (0xAB9C, 'M', 'áŒ'), + (0xAB9D, 'M', 'á'), + (0xAB9E, 'M', 'á'), + (0xAB9F, 'M', 'á'), + (0xABA0, 'M', 'á'), + (0xABA1, 'M', 'á‘'), + (0xABA2, 'M', 'á’'), + (0xABA3, 'M', 'á“'), + (0xABA4, 'M', 'á”'), + (0xABA5, 'M', 'á•'), + (0xABA6, 'M', 'á–'), + (0xABA7, 'M', 'á—'), + (0xABA8, 'M', 'á˜'), + (0xABA9, 'M', 'á™'), + (0xABAA, 'M', 'á'), + ] + +def _seg_39() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xABAB, 'M', 'á›'), + (0xABAC, 'M', 'áœ'), + (0xABAD, 'M', 'á'), + (0xABAE, 'M', 'á'), + (0xABAF, 'M', 'áŸ'), + (0xABB0, 'M', 'á '), + (0xABB1, 'M', 'á¡'), + (0xABB2, 'M', 'á¢'), + (0xABB3, 'M', 'á£'), + (0xABB4, 'M', 'á¤'), + (0xABB5, 'M', 'á¥'), + (0xABB6, 'M', 'á¦'), + (0xABB7, 'M', 'á§'), + (0xABB8, 'M', 'á¨'), + (0xABB9, 'M', 'á©'), + (0xABBA, 'M', 'áª'), + (0xABBB, 'M', 'á«'), + (0xABBC, 'M', 'á¬'), + (0xABBD, 'M', 'á­'), + (0xABBE, 'M', 'á®'), + (0xABBF, 'M', 'á¯'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', '豈'), + (0xF901, 'M', 'æ›´'), + (0xF902, 'M', 'è»'), + (0xF903, 'M', '賈'), + (0xF904, 'M', '滑'), + (0xF905, 'M', '串'), + (0xF906, 'M', 'å¥'), + (0xF907, 'M', '龜'), + (0xF909, 'M', '契'), + (0xF90A, 'M', '金'), + (0xF90B, 'M', 'å–‡'), + (0xF90C, 'M', '奈'), + (0xF90D, 'M', '懶'), + (0xF90E, 'M', '癩'), + (0xF90F, 'M', 'ç¾…'), + (0xF910, 'M', '蘿'), + (0xF911, 'M', 'èº'), + (0xF912, 'M', '裸'), + (0xF913, 'M', 'é‚'), + (0xF914, 'M', '樂'), + (0xF915, 'M', 'æ´›'), + (0xF916, 'M', '烙'), + (0xF917, 'M', 'ç'), + (0xF918, 'M', 'è½'), + (0xF919, 'M', 'é…ª'), + (0xF91A, 'M', '駱'), + (0xF91B, 'M', '亂'), + (0xF91C, 'M', 'åµ'), + (0xF91D, 'M', '欄'), + (0xF91E, 'M', '爛'), + (0xF91F, 'M', '蘭'), + (0xF920, 'M', 'é¸'), + (0xF921, 'M', 'åµ'), + (0xF922, 'M', 'æ¿«'), + (0xF923, 'M', 'è—'), + (0xF924, 'M', '襤'), + (0xF925, 'M', '拉'), + (0xF926, 'M', '臘'), + (0xF927, 'M', 'è Ÿ'), + (0xF928, 'M', 'å»'), + (0xF929, 'M', '朗'), + (0xF92A, 'M', '浪'), + (0xF92B, 'M', '狼'), + (0xF92C, 'M', 'éƒ'), + (0xF92D, 'M', '來'), + (0xF92E, 'M', '冷'), + (0xF92F, 'M', 'å‹'), + (0xF930, 'M', 'æ“„'), + (0xF931, 'M', 'æ«“'), + (0xF932, 'M', 'çˆ'), + (0xF933, 'M', '盧'), + (0xF934, 'M', 'è€'), + (0xF935, 'M', '蘆'), + (0xF936, 'M', '虜'), + (0xF937, 'M', 'è·¯'), + (0xF938, 'M', '露'), + (0xF939, 'M', 'é­¯'), + (0xF93A, 'M', 'é·º'), + (0xF93B, 'M', '碌'), + (0xF93C, 'M', '祿'), + (0xF93D, 'M', '綠'), + (0xF93E, 'M', 'è‰'), + (0xF93F, 'M', '錄'), + (0xF940, 'M', '鹿'), + (0xF941, 'M', 'è«–'), + (0xF942, 'M', '壟'), + (0xF943, 'M', '弄'), + (0xF944, 'M', 'ç± '), + (0xF945, 'M', 'è¾'), + ] + +def _seg_40() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF946, 'M', '牢'), + (0xF947, 'M', 'ç£'), + (0xF948, 'M', '賂'), + (0xF949, 'M', 'é›·'), + (0xF94A, 'M', '壘'), + (0xF94B, 'M', 'å±¢'), + (0xF94C, 'M', '樓'), + (0xF94D, 'M', 'æ·'), + (0xF94E, 'M', 'æ¼'), + (0xF94F, 'M', 'ç´¯'), + (0xF950, 'M', '縷'), + (0xF951, 'M', '陋'), + (0xF952, 'M', 'å‹’'), + (0xF953, 'M', 'è‚‹'), + (0xF954, 'M', '凜'), + (0xF955, 'M', '凌'), + (0xF956, 'M', '稜'), + (0xF957, 'M', '綾'), + (0xF958, 'M', 'è±'), + (0xF959, 'M', '陵'), + (0xF95A, 'M', '讀'), + (0xF95B, 'M', 'æ‹'), + (0xF95C, 'M', '樂'), + (0xF95D, 'M', '諾'), + (0xF95E, 'M', '丹'), + (0xF95F, 'M', '寧'), + (0xF960, 'M', '怒'), + (0xF961, 'M', 'ç‡'), + (0xF962, 'M', 'ç•°'), + (0xF963, 'M', '北'), + (0xF964, 'M', '磻'), + (0xF965, 'M', '便'), + (0xF966, 'M', '復'), + (0xF967, 'M', 'ä¸'), + (0xF968, 'M', '泌'), + (0xF969, 'M', '數'), + (0xF96A, 'M', 'ç´¢'), + (0xF96B, 'M', 'åƒ'), + (0xF96C, 'M', 'å¡'), + (0xF96D, 'M', 'çœ'), + (0xF96E, 'M', '葉'), + (0xF96F, 'M', '說'), + (0xF970, 'M', '殺'), + (0xF971, 'M', 'è¾°'), + (0xF972, 'M', '沈'), + (0xF973, 'M', '拾'), + (0xF974, 'M', 'è‹¥'), + (0xF975, 'M', 'æ '), + (0xF976, 'M', 'ç•¥'), + (0xF977, 'M', '亮'), + (0xF978, 'M', 'å…©'), + (0xF979, 'M', '凉'), + (0xF97A, 'M', 'æ¢'), + (0xF97B, 'M', '糧'), + (0xF97C, 'M', '良'), + (0xF97D, 'M', 'è«’'), + (0xF97E, 'M', 'é‡'), + (0xF97F, 'M', '勵'), + (0xF980, 'M', 'å‘‚'), + (0xF981, 'M', '女'), + (0xF982, 'M', '廬'), + (0xF983, 'M', 'æ—…'), + (0xF984, 'M', '濾'), + (0xF985, 'M', '礪'), + (0xF986, 'M', 'é–­'), + (0xF987, 'M', '驪'), + (0xF988, 'M', '麗'), + (0xF989, 'M', 'é»'), + (0xF98A, 'M', 'å›'), + (0xF98B, 'M', '曆'), + (0xF98C, 'M', 'æ­·'), + (0xF98D, 'M', 'è½¢'), + (0xF98E, 'M', 'å¹´'), + (0xF98F, 'M', 'æ†'), + (0xF990, 'M', '戀'), + (0xF991, 'M', 'æ’'), + (0xF992, 'M', 'æ¼£'), + (0xF993, 'M', 'ç…‰'), + (0xF994, 'M', 'ç’‰'), + (0xF995, 'M', 'ç§'), + (0xF996, 'M', 'ç·´'), + (0xF997, 'M', 'è¯'), + (0xF998, 'M', '輦'), + (0xF999, 'M', 'è“®'), + (0xF99A, 'M', '連'), + (0xF99B, 'M', 'é'), + (0xF99C, 'M', '列'), + (0xF99D, 'M', 'å£'), + (0xF99E, 'M', 'å’½'), + (0xF99F, 'M', '烈'), + (0xF9A0, 'M', '裂'), + (0xF9A1, 'M', '說'), + (0xF9A2, 'M', '廉'), + (0xF9A3, 'M', '念'), + (0xF9A4, 'M', 'æ»'), + (0xF9A5, 'M', 'æ®®'), + (0xF9A6, 'M', 'ç°¾'), + (0xF9A7, 'M', 'çµ'), + (0xF9A8, 'M', '令'), + (0xF9A9, 'M', '囹'), + ] + +def _seg_41() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF9AA, 'M', '寧'), + (0xF9AB, 'M', '嶺'), + (0xF9AC, 'M', '怜'), + (0xF9AD, 'M', 'ç²'), + (0xF9AE, 'M', 'ç‘©'), + (0xF9AF, 'M', 'ç¾'), + (0xF9B0, 'M', 'è†'), + (0xF9B1, 'M', '鈴'), + (0xF9B2, 'M', '零'), + (0xF9B3, 'M', 'éˆ'), + (0xF9B4, 'M', 'é ˜'), + (0xF9B5, 'M', '例'), + (0xF9B6, 'M', '禮'), + (0xF9B7, 'M', '醴'), + (0xF9B8, 'M', 'é¸'), + (0xF9B9, 'M', '惡'), + (0xF9BA, 'M', '了'), + (0xF9BB, 'M', 'åƒ'), + (0xF9BC, 'M', '寮'), + (0xF9BD, 'M', 'å°¿'), + (0xF9BE, 'M', 'æ–™'), + (0xF9BF, 'M', '樂'), + (0xF9C0, 'M', 'ç‡'), + (0xF9C1, 'M', '療'), + (0xF9C2, 'M', '蓼'), + (0xF9C3, 'M', 'é¼'), + (0xF9C4, 'M', 'é¾'), + (0xF9C5, 'M', 'æˆ'), + (0xF9C6, 'M', '阮'), + (0xF9C7, 'M', 'å‰'), + (0xF9C8, 'M', 'æ»'), + (0xF9C9, 'M', '柳'), + (0xF9CA, 'M', 'æµ'), + (0xF9CB, 'M', '溜'), + (0xF9CC, 'M', 'ç‰'), + (0xF9CD, 'M', 'ç•™'), + (0xF9CE, 'M', 'ç¡«'), + (0xF9CF, 'M', 'ç´'), + (0xF9D0, 'M', 'é¡'), + (0xF9D1, 'M', 'å…­'), + (0xF9D2, 'M', '戮'), + (0xF9D3, 'M', '陸'), + (0xF9D4, 'M', '倫'), + (0xF9D5, 'M', 'å´™'), + (0xF9D6, 'M', 'æ·ª'), + (0xF9D7, 'M', '輪'), + (0xF9D8, 'M', '律'), + (0xF9D9, 'M', 'æ…„'), + (0xF9DA, 'M', 'æ —'), + (0xF9DB, 'M', 'ç‡'), + (0xF9DC, 'M', 'é†'), + (0xF9DD, 'M', '利'), + (0xF9DE, 'M', 'å'), + (0xF9DF, 'M', 'å±¥'), + (0xF9E0, 'M', '易'), + (0xF9E1, 'M', 'æ'), + (0xF9E2, 'M', '梨'), + (0xF9E3, 'M', 'æ³¥'), + (0xF9E4, 'M', 'ç†'), + (0xF9E5, 'M', 'ç—¢'), + (0xF9E6, 'M', 'ç½¹'), + (0xF9E7, 'M', 'è£'), + (0xF9E8, 'M', '裡'), + (0xF9E9, 'M', '里'), + (0xF9EA, 'M', '離'), + (0xF9EB, 'M', '匿'), + (0xF9EC, 'M', '溺'), + (0xF9ED, 'M', 'å'), + (0xF9EE, 'M', 'ç‡'), + (0xF9EF, 'M', 'ç’˜'), + (0xF9F0, 'M', 'è—º'), + (0xF9F1, 'M', 'é£'), + (0xF9F2, 'M', 'é±—'), + (0xF9F3, 'M', '麟'), + (0xF9F4, 'M', 'æ—'), + (0xF9F5, 'M', 'æ·‹'), + (0xF9F6, 'M', '臨'), + (0xF9F7, 'M', 'ç«‹'), + (0xF9F8, 'M', '笠'), + (0xF9F9, 'M', 'ç²’'), + (0xF9FA, 'M', 'ç‹€'), + (0xF9FB, 'M', 'ç‚™'), + (0xF9FC, 'M', 'è­˜'), + (0xF9FD, 'M', '什'), + (0xF9FE, 'M', '茶'), + (0xF9FF, 'M', '刺'), + (0xFA00, 'M', '切'), + (0xFA01, 'M', '度'), + (0xFA02, 'M', 'æ‹“'), + (0xFA03, 'M', 'ç³–'), + (0xFA04, 'M', 'å®…'), + (0xFA05, 'M', 'æ´'), + (0xFA06, 'M', 'æ´'), + (0xFA07, 'M', 'è¼»'), + (0xFA08, 'M', 'è¡Œ'), + (0xFA09, 'M', 'é™'), + (0xFA0A, 'M', '見'), + (0xFA0B, 'M', '廓'), + (0xFA0C, 'M', 'å…€'), + (0xFA0D, 'M', 'å—€'), + ] + +def _seg_42() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA0E, 'V'), + (0xFA10, 'M', 'å¡'), + (0xFA11, 'V'), + (0xFA12, 'M', 'æ™´'), + (0xFA13, 'V'), + (0xFA15, 'M', 'å‡'), + (0xFA16, 'M', '猪'), + (0xFA17, 'M', 'ç›'), + (0xFA18, 'M', '礼'), + (0xFA19, 'M', 'ç¥'), + (0xFA1A, 'M', '祥'), + (0xFA1B, 'M', 'ç¦'), + (0xFA1C, 'M', 'é–'), + (0xFA1D, 'M', 'ç²¾'), + (0xFA1E, 'M', 'ç¾½'), + (0xFA1F, 'V'), + (0xFA20, 'M', '蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', '諸'), + (0xFA23, 'V'), + (0xFA25, 'M', '逸'), + (0xFA26, 'M', '都'), + (0xFA27, 'V'), + (0xFA2A, 'M', '飯'), + (0xFA2B, 'M', '飼'), + (0xFA2C, 'M', '館'), + (0xFA2D, 'M', '鶴'), + (0xFA2E, 'M', 'éƒ'), + (0xFA2F, 'M', 'é·'), + (0xFA30, 'M', 'ä¾®'), + (0xFA31, 'M', '僧'), + (0xFA32, 'M', 'å…'), + (0xFA33, 'M', '勉'), + (0xFA34, 'M', '勤'), + (0xFA35, 'M', 'å‘'), + (0xFA36, 'M', 'å–'), + (0xFA37, 'M', '嘆'), + (0xFA38, 'M', '器'), + (0xFA39, 'M', 'å¡€'), + (0xFA3A, 'M', '墨'), + (0xFA3B, 'M', '層'), + (0xFA3C, 'M', 'å±®'), + (0xFA3D, 'M', 'æ‚”'), + (0xFA3E, 'M', 'æ…¨'), + (0xFA3F, 'M', 'æ†'), + (0xFA40, 'M', '懲'), + (0xFA41, 'M', 'æ•'), + (0xFA42, 'M', 'æ—¢'), + (0xFA43, 'M', 'æ‘'), + (0xFA44, 'M', '梅'), + (0xFA45, 'M', 'æµ·'), + (0xFA46, 'M', 'æ¸'), + (0xFA47, 'M', 'æ¼¢'), + (0xFA48, 'M', 'ç…®'), + (0xFA49, 'M', '爫'), + (0xFA4A, 'M', 'ç¢'), + (0xFA4B, 'M', '碑'), + (0xFA4C, 'M', '社'), + (0xFA4D, 'M', '祉'), + (0xFA4E, 'M', '祈'), + (0xFA4F, 'M', 'ç¥'), + (0xFA50, 'M', '祖'), + (0xFA51, 'M', 'ç¥'), + (0xFA52, 'M', 'ç¦'), + (0xFA53, 'M', 'ç¦'), + (0xFA54, 'M', 'ç©€'), + (0xFA55, 'M', 'çª'), + (0xFA56, 'M', '節'), + (0xFA57, 'M', 'ç·´'), + (0xFA58, 'M', '縉'), + (0xFA59, 'M', 'ç¹'), + (0xFA5A, 'M', 'ç½²'), + (0xFA5B, 'M', '者'), + (0xFA5C, 'M', '臭'), + (0xFA5D, 'M', '艹'), + (0xFA5F, 'M', 'è‘—'), + (0xFA60, 'M', 'è¤'), + (0xFA61, 'M', '視'), + (0xFA62, 'M', 'è¬'), + (0xFA63, 'M', '謹'), + (0xFA64, 'M', '賓'), + (0xFA65, 'M', 'è´ˆ'), + (0xFA66, 'M', '辶'), + (0xFA67, 'M', '逸'), + (0xFA68, 'M', '難'), + (0xFA69, 'M', '響'), + (0xFA6A, 'M', 'é »'), + (0xFA6B, 'M', 'æµ'), + (0xFA6C, 'M', '𤋮'), + (0xFA6D, 'M', '舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', '並'), + (0xFA71, 'M', '况'), + (0xFA72, 'M', 'å…¨'), + (0xFA73, 'M', 'ä¾€'), + (0xFA74, 'M', 'å……'), + (0xFA75, 'M', '冀'), + (0xFA76, 'M', '勇'), + (0xFA77, 'M', '勺'), + (0xFA78, 'M', 'å–'), + ] + +def _seg_43() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA79, 'M', 'å••'), + (0xFA7A, 'M', 'å–™'), + (0xFA7B, 'M', 'å—¢'), + (0xFA7C, 'M', 'å¡'), + (0xFA7D, 'M', '墳'), + (0xFA7E, 'M', '奄'), + (0xFA7F, 'M', '奔'), + (0xFA80, 'M', 'å©¢'), + (0xFA81, 'M', '嬨'), + (0xFA82, 'M', 'å»’'), + (0xFA83, 'M', 'å»™'), + (0xFA84, 'M', '彩'), + (0xFA85, 'M', 'å¾­'), + (0xFA86, 'M', '惘'), + (0xFA87, 'M', 'æ…'), + (0xFA88, 'M', '愈'), + (0xFA89, 'M', 'æ†'), + (0xFA8A, 'M', 'æ… '), + (0xFA8B, 'M', '懲'), + (0xFA8C, 'M', '戴'), + (0xFA8D, 'M', 'æ„'), + (0xFA8E, 'M', 'æœ'), + (0xFA8F, 'M', 'æ‘’'), + (0xFA90, 'M', 'æ•–'), + (0xFA91, 'M', 'æ™´'), + (0xFA92, 'M', '朗'), + (0xFA93, 'M', '望'), + (0xFA94, 'M', 'æ–'), + (0xFA95, 'M', 'æ­¹'), + (0xFA96, 'M', '殺'), + (0xFA97, 'M', 'æµ'), + (0xFA98, 'M', 'æ»›'), + (0xFA99, 'M', '滋'), + (0xFA9A, 'M', 'æ¼¢'), + (0xFA9B, 'M', 'ç€'), + (0xFA9C, 'M', 'ç…®'), + (0xFA9D, 'M', 'ç§'), + (0xFA9E, 'M', '爵'), + (0xFA9F, 'M', 'ç¯'), + (0xFAA0, 'M', '猪'), + (0xFAA1, 'M', '瑱'), + (0xFAA2, 'M', '甆'), + (0xFAA3, 'M', 'ç”»'), + (0xFAA4, 'M', 'ç˜'), + (0xFAA5, 'M', '瘟'), + (0xFAA6, 'M', 'ç›'), + (0xFAA7, 'M', 'ç››'), + (0xFAA8, 'M', 'ç›´'), + (0xFAA9, 'M', 'ç'), + (0xFAAA, 'M', 'ç€'), + (0xFAAB, 'M', '磌'), + (0xFAAC, 'M', '窱'), + (0xFAAD, 'M', '節'), + (0xFAAE, 'M', 'ç±»'), + (0xFAAF, 'M', 'çµ›'), + (0xFAB0, 'M', 'ç·´'), + (0xFAB1, 'M', 'ç¼¾'), + (0xFAB2, 'M', '者'), + (0xFAB3, 'M', 'è’'), + (0xFAB4, 'M', 'è¯'), + (0xFAB5, 'M', 'è¹'), + (0xFAB6, 'M', 'è¥'), + (0xFAB7, 'M', '覆'), + (0xFAB8, 'M', '視'), + (0xFAB9, 'M', '調'), + (0xFABA, 'M', '諸'), + (0xFABB, 'M', 'è«‹'), + (0xFABC, 'M', 'è¬'), + (0xFABD, 'M', '諾'), + (0xFABE, 'M', 'è«­'), + (0xFABF, 'M', '謹'), + (0xFAC0, 'M', 'è®'), + (0xFAC1, 'M', 'è´ˆ'), + (0xFAC2, 'M', '輸'), + (0xFAC3, 'M', 'é²'), + (0xFAC4, 'M', '醙'), + (0xFAC5, 'M', '鉶'), + (0xFAC6, 'M', '陼'), + (0xFAC7, 'M', '難'), + (0xFAC8, 'M', 'é–'), + (0xFAC9, 'M', '韛'), + (0xFACA, 'M', '響'), + (0xFACB, 'M', 'é ‹'), + (0xFACC, 'M', 'é »'), + (0xFACD, 'M', '鬒'), + (0xFACE, 'M', '龜'), + (0xFACF, 'M', 'đ¢¡'), + (0xFAD0, 'M', 'đ¢¡„'), + (0xFAD1, 'M', 'đ£•'), + (0xFAD2, 'M', 'ă®'), + (0xFAD3, 'M', '䀘'), + (0xFAD4, 'M', '䀹'), + (0xFAD5, 'M', 'đ¥‰‰'), + (0xFAD6, 'M', 'đ¥³'), + (0xFAD7, 'M', '𧻓'), + (0xFAD8, 'M', '齃'), + (0xFAD9, 'M', 'é¾'), + (0xFADA, 'X'), + (0xFB00, 'M', 'ff'), + (0xFB01, 'M', 'fi'), + ] + +def _seg_44() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFB02, 'M', 'fl'), + (0xFB03, 'M', 'ffi'), + (0xFB04, 'M', 'ffl'), + (0xFB05, 'M', 'st'), + (0xFB07, 'X'), + (0xFB13, 'M', 'Ơ´Ơ¶'), + (0xFB14, 'M', 'Ơ´Ơ¥'), + (0xFB15, 'M', 'Ơ´Ơ«'), + (0xFB16, 'M', 'Ơ¾Ơ¶'), + (0xFB17, 'M', 'Ơ´Ơ­'), + (0xFB18, 'X'), + (0xFB1D, 'M', '×™Ö´'), + (0xFB1E, 'V'), + (0xFB1F, 'M', 'ײַ'), + (0xFB20, 'M', '×¢'), + (0xFB21, 'M', '×'), + (0xFB22, 'M', 'ד'), + (0xFB23, 'M', '×”'), + (0xFB24, 'M', '×›'), + (0xFB25, 'M', 'ל'), + (0xFB26, 'M', '×'), + (0xFB27, 'M', 'ר'), + (0xFB28, 'M', 'ת'), + (0xFB29, '3', '+'), + (0xFB2A, 'M', 'ש×'), + (0xFB2B, 'M', 'שׂ'), + (0xFB2C, 'M', 'שּ×'), + (0xFB2D, 'M', 'שּׂ'), + (0xFB2E, 'M', '×Ö·'), + (0xFB2F, 'M', '×Ö¸'), + (0xFB30, 'M', '×Ö¼'), + (0xFB31, 'M', 'בּ'), + (0xFB32, 'M', '×’Ö¼'), + (0xFB33, 'M', 'דּ'), + (0xFB34, 'M', '×”Ö¼'), + (0xFB35, 'M', 'וּ'), + (0xFB36, 'M', '×–Ö¼'), + (0xFB37, 'X'), + (0xFB38, 'M', 'טּ'), + (0xFB39, 'M', '×™Ö¼'), + (0xFB3A, 'M', '×Ö¼'), + (0xFB3B, 'M', '×›Ö¼'), + (0xFB3C, 'M', 'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', '×Ö¼'), + (0xFB3F, 'X'), + (0xFB40, 'M', '× Ö¼'), + (0xFB41, 'M', 'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', '×£Ö¼'), + (0xFB44, 'M', 'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', 'צּ'), + (0xFB47, 'M', 'קּ'), + (0xFB48, 'M', 'רּ'), + (0xFB49, 'M', 'שּ'), + (0xFB4A, 'M', 'תּ'), + (0xFB4B, 'M', 'וֹ'), + (0xFB4C, 'M', 'בֿ'), + (0xFB4D, 'M', '×›Ö¿'), + (0xFB4E, 'M', 'פֿ'), + (0xFB4F, 'M', '×ל'), + (0xFB50, 'M', 'Ù±'), + (0xFB52, 'M', 'Ù»'), + (0xFB56, 'M', 'Ù¾'), + (0xFB5A, 'M', 'Ú€'), + (0xFB5E, 'M', 'Ùº'), + (0xFB62, 'M', 'Ù¿'), + (0xFB66, 'M', 'Ù¹'), + (0xFB6A, 'M', 'Ú¤'), + (0xFB6E, 'M', 'Ú¦'), + (0xFB72, 'M', 'Ú„'), + (0xFB76, 'M', 'Úƒ'), + (0xFB7A, 'M', 'Ú†'), + (0xFB7E, 'M', 'Ú‡'), + (0xFB82, 'M', 'Ú'), + (0xFB84, 'M', 'ÚŒ'), + (0xFB86, 'M', 'Ú'), + (0xFB88, 'M', 'Úˆ'), + (0xFB8A, 'M', 'Ú˜'), + (0xFB8C, 'M', 'Ú‘'), + (0xFB8E, 'M', 'Ú©'), + (0xFB92, 'M', 'Ú¯'), + (0xFB96, 'M', 'Ú³'), + (0xFB9A, 'M', 'Ú±'), + (0xFB9E, 'M', 'Úº'), + (0xFBA0, 'M', 'Ú»'), + (0xFBA4, 'M', 'Û€'), + (0xFBA6, 'M', 'Û'), + (0xFBAA, 'M', 'Ú¾'), + (0xFBAE, 'M', 'Û’'), + (0xFBB0, 'M', 'Û“'), + (0xFBB2, 'V'), + (0xFBC3, 'X'), + (0xFBD3, 'M', 'Ú­'), + (0xFBD7, 'M', 'Û‡'), + (0xFBD9, 'M', 'Û†'), + (0xFBDB, 'M', 'Ûˆ'), + (0xFBDD, 'M', 'Û‡Ù´'), + (0xFBDE, 'M', 'Û‹'), + ] + +def _seg_45() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFBE0, 'M', 'Û…'), + (0xFBE2, 'M', 'Û‰'), + (0xFBE4, 'M', 'Û'), + (0xFBE8, 'M', 'Ù‰'), + (0xFBEA, 'M', 'ئا'), + (0xFBEC, 'M', 'ئە'), + (0xFBEE, 'M', 'ئو'), + (0xFBF0, 'M', 'ئۇ'), + (0xFBF2, 'M', 'ئۆ'), + (0xFBF4, 'M', 'ئۈ'), + (0xFBF6, 'M', 'ئÛ'), + (0xFBF9, 'M', 'ئى'), + (0xFBFC, 'M', 'ÛŒ'), + (0xFC00, 'M', 'ئج'), + (0xFC01, 'M', 'ئح'), + (0xFC02, 'M', 'ئم'), + (0xFC03, 'M', 'ئى'), + (0xFC04, 'M', 'ئÙ'), + (0xFC05, 'M', 'بج'), + (0xFC06, 'M', 'بح'), + (0xFC07, 'M', 'بخ'), + (0xFC08, 'M', 'بم'), + (0xFC09, 'M', 'بى'), + (0xFC0A, 'M', 'بÙ'), + (0xFC0B, 'M', 'تج'), + (0xFC0C, 'M', 'تح'), + (0xFC0D, 'M', 'تخ'), + (0xFC0E, 'M', 'تم'), + (0xFC0F, 'M', 'تى'), + (0xFC10, 'M', 'تÙ'), + (0xFC11, 'M', 'ثج'), + (0xFC12, 'M', 'ثم'), + (0xFC13, 'M', 'ثى'), + (0xFC14, 'M', 'Ø«Ù'), + (0xFC15, 'M', 'جح'), + (0xFC16, 'M', 'جم'), + (0xFC17, 'M', 'حج'), + (0xFC18, 'M', 'حم'), + (0xFC19, 'M', 'خج'), + (0xFC1A, 'M', 'خح'), + (0xFC1B, 'M', 'خم'), + (0xFC1C, 'M', 'سج'), + (0xFC1D, 'M', 'سح'), + (0xFC1E, 'M', 'سخ'), + (0xFC1F, 'M', 'سم'), + (0xFC20, 'M', 'صح'), + (0xFC21, 'M', 'صم'), + (0xFC22, 'M', 'ضج'), + (0xFC23, 'M', 'ضح'), + (0xFC24, 'M', 'ضخ'), + (0xFC25, 'M', 'ضم'), + (0xFC26, 'M', 'طح'), + (0xFC27, 'M', 'طم'), + (0xFC28, 'M', 'ظم'), + (0xFC29, 'M', 'عج'), + (0xFC2A, 'M', 'عم'), + (0xFC2B, 'M', 'غج'), + (0xFC2C, 'M', 'غم'), + (0xFC2D, 'M', 'Ùج'), + (0xFC2E, 'M', 'ÙØ­'), + (0xFC2F, 'M', 'ÙØ®'), + (0xFC30, 'M', 'ÙÙ…'), + (0xFC31, 'M', 'ÙÙ‰'), + (0xFC32, 'M', 'ÙÙ'), + (0xFC33, 'M', 'قح'), + (0xFC34, 'M', 'قم'), + (0xFC35, 'M', 'قى'), + (0xFC36, 'M', 'Ù‚Ù'), + (0xFC37, 'M', 'كا'), + (0xFC38, 'M', 'كج'), + (0xFC39, 'M', 'كح'), + (0xFC3A, 'M', 'كخ'), + (0xFC3B, 'M', 'كل'), + (0xFC3C, 'M', 'كم'), + (0xFC3D, 'M', 'كى'), + (0xFC3E, 'M', 'ÙƒÙ'), + (0xFC3F, 'M', 'لج'), + (0xFC40, 'M', 'لح'), + (0xFC41, 'M', 'لخ'), + (0xFC42, 'M', 'لم'), + (0xFC43, 'M', 'لى'), + (0xFC44, 'M', 'Ù„Ù'), + (0xFC45, 'M', 'مج'), + (0xFC46, 'M', 'مح'), + (0xFC47, 'M', 'مخ'), + (0xFC48, 'M', 'مم'), + (0xFC49, 'M', 'مى'), + (0xFC4A, 'M', 'Ù…Ù'), + (0xFC4B, 'M', 'نج'), + (0xFC4C, 'M', 'نح'), + (0xFC4D, 'M', 'نخ'), + (0xFC4E, 'M', 'نم'), + (0xFC4F, 'M', 'نى'), + (0xFC50, 'M', 'Ù†Ù'), + (0xFC51, 'M', 'هج'), + (0xFC52, 'M', 'هم'), + (0xFC53, 'M', 'هى'), + (0xFC54, 'M', 'Ù‡Ù'), + (0xFC55, 'M', 'Ùج'), + (0xFC56, 'M', 'ÙØ­'), + ] + +def _seg_46() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFC57, 'M', 'ÙØ®'), + (0xFC58, 'M', 'ÙÙ…'), + (0xFC59, 'M', 'ÙÙ‰'), + (0xFC5A, 'M', 'ÙÙ'), + (0xFC5B, 'M', 'ذٰ'), + (0xFC5C, 'M', 'رٰ'), + (0xFC5D, 'M', 'ىٰ'), + (0xFC5E, '3', ' ٌّ'), + (0xFC5F, '3', ' ÙÙ‘'), + (0xFC60, '3', ' ÙÙ‘'), + (0xFC61, '3', ' ÙÙ‘'), + (0xFC62, '3', ' ÙÙ‘'), + (0xFC63, '3', ' ّٰ'), + (0xFC64, 'M', 'ئر'), + (0xFC65, 'M', 'ئز'), + (0xFC66, 'M', 'ئم'), + (0xFC67, 'M', 'ئن'), + (0xFC68, 'M', 'ئى'), + (0xFC69, 'M', 'ئÙ'), + (0xFC6A, 'M', 'بر'), + (0xFC6B, 'M', 'بز'), + (0xFC6C, 'M', 'بم'), + (0xFC6D, 'M', 'بن'), + (0xFC6E, 'M', 'بى'), + (0xFC6F, 'M', 'بÙ'), + (0xFC70, 'M', 'تر'), + (0xFC71, 'M', 'تز'), + (0xFC72, 'M', 'تم'), + (0xFC73, 'M', 'تن'), + (0xFC74, 'M', 'تى'), + (0xFC75, 'M', 'تÙ'), + (0xFC76, 'M', 'ثر'), + (0xFC77, 'M', 'ثز'), + (0xFC78, 'M', 'ثم'), + (0xFC79, 'M', 'ثن'), + (0xFC7A, 'M', 'ثى'), + (0xFC7B, 'M', 'Ø«Ù'), + (0xFC7C, 'M', 'ÙÙ‰'), + (0xFC7D, 'M', 'ÙÙ'), + (0xFC7E, 'M', 'قى'), + (0xFC7F, 'M', 'Ù‚Ù'), + (0xFC80, 'M', 'كا'), + (0xFC81, 'M', 'كل'), + (0xFC82, 'M', 'كم'), + (0xFC83, 'M', 'كى'), + (0xFC84, 'M', 'ÙƒÙ'), + (0xFC85, 'M', 'لم'), + (0xFC86, 'M', 'لى'), + (0xFC87, 'M', 'Ù„Ù'), + (0xFC88, 'M', 'ما'), + (0xFC89, 'M', 'مم'), + (0xFC8A, 'M', 'نر'), + (0xFC8B, 'M', 'نز'), + (0xFC8C, 'M', 'نم'), + (0xFC8D, 'M', 'نن'), + (0xFC8E, 'M', 'نى'), + (0xFC8F, 'M', 'Ù†Ù'), + (0xFC90, 'M', 'ىٰ'), + (0xFC91, 'M', 'Ùر'), + (0xFC92, 'M', 'Ùز'), + (0xFC93, 'M', 'ÙÙ…'), + (0xFC94, 'M', 'ÙÙ†'), + (0xFC95, 'M', 'ÙÙ‰'), + (0xFC96, 'M', 'ÙÙ'), + (0xFC97, 'M', 'ئج'), + (0xFC98, 'M', 'ئح'), + (0xFC99, 'M', 'ئخ'), + (0xFC9A, 'M', 'ئم'), + (0xFC9B, 'M', 'ئه'), + (0xFC9C, 'M', 'بج'), + (0xFC9D, 'M', 'بح'), + (0xFC9E, 'M', 'بخ'), + (0xFC9F, 'M', 'بم'), + (0xFCA0, 'M', 'به'), + (0xFCA1, 'M', 'تج'), + (0xFCA2, 'M', 'تح'), + (0xFCA3, 'M', 'تخ'), + (0xFCA4, 'M', 'تم'), + (0xFCA5, 'M', 'ته'), + (0xFCA6, 'M', 'ثم'), + (0xFCA7, 'M', 'جح'), + (0xFCA8, 'M', 'جم'), + (0xFCA9, 'M', 'حج'), + (0xFCAA, 'M', 'حم'), + (0xFCAB, 'M', 'خج'), + (0xFCAC, 'M', 'خم'), + (0xFCAD, 'M', 'سج'), + (0xFCAE, 'M', 'سح'), + (0xFCAF, 'M', 'سخ'), + (0xFCB0, 'M', 'سم'), + (0xFCB1, 'M', 'صح'), + (0xFCB2, 'M', 'صخ'), + (0xFCB3, 'M', 'صم'), + (0xFCB4, 'M', 'ضج'), + (0xFCB5, 'M', 'ضح'), + (0xFCB6, 'M', 'ضخ'), + (0xFCB7, 'M', 'ضم'), + (0xFCB8, 'M', 'طح'), + (0xFCB9, 'M', 'ظم'), + (0xFCBA, 'M', 'عج'), + ] + +def _seg_47() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFCBB, 'M', 'عم'), + (0xFCBC, 'M', 'غج'), + (0xFCBD, 'M', 'غم'), + (0xFCBE, 'M', 'Ùج'), + (0xFCBF, 'M', 'ÙØ­'), + (0xFCC0, 'M', 'ÙØ®'), + (0xFCC1, 'M', 'ÙÙ…'), + (0xFCC2, 'M', 'قح'), + (0xFCC3, 'M', 'قم'), + (0xFCC4, 'M', 'كج'), + (0xFCC5, 'M', 'كح'), + (0xFCC6, 'M', 'كخ'), + (0xFCC7, 'M', 'كل'), + (0xFCC8, 'M', 'كم'), + (0xFCC9, 'M', 'لج'), + (0xFCCA, 'M', 'لح'), + (0xFCCB, 'M', 'لخ'), + (0xFCCC, 'M', 'لم'), + (0xFCCD, 'M', 'له'), + (0xFCCE, 'M', 'مج'), + (0xFCCF, 'M', 'مح'), + (0xFCD0, 'M', 'مخ'), + (0xFCD1, 'M', 'مم'), + (0xFCD2, 'M', 'نج'), + (0xFCD3, 'M', 'نح'), + (0xFCD4, 'M', 'نخ'), + (0xFCD5, 'M', 'نم'), + (0xFCD6, 'M', 'نه'), + (0xFCD7, 'M', 'هج'), + (0xFCD8, 'M', 'هم'), + (0xFCD9, 'M', 'هٰ'), + (0xFCDA, 'M', 'Ùج'), + (0xFCDB, 'M', 'ÙØ­'), + (0xFCDC, 'M', 'ÙØ®'), + (0xFCDD, 'M', 'ÙÙ…'), + (0xFCDE, 'M', 'ÙÙ‡'), + (0xFCDF, 'M', 'ئم'), + (0xFCE0, 'M', 'ئه'), + (0xFCE1, 'M', 'بم'), + (0xFCE2, 'M', 'به'), + (0xFCE3, 'M', 'تم'), + (0xFCE4, 'M', 'ته'), + (0xFCE5, 'M', 'ثم'), + (0xFCE6, 'M', 'ثه'), + (0xFCE7, 'M', 'سم'), + (0xFCE8, 'M', 'سه'), + (0xFCE9, 'M', 'شم'), + (0xFCEA, 'M', 'شه'), + (0xFCEB, 'M', 'كل'), + (0xFCEC, 'M', 'كم'), + (0xFCED, 'M', 'لم'), + (0xFCEE, 'M', 'نم'), + (0xFCEF, 'M', 'نه'), + (0xFCF0, 'M', 'ÙÙ…'), + (0xFCF1, 'M', 'ÙÙ‡'), + (0xFCF2, 'M', 'Ù€ÙÙ‘'), + (0xFCF3, 'M', 'Ù€ÙÙ‘'), + (0xFCF4, 'M', 'Ù€ÙÙ‘'), + (0xFCF5, 'M', 'طى'), + (0xFCF6, 'M', 'Ø·Ù'), + (0xFCF7, 'M', 'عى'), + (0xFCF8, 'M', 'عÙ'), + (0xFCF9, 'M', 'غى'), + (0xFCFA, 'M', 'غÙ'), + (0xFCFB, 'M', 'سى'), + (0xFCFC, 'M', 'سÙ'), + (0xFCFD, 'M', 'شى'), + (0xFCFE, 'M', 'Ø´Ù'), + (0xFCFF, 'M', 'حى'), + (0xFD00, 'M', 'Ø­Ù'), + (0xFD01, 'M', 'جى'), + (0xFD02, 'M', 'جÙ'), + (0xFD03, 'M', 'خى'), + (0xFD04, 'M', 'Ø®Ù'), + (0xFD05, 'M', 'صى'), + (0xFD06, 'M', 'صÙ'), + (0xFD07, 'M', 'ضى'), + (0xFD08, 'M', 'ضÙ'), + (0xFD09, 'M', 'شج'), + (0xFD0A, 'M', 'شح'), + (0xFD0B, 'M', 'شخ'), + (0xFD0C, 'M', 'شم'), + (0xFD0D, 'M', 'شر'), + (0xFD0E, 'M', 'سر'), + (0xFD0F, 'M', 'صر'), + (0xFD10, 'M', 'ضر'), + (0xFD11, 'M', 'طى'), + (0xFD12, 'M', 'Ø·Ù'), + (0xFD13, 'M', 'عى'), + (0xFD14, 'M', 'عÙ'), + (0xFD15, 'M', 'غى'), + (0xFD16, 'M', 'غÙ'), + (0xFD17, 'M', 'سى'), + (0xFD18, 'M', 'سÙ'), + (0xFD19, 'M', 'شى'), + (0xFD1A, 'M', 'Ø´Ù'), + (0xFD1B, 'M', 'حى'), + (0xFD1C, 'M', 'Ø­Ù'), + (0xFD1D, 'M', 'جى'), + (0xFD1E, 'M', 'جÙ'), + ] + +def _seg_48() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFD1F, 'M', 'خى'), + (0xFD20, 'M', 'Ø®Ù'), + (0xFD21, 'M', 'صى'), + (0xFD22, 'M', 'صÙ'), + (0xFD23, 'M', 'ضى'), + (0xFD24, 'M', 'ضÙ'), + (0xFD25, 'M', 'شج'), + (0xFD26, 'M', 'شح'), + (0xFD27, 'M', 'شخ'), + (0xFD28, 'M', 'شم'), + (0xFD29, 'M', 'شر'), + (0xFD2A, 'M', 'سر'), + (0xFD2B, 'M', 'صر'), + (0xFD2C, 'M', 'ضر'), + (0xFD2D, 'M', 'شج'), + (0xFD2E, 'M', 'شح'), + (0xFD2F, 'M', 'شخ'), + (0xFD30, 'M', 'شم'), + (0xFD31, 'M', 'سه'), + (0xFD32, 'M', 'شه'), + (0xFD33, 'M', 'طم'), + (0xFD34, 'M', 'سج'), + (0xFD35, 'M', 'سح'), + (0xFD36, 'M', 'سخ'), + (0xFD37, 'M', 'شج'), + (0xFD38, 'M', 'شح'), + (0xFD39, 'M', 'شخ'), + (0xFD3A, 'M', 'طم'), + (0xFD3B, 'M', 'ظم'), + (0xFD3C, 'M', 'اً'), + (0xFD3E, 'V'), + (0xFD50, 'M', 'تجم'), + (0xFD51, 'M', 'تحج'), + (0xFD53, 'M', 'تحم'), + (0xFD54, 'M', 'تخم'), + (0xFD55, 'M', 'تمج'), + (0xFD56, 'M', 'تمح'), + (0xFD57, 'M', 'تمخ'), + (0xFD58, 'M', 'جمح'), + (0xFD5A, 'M', 'حمÙ'), + (0xFD5B, 'M', 'حمى'), + (0xFD5C, 'M', 'سحج'), + (0xFD5D, 'M', 'سجح'), + (0xFD5E, 'M', 'سجى'), + (0xFD5F, 'M', 'سمح'), + (0xFD61, 'M', 'سمج'), + (0xFD62, 'M', 'سمم'), + (0xFD64, 'M', 'صحح'), + (0xFD66, 'M', 'صمم'), + (0xFD67, 'M', 'شحم'), + (0xFD69, 'M', 'شجÙ'), + (0xFD6A, 'M', 'شمخ'), + (0xFD6C, 'M', 'شمم'), + (0xFD6E, 'M', 'ضحى'), + (0xFD6F, 'M', 'ضخم'), + (0xFD71, 'M', 'طمح'), + (0xFD73, 'M', 'طمم'), + (0xFD74, 'M', 'طمÙ'), + (0xFD75, 'M', 'عجم'), + (0xFD76, 'M', 'عمم'), + (0xFD78, 'M', 'عمى'), + (0xFD79, 'M', 'غمم'), + (0xFD7A, 'M', 'غمÙ'), + (0xFD7B, 'M', 'غمى'), + (0xFD7C, 'M', 'Ùخم'), + (0xFD7E, 'M', 'قمح'), + (0xFD7F, 'M', 'قمم'), + (0xFD80, 'M', 'لحم'), + (0xFD81, 'M', 'لحÙ'), + (0xFD82, 'M', 'لحى'), + (0xFD83, 'M', 'لجج'), + (0xFD85, 'M', 'لخم'), + (0xFD87, 'M', 'لمح'), + (0xFD89, 'M', 'محج'), + (0xFD8A, 'M', 'محم'), + (0xFD8B, 'M', 'محÙ'), + (0xFD8C, 'M', 'مجح'), + (0xFD8D, 'M', 'مجم'), + (0xFD8E, 'M', 'مخج'), + (0xFD8F, 'M', 'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', 'مجخ'), + (0xFD93, 'M', 'همج'), + (0xFD94, 'M', 'همم'), + (0xFD95, 'M', 'نحم'), + (0xFD96, 'M', 'نحى'), + (0xFD97, 'M', 'نجم'), + (0xFD99, 'M', 'نجى'), + (0xFD9A, 'M', 'نمÙ'), + (0xFD9B, 'M', 'نمى'), + (0xFD9C, 'M', 'Ùمم'), + (0xFD9E, 'M', 'بخÙ'), + (0xFD9F, 'M', 'تجÙ'), + (0xFDA0, 'M', 'تجى'), + (0xFDA1, 'M', 'تخÙ'), + (0xFDA2, 'M', 'تخى'), + (0xFDA3, 'M', 'تمÙ'), + (0xFDA4, 'M', 'تمى'), + (0xFDA5, 'M', 'جمÙ'), + (0xFDA6, 'M', 'جحى'), + ] + +def _seg_49() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFDA7, 'M', 'جمى'), + (0xFDA8, 'M', 'سخى'), + (0xFDA9, 'M', 'صحÙ'), + (0xFDAA, 'M', 'شحÙ'), + (0xFDAB, 'M', 'ضحÙ'), + (0xFDAC, 'M', 'لجÙ'), + (0xFDAD, 'M', 'لمÙ'), + (0xFDAE, 'M', 'ÙØ­Ù'), + (0xFDAF, 'M', 'ÙجÙ'), + (0xFDB0, 'M', 'ÙÙ…Ù'), + (0xFDB1, 'M', 'ممÙ'), + (0xFDB2, 'M', 'قمÙ'), + (0xFDB3, 'M', 'نحÙ'), + (0xFDB4, 'M', 'قمح'), + (0xFDB5, 'M', 'لحم'), + (0xFDB6, 'M', 'عمÙ'), + (0xFDB7, 'M', 'كمÙ'), + (0xFDB8, 'M', 'نجح'), + (0xFDB9, 'M', 'مخÙ'), + (0xFDBA, 'M', 'لجم'), + (0xFDBB, 'M', 'كمم'), + (0xFDBC, 'M', 'لجم'), + (0xFDBD, 'M', 'نجح'), + (0xFDBE, 'M', 'جحÙ'), + (0xFDBF, 'M', 'حجÙ'), + (0xFDC0, 'M', 'مجÙ'), + (0xFDC1, 'M', 'ÙÙ…Ù'), + (0xFDC2, 'M', 'بحÙ'), + (0xFDC3, 'M', 'كمم'), + (0xFDC4, 'M', 'عجم'), + (0xFDC5, 'M', 'صمم'), + (0xFDC6, 'M', 'سخÙ'), + (0xFDC7, 'M', 'نجÙ'), + (0xFDC8, 'X'), + (0xFDCF, 'V'), + (0xFDD0, 'X'), + (0xFDF0, 'M', 'صلے'), + (0xFDF1, 'M', 'قلے'), + (0xFDF2, 'M', 'الله'), + (0xFDF3, 'M', 'اكبر'), + (0xFDF4, 'M', 'محمد'), + (0xFDF5, 'M', 'صلعم'), + (0xFDF6, 'M', 'رسول'), + (0xFDF7, 'M', 'علÙÙ‡'), + (0xFDF8, 'M', 'وسلم'), + (0xFDF9, 'M', 'صلى'), + (0xFDFA, '3', 'صلى الله علÙÙ‡ وسلم'), + (0xFDFB, '3', 'جل جلاله'), + (0xFDFC, 'M', 'ریال'), + (0xFDFD, 'V'), + (0xFE00, 'I'), + (0xFE10, '3', ','), + (0xFE11, 'M', 'ă€'), + (0xFE12, 'X'), + (0xFE13, '3', ':'), + (0xFE14, '3', ';'), + (0xFE15, '3', '!'), + (0xFE16, '3', '?'), + (0xFE17, 'M', '〖'), + (0xFE18, 'M', '〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', '—'), + (0xFE32, 'M', '–'), + (0xFE33, '3', '_'), + (0xFE35, '3', '('), + (0xFE36, '3', ')'), + (0xFE37, '3', '{'), + (0xFE38, '3', '}'), + (0xFE39, 'M', '〔'), + (0xFE3A, 'M', '〕'), + (0xFE3B, 'M', 'ă€'), + (0xFE3C, 'M', '】'), + (0xFE3D, 'M', 'ă€'), + (0xFE3E, 'M', '》'), + (0xFE3F, 'M', 'ă€ˆ'), + (0xFE40, 'M', '〉'), + (0xFE41, 'M', 'ă€Œ'), + (0xFE42, 'M', 'ă€'), + (0xFE43, 'M', 'ă€'), + (0xFE44, 'M', 'ă€'), + (0xFE45, 'V'), + (0xFE47, '3', '['), + (0xFE48, '3', ']'), + (0xFE49, '3', ' ̀…'), + (0xFE4D, '3', '_'), + (0xFE50, '3', ','), + (0xFE51, 'M', 'ă€'), + (0xFE52, 'X'), + (0xFE54, '3', ';'), + (0xFE55, '3', ':'), + (0xFE56, '3', '?'), + (0xFE57, '3', '!'), + (0xFE58, 'M', '—'), + (0xFE59, '3', '('), + (0xFE5A, '3', ')'), + (0xFE5B, '3', '{'), + (0xFE5C, '3', '}'), + (0xFE5D, 'M', '〔'), + ] + +def _seg_50() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFE5E, 'M', '〕'), + (0xFE5F, '3', '#'), + (0xFE60, '3', '&'), + (0xFE61, '3', '*'), + (0xFE62, '3', '+'), + (0xFE63, 'M', '-'), + (0xFE64, '3', '<'), + (0xFE65, '3', '>'), + (0xFE66, '3', '='), + (0xFE67, 'X'), + (0xFE68, '3', '\\'), + (0xFE69, '3', '$'), + (0xFE6A, '3', '%'), + (0xFE6B, '3', '@'), + (0xFE6C, 'X'), + (0xFE70, '3', ' Ù‹'), + (0xFE71, 'M', 'ـً'), + (0xFE72, '3', ' ÙŒ'), + (0xFE73, 'V'), + (0xFE74, '3', ' Ù'), + (0xFE75, 'X'), + (0xFE76, '3', ' Ù'), + (0xFE77, 'M', 'Ù€Ù'), + (0xFE78, '3', ' Ù'), + (0xFE79, 'M', 'Ù€Ù'), + (0xFE7A, '3', ' Ù'), + (0xFE7B, 'M', 'Ù€Ù'), + (0xFE7C, '3', ' Ù‘'), + (0xFE7D, 'M', 'ـّ'), + (0xFE7E, '3', ' Ù’'), + (0xFE7F, 'M', 'ـْ'), + (0xFE80, 'M', 'Ø¡'), + (0xFE81, 'M', 'Ø¢'), + (0xFE83, 'M', 'Ø£'), + (0xFE85, 'M', 'ؤ'), + (0xFE87, 'M', 'Ø¥'), + (0xFE89, 'M', 'ئ'), + (0xFE8D, 'M', 'ا'), + (0xFE8F, 'M', 'ب'), + (0xFE93, 'M', 'Ø©'), + (0xFE95, 'M', 'ت'), + (0xFE99, 'M', 'Ø«'), + (0xFE9D, 'M', 'ج'), + (0xFEA1, 'M', 'Ø­'), + (0xFEA5, 'M', 'Ø®'), + (0xFEA9, 'M', 'د'), + (0xFEAB, 'M', 'Ø°'), + (0xFEAD, 'M', 'ر'), + (0xFEAF, 'M', 'ز'), + (0xFEB1, 'M', 'س'), + (0xFEB5, 'M', 'Ø´'), + (0xFEB9, 'M', 'ص'), + (0xFEBD, 'M', 'ض'), + (0xFEC1, 'M', 'Ø·'), + (0xFEC5, 'M', 'ظ'), + (0xFEC9, 'M', 'ع'), + (0xFECD, 'M', 'غ'), + (0xFED1, 'M', 'Ù'), + (0xFED5, 'M', 'Ù‚'), + (0xFED9, 'M', 'Ùƒ'), + (0xFEDD, 'M', 'Ù„'), + (0xFEE1, 'M', 'Ù…'), + (0xFEE5, 'M', 'Ù†'), + (0xFEE9, 'M', 'Ù‡'), + (0xFEED, 'M', 'Ùˆ'), + (0xFEEF, 'M', 'Ù‰'), + (0xFEF1, 'M', 'Ù'), + (0xFEF5, 'M', 'لآ'), + (0xFEF7, 'M', 'لأ'), + (0xFEF9, 'M', 'لإ'), + (0xFEFB, 'M', 'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', '!'), + (0xFF02, '3', '"'), + (0xFF03, '3', '#'), + (0xFF04, '3', '$'), + (0xFF05, '3', '%'), + (0xFF06, '3', '&'), + (0xFF07, '3', '\''), + (0xFF08, '3', '('), + (0xFF09, '3', ')'), + (0xFF0A, '3', '*'), + (0xFF0B, '3', '+'), + (0xFF0C, '3', ','), + (0xFF0D, 'M', '-'), + (0xFF0E, 'M', '.'), + (0xFF0F, '3', '/'), + (0xFF10, 'M', '0'), + (0xFF11, 'M', '1'), + (0xFF12, 'M', '2'), + (0xFF13, 'M', '3'), + (0xFF14, 'M', '4'), + (0xFF15, 'M', '5'), + (0xFF16, 'M', '6'), + (0xFF17, 'M', '7'), + (0xFF18, 'M', '8'), + (0xFF19, 'M', '9'), + (0xFF1A, '3', ':'), + ] + +def _seg_51() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF1B, '3', ';'), + (0xFF1C, '3', '<'), + (0xFF1D, '3', '='), + (0xFF1E, '3', '>'), + (0xFF1F, '3', '?'), + (0xFF20, '3', '@'), + (0xFF21, 'M', 'a'), + (0xFF22, 'M', 'b'), + (0xFF23, 'M', 'c'), + (0xFF24, 'M', 'd'), + (0xFF25, 'M', 'e'), + (0xFF26, 'M', 'f'), + (0xFF27, 'M', 'g'), + (0xFF28, 'M', 'h'), + (0xFF29, 'M', 'i'), + (0xFF2A, 'M', 'j'), + (0xFF2B, 'M', 'k'), + (0xFF2C, 'M', 'l'), + (0xFF2D, 'M', 'm'), + (0xFF2E, 'M', 'n'), + (0xFF2F, 'M', 'o'), + (0xFF30, 'M', 'p'), + (0xFF31, 'M', 'q'), + (0xFF32, 'M', 'r'), + (0xFF33, 'M', 's'), + (0xFF34, 'M', 't'), + (0xFF35, 'M', 'u'), + (0xFF36, 'M', 'v'), + (0xFF37, 'M', 'w'), + (0xFF38, 'M', 'x'), + (0xFF39, 'M', 'y'), + (0xFF3A, 'M', 'z'), + (0xFF3B, '3', '['), + (0xFF3C, '3', '\\'), + (0xFF3D, '3', ']'), + (0xFF3E, '3', '^'), + (0xFF3F, '3', '_'), + (0xFF40, '3', '`'), + (0xFF41, 'M', 'a'), + (0xFF42, 'M', 'b'), + (0xFF43, 'M', 'c'), + (0xFF44, 'M', 'd'), + (0xFF45, 'M', 'e'), + (0xFF46, 'M', 'f'), + (0xFF47, 'M', 'g'), + (0xFF48, 'M', 'h'), + (0xFF49, 'M', 'i'), + (0xFF4A, 'M', 'j'), + (0xFF4B, 'M', 'k'), + (0xFF4C, 'M', 'l'), + (0xFF4D, 'M', 'm'), + (0xFF4E, 'M', 'n'), + (0xFF4F, 'M', 'o'), + (0xFF50, 'M', 'p'), + (0xFF51, 'M', 'q'), + (0xFF52, 'M', 'r'), + (0xFF53, 'M', 's'), + (0xFF54, 'M', 't'), + (0xFF55, 'M', 'u'), + (0xFF56, 'M', 'v'), + (0xFF57, 'M', 'w'), + (0xFF58, 'M', 'x'), + (0xFF59, 'M', 'y'), + (0xFF5A, 'M', 'z'), + (0xFF5B, '3', '{'), + (0xFF5C, '3', '|'), + (0xFF5D, '3', '}'), + (0xFF5E, '3', '~'), + (0xFF5F, 'M', '⦅'), + (0xFF60, 'M', '⦆'), + (0xFF61, 'M', '.'), + (0xFF62, 'M', 'ă€Œ'), + (0xFF63, 'M', 'ă€'), + (0xFF64, 'M', 'ă€'), + (0xFF65, 'M', 'ăƒ»'), + (0xFF66, 'M', 'ăƒ²'), + (0xFF67, 'M', 'ă‚¡'), + (0xFF68, 'M', 'ă‚£'), + (0xFF69, 'M', 'ă‚¥'), + (0xFF6A, 'M', 'ェ'), + (0xFF6B, 'M', 'ă‚©'), + (0xFF6C, 'M', 'ăƒ£'), + (0xFF6D, 'M', 'ăƒ¥'), + (0xFF6E, 'M', 'ăƒ§'), + (0xFF6F, 'M', 'ăƒƒ'), + (0xFF70, 'M', 'ăƒ¼'), + (0xFF71, 'M', 'ă‚¢'), + (0xFF72, 'M', 'イ'), + (0xFF73, 'M', 'ウ'), + (0xFF74, 'M', 'エ'), + (0xFF75, 'M', 'ă‚ª'), + (0xFF76, 'M', 'ă‚«'), + (0xFF77, 'M', 'ă‚­'), + (0xFF78, 'M', 'ă‚¯'), + (0xFF79, 'M', 'ケ'), + (0xFF7A, 'M', 'ă‚³'), + (0xFF7B, 'M', 'サ'), + (0xFF7C, 'M', 'ă‚·'), + (0xFF7D, 'M', 'ă‚¹'), + (0xFF7E, 'M', 'ă‚»'), + ] + +def _seg_52() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF7F, 'M', 'ă‚½'), + (0xFF80, 'M', 'ă‚¿'), + (0xFF81, 'M', 'ăƒ'), + (0xFF82, 'M', 'ăƒ„'), + (0xFF83, 'M', 'ăƒ†'), + (0xFF84, 'M', 'ăƒˆ'), + (0xFF85, 'M', 'ăƒ'), + (0xFF86, 'M', 'ăƒ‹'), + (0xFF87, 'M', 'ăƒŒ'), + (0xFF88, 'M', 'ăƒ'), + (0xFF89, 'M', 'ăƒ'), + (0xFF8A, 'M', 'ăƒ'), + (0xFF8B, 'M', 'ăƒ’'), + (0xFF8C, 'M', 'ăƒ•'), + (0xFF8D, 'M', 'ăƒ˜'), + (0xFF8E, 'M', 'ăƒ›'), + (0xFF8F, 'M', 'ăƒ'), + (0xFF90, 'M', 'ăƒŸ'), + (0xFF91, 'M', 'ăƒ '), + (0xFF92, 'M', 'ăƒ¡'), + (0xFF93, 'M', 'ăƒ¢'), + (0xFF94, 'M', 'ăƒ¤'), + (0xFF95, 'M', 'ăƒ¦'), + (0xFF96, 'M', 'ăƒ¨'), + (0xFF97, 'M', 'ăƒ©'), + (0xFF98, 'M', 'ăƒª'), + (0xFF99, 'M', 'ăƒ«'), + (0xFF9A, 'M', 'ăƒ¬'), + (0xFF9B, 'M', 'ăƒ­'), + (0xFF9C, 'M', 'ăƒ¯'), + (0xFF9D, 'M', 'ăƒ³'), + (0xFF9E, 'M', 'ă‚™'), + (0xFF9F, 'M', 'ă‚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', 'á„€'), + (0xFFA2, 'M', 'á„'), + (0xFFA3, 'M', 'ᆪ'), + (0xFFA4, 'M', 'á„‚'), + (0xFFA5, 'M', 'ᆬ'), + (0xFFA6, 'M', 'ᆭ'), + (0xFFA7, 'M', 'ᄃ'), + (0xFFA8, 'M', 'á„„'), + (0xFFA9, 'M', 'á„…'), + (0xFFAA, 'M', 'ᆰ'), + (0xFFAB, 'M', 'ᆱ'), + (0xFFAC, 'M', 'ᆲ'), + (0xFFAD, 'M', 'ᆳ'), + (0xFFAE, 'M', 'ᆴ'), + (0xFFAF, 'M', 'ᆵ'), + (0xFFB0, 'M', 'á„'), + (0xFFB1, 'M', 'ᄆ'), + (0xFFB2, 'M', 'ᄇ'), + (0xFFB3, 'M', 'ᄈ'), + (0xFFB4, 'M', 'á„¡'), + (0xFFB5, 'M', 'ᄉ'), + (0xFFB6, 'M', 'á„'), + (0xFFB7, 'M', 'á„‹'), + (0xFFB8, 'M', 'á„Œ'), + (0xFFB9, 'M', 'á„'), + (0xFFBA, 'M', 'á„'), + (0xFFBB, 'M', 'á„'), + (0xFFBC, 'M', 'á„'), + (0xFFBD, 'M', 'á„‘'), + (0xFFBE, 'M', 'á„’'), + (0xFFBF, 'X'), + (0xFFC2, 'M', 'á…¡'), + (0xFFC3, 'M', 'á…¢'), + (0xFFC4, 'M', 'á…£'), + (0xFFC5, 'M', 'á…¤'), + (0xFFC6, 'M', 'á…¥'), + (0xFFC7, 'M', 'á…¦'), + (0xFFC8, 'X'), + (0xFFCA, 'M', 'á…§'), + (0xFFCB, 'M', 'á…¨'), + (0xFFCC, 'M', 'á…©'), + (0xFFCD, 'M', 'á…ª'), + (0xFFCE, 'M', 'á…«'), + (0xFFCF, 'M', 'á…¬'), + (0xFFD0, 'X'), + (0xFFD2, 'M', 'á…­'), + (0xFFD3, 'M', 'á…®'), + (0xFFD4, 'M', 'á…¯'), + (0xFFD5, 'M', 'á…°'), + (0xFFD6, 'M', 'á…±'), + (0xFFD7, 'M', 'á…²'), + (0xFFD8, 'X'), + (0xFFDA, 'M', 'á…³'), + (0xFFDB, 'M', 'á…´'), + (0xFFDC, 'M', 'á…µ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', '¢'), + (0xFFE1, 'M', '£'), + (0xFFE2, 'M', '¬'), + (0xFFE3, '3', ' ̀„'), + (0xFFE4, 'M', '¦'), + (0xFFE5, 'M', 'Â¥'), + (0xFFE6, 'M', 'â‚©'), + (0xFFE7, 'X'), + (0xFFE8, 'M', '│'), + (0xFFE9, 'M', 'â†'), + ] + +def _seg_53() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFFEA, 'M', '↑'), + (0xFFEB, 'M', '→'), + (0xFFEC, 'M', '↓'), + (0xFFED, 'M', 'â– '), + (0xFFEE, 'M', 'â—‹'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018F, 'X'), + (0x10190, 'V'), + (0x1019D, 'X'), + (0x101A0, 'V'), + (0x101A1, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x102E0, 'V'), + (0x102FC, 'X'), + (0x10300, 'V'), + (0x10324, 'X'), + (0x1032D, 'V'), + (0x1034B, 'X'), + (0x10350, 'V'), + (0x1037B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', 'đ¨'), + (0x10401, 'M', 'đ©'), + (0x10402, 'M', 'đª'), + (0x10403, 'M', 'đ«'), + (0x10404, 'M', 'đ¬'), + (0x10405, 'M', 'đ­'), + (0x10406, 'M', 'đ®'), + (0x10407, 'M', 'đ¯'), + (0x10408, 'M', 'đ°'), + (0x10409, 'M', 'đ±'), + (0x1040A, 'M', 'đ²'), + (0x1040B, 'M', 'đ³'), + (0x1040C, 'M', 'đ´'), + (0x1040D, 'M', 'đµ'), + (0x1040E, 'M', 'đ¶'), + (0x1040F, 'M', 'đ·'), + (0x10410, 'M', 'đ¸'), + (0x10411, 'M', 'đ¹'), + (0x10412, 'M', 'đº'), + (0x10413, 'M', 'đ»'), + (0x10414, 'M', 'đ¼'), + (0x10415, 'M', 'đ½'), + (0x10416, 'M', 'đ¾'), + (0x10417, 'M', 'đ¿'), + (0x10418, 'M', 'đ‘€'), + (0x10419, 'M', 'đ‘'), + (0x1041A, 'M', 'đ‘‚'), + (0x1041B, 'M', 'đ‘ƒ'), + (0x1041C, 'M', 'đ‘„'), + (0x1041D, 'M', 'đ‘…'), + (0x1041E, 'M', 'đ‘†'), + (0x1041F, 'M', 'đ‘‡'), + (0x10420, 'M', 'đ‘ˆ'), + (0x10421, 'M', 'đ‘‰'), + (0x10422, 'M', 'đ‘'), + (0x10423, 'M', 'đ‘‹'), + (0x10424, 'M', 'đ‘Œ'), + (0x10425, 'M', 'đ‘'), + (0x10426, 'M', 'đ‘'), + (0x10427, 'M', 'đ‘'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', 'đ“˜'), + (0x104B1, 'M', 'đ“™'), + (0x104B2, 'M', 'đ“'), + (0x104B3, 'M', 'đ“›'), + (0x104B4, 'M', 'đ“œ'), + (0x104B5, 'M', 'đ“'), + ] + +def _seg_54() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x104B6, 'M', 'đ“'), + (0x104B7, 'M', 'đ“Ÿ'), + (0x104B8, 'M', 'đ“ '), + (0x104B9, 'M', 'đ“¡'), + (0x104BA, 'M', 'đ“¢'), + (0x104BB, 'M', 'đ“£'), + (0x104BC, 'M', 'đ“¤'), + (0x104BD, 'M', 'đ“¥'), + (0x104BE, 'M', 'đ“¦'), + (0x104BF, 'M', 'đ“§'), + (0x104C0, 'M', 'đ“¨'), + (0x104C1, 'M', 'đ“©'), + (0x104C2, 'M', 'đ“ª'), + (0x104C3, 'M', 'đ“«'), + (0x104C4, 'M', 'đ“¬'), + (0x104C5, 'M', 'đ“­'), + (0x104C6, 'M', 'đ“®'), + (0x104C7, 'M', 'đ“¯'), + (0x104C8, 'M', 'đ“°'), + (0x104C9, 'M', 'đ“±'), + (0x104CA, 'M', 'đ“²'), + (0x104CB, 'M', 'đ“³'), + (0x104CC, 'M', 'đ“´'), + (0x104CD, 'M', 'đ“µ'), + (0x104CE, 'M', 'đ“¶'), + (0x104CF, 'M', 'đ“·'), + (0x104D0, 'M', 'đ“¸'), + (0x104D1, 'M', 'đ“¹'), + (0x104D2, 'M', 'đ“º'), + (0x104D3, 'M', 'đ“»'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'M', 'đ–—'), + (0x10571, 'M', 'đ–˜'), + (0x10572, 'M', 'đ–™'), + (0x10573, 'M', 'đ–'), + (0x10574, 'M', 'đ–›'), + (0x10575, 'M', 'đ–œ'), + (0x10576, 'M', 'đ–'), + (0x10577, 'M', 'đ–'), + (0x10578, 'M', 'đ–Ÿ'), + (0x10579, 'M', 'đ– '), + (0x1057A, 'M', 'đ–¡'), + (0x1057B, 'X'), + (0x1057C, 'M', 'đ–£'), + (0x1057D, 'M', 'đ–¤'), + (0x1057E, 'M', 'đ–¥'), + (0x1057F, 'M', 'đ–¦'), + (0x10580, 'M', 'đ–§'), + (0x10581, 'M', 'đ–¨'), + (0x10582, 'M', 'đ–©'), + (0x10583, 'M', 'đ–ª'), + (0x10584, 'M', 'đ–«'), + (0x10585, 'M', 'đ–¬'), + (0x10586, 'M', 'đ–­'), + (0x10587, 'M', 'đ–®'), + (0x10588, 'M', 'đ–¯'), + (0x10589, 'M', 'đ–°'), + (0x1058A, 'M', 'đ–±'), + (0x1058B, 'X'), + (0x1058C, 'M', 'đ–³'), + (0x1058D, 'M', 'đ–´'), + (0x1058E, 'M', 'đ–µ'), + (0x1058F, 'M', 'đ–¶'), + (0x10590, 'M', 'đ–·'), + (0x10591, 'M', 'đ–¸'), + (0x10592, 'M', 'đ–¹'), + (0x10593, 'X'), + (0x10594, 'M', 'đ–»'), + (0x10595, 'M', 'đ–¼'), + (0x10596, 'X'), + (0x10597, 'V'), + (0x105A2, 'X'), + (0x105A3, 'V'), + (0x105B2, 'X'), + (0x105B3, 'V'), + (0x105BA, 'X'), + (0x105BB, 'V'), + (0x105BD, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10780, 'V'), + (0x10781, 'M', 'Ë'), + (0x10782, 'M', 'Ë‘'), + (0x10783, 'M', 'æ'), + (0x10784, 'M', 'Ê™'), + (0x10785, 'M', 'É“'), + (0x10786, 'X'), + (0x10787, 'M', 'Ê£'), + (0x10788, 'M', 'ê­¦'), + ] + +def _seg_55() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x10789, 'M', 'Ê¥'), + (0x1078A, 'M', 'ʤ'), + (0x1078B, 'M', 'É–'), + (0x1078C, 'M', 'É—'), + (0x1078D, 'M', 'ᶑ'), + (0x1078E, 'M', 'ɘ'), + (0x1078F, 'M', 'É'), + (0x10790, 'M', 'Ê©'), + (0x10791, 'M', 'ɤ'), + (0x10792, 'M', 'É¢'), + (0x10793, 'M', 'É '), + (0x10794, 'M', 'Ê›'), + (0x10795, 'M', 'ħ'), + (0x10796, 'M', 'Êœ'), + (0x10797, 'M', 'ɧ'), + (0x10798, 'M', 'Ê„'), + (0x10799, 'M', 'ʪ'), + (0x1079A, 'M', 'Ê«'), + (0x1079B, 'M', 'ɬ'), + (0x1079C, 'M', 'đ¼„'), + (0x1079D, 'M', 'ê'), + (0x1079E, 'M', 'É®'), + (0x1079F, 'M', 'đ¼…'), + (0x107A0, 'M', 'Ê'), + (0x107A1, 'M', 'đ¼†'), + (0x107A2, 'M', 'ø'), + (0x107A3, 'M', 'ɶ'), + (0x107A4, 'M', 'É·'), + (0x107A5, 'M', 'q'), + (0x107A6, 'M', 'ɺ'), + (0x107A7, 'M', 'đ¼ˆ'), + (0x107A8, 'M', 'ɽ'), + (0x107A9, 'M', 'ɾ'), + (0x107AA, 'M', 'Ê€'), + (0x107AB, 'M', 'ʨ'), + (0x107AC, 'M', 'ʦ'), + (0x107AD, 'M', 'ê­§'), + (0x107AE, 'M', 'ʧ'), + (0x107AF, 'M', 'ʈ'), + (0x107B0, 'M', 'â±±'), + (0x107B1, 'X'), + (0x107B2, 'M', 'Ê'), + (0x107B3, 'M', 'Ê¡'), + (0x107B4, 'M', 'Ê¢'), + (0x107B5, 'M', 'ʘ'), + (0x107B6, 'M', 'Ç€'), + (0x107B7, 'M', 'Ç'), + (0x107B8, 'M', 'Ç‚'), + (0x107B9, 'M', 'đ¼'), + (0x107BA, 'M', 'đ¼'), + (0x107BB, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x1089F, 'X'), + (0x108A7, 'V'), + (0x108B0, 'X'), + (0x108E0, 'V'), + (0x108F3, 'X'), + (0x108F4, 'V'), + (0x108F6, 'X'), + (0x108FB, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BC, 'V'), + (0x109D0, 'X'), + (0x109D2, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A36, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A49, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10AA0, 'X'), + (0x10AC0, 'V'), + ] + +def _seg_56() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x10AE7, 'X'), + (0x10AEB, 'V'), + (0x10AF7, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B92, 'X'), + (0x10B99, 'V'), + (0x10B9D, 'X'), + (0x10BA9, 'V'), + (0x10BB0, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10C80, 'M', 'đ³€'), + (0x10C81, 'M', 'đ³'), + (0x10C82, 'M', 'đ³‚'), + (0x10C83, 'M', 'đ³ƒ'), + (0x10C84, 'M', 'đ³„'), + (0x10C85, 'M', 'đ³…'), + (0x10C86, 'M', 'đ³†'), + (0x10C87, 'M', 'đ³‡'), + (0x10C88, 'M', 'đ³ˆ'), + (0x10C89, 'M', 'đ³‰'), + (0x10C8A, 'M', 'đ³'), + (0x10C8B, 'M', 'đ³‹'), + (0x10C8C, 'M', 'đ³Œ'), + (0x10C8D, 'M', 'đ³'), + (0x10C8E, 'M', 'đ³'), + (0x10C8F, 'M', 'đ³'), + (0x10C90, 'M', 'đ³'), + (0x10C91, 'M', 'đ³‘'), + (0x10C92, 'M', 'đ³’'), + (0x10C93, 'M', 'đ³“'), + (0x10C94, 'M', 'đ³”'), + (0x10C95, 'M', 'đ³•'), + (0x10C96, 'M', 'đ³–'), + (0x10C97, 'M', 'đ³—'), + (0x10C98, 'M', 'đ³˜'), + (0x10C99, 'M', 'đ³™'), + (0x10C9A, 'M', 'đ³'), + (0x10C9B, 'M', 'đ³›'), + (0x10C9C, 'M', 'đ³œ'), + (0x10C9D, 'M', 'đ³'), + (0x10C9E, 'M', 'đ³'), + (0x10C9F, 'M', 'đ³Ÿ'), + (0x10CA0, 'M', 'đ³ '), + (0x10CA1, 'M', 'đ³¡'), + (0x10CA2, 'M', 'đ³¢'), + (0x10CA3, 'M', 'đ³£'), + (0x10CA4, 'M', 'đ³¤'), + (0x10CA5, 'M', 'đ³¥'), + (0x10CA6, 'M', 'đ³¦'), + (0x10CA7, 'M', 'đ³§'), + (0x10CA8, 'M', 'đ³¨'), + (0x10CA9, 'M', 'đ³©'), + (0x10CAA, 'M', 'đ³ª'), + (0x10CAB, 'M', 'đ³«'), + (0x10CAC, 'M', 'đ³¬'), + (0x10CAD, 'M', 'đ³­'), + (0x10CAE, 'M', 'đ³®'), + (0x10CAF, 'M', 'đ³¯'), + (0x10CB0, 'M', 'đ³°'), + (0x10CB1, 'M', 'đ³±'), + (0x10CB2, 'M', 'đ³²'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D28, 'X'), + (0x10D30, 'V'), + (0x10D3A, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x10E80, 'V'), + (0x10EAA, 'X'), + (0x10EAB, 'V'), + (0x10EAE, 'X'), + (0x10EB0, 'V'), + (0x10EB2, 'X'), + (0x10EFD, 'V'), + (0x10F28, 'X'), + (0x10F30, 'V'), + (0x10F5A, 'X'), + (0x10F70, 'V'), + (0x10F8A, 'X'), + (0x10FB0, 'V'), + (0x10FCC, 'X'), + (0x10FE0, 'V'), + (0x10FF7, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11076, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + ] + +def _seg_57() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x110C3, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11148, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + (0x11213, 'V'), + (0x11242, 'X'), + (0x11280, 'V'), + (0x11287, 'X'), + (0x11288, 'V'), + (0x11289, 'X'), + (0x1128A, 'V'), + (0x1128E, 'X'), + (0x1128F, 'V'), + (0x1129E, 'X'), + (0x1129F, 'V'), + (0x112AA, 'X'), + (0x112B0, 'V'), + (0x112EB, 'X'), + (0x112F0, 'V'), + (0x112FA, 'X'), + (0x11300, 'V'), + (0x11304, 'X'), + (0x11305, 'V'), + (0x1130D, 'X'), + (0x1130F, 'V'), + (0x11311, 'X'), + (0x11313, 'V'), + (0x11329, 'X'), + (0x1132A, 'V'), + (0x11331, 'X'), + (0x11332, 'V'), + (0x11334, 'X'), + (0x11335, 'V'), + (0x1133A, 'X'), + (0x1133B, 'V'), + (0x11345, 'X'), + (0x11347, 'V'), + (0x11349, 'X'), + (0x1134B, 'V'), + (0x1134E, 'X'), + (0x11350, 'V'), + (0x11351, 'X'), + (0x11357, 'V'), + (0x11358, 'X'), + (0x1135D, 'V'), + (0x11364, 'X'), + (0x11366, 'V'), + (0x1136D, 'X'), + (0x11370, 'V'), + (0x11375, 'X'), + (0x11400, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + (0x11462, 'X'), + (0x11480, 'V'), + (0x114C8, 'X'), + (0x114D0, 'V'), + (0x114DA, 'X'), + (0x11580, 'V'), + (0x115B6, 'X'), + (0x115B8, 'V'), + (0x115DE, 'X'), + (0x11600, 'V'), + (0x11645, 'X'), + (0x11650, 'V'), + (0x1165A, 'X'), + (0x11660, 'V'), + (0x1166D, 'X'), + (0x11680, 'V'), + (0x116BA, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171B, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11747, 'X'), + (0x11800, 'V'), + (0x1183C, 'X'), + (0x118A0, 'M', 'đ‘£€'), + (0x118A1, 'M', 'đ‘£'), + (0x118A2, 'M', 'đ‘£‚'), + (0x118A3, 'M', 'đ‘£ƒ'), + (0x118A4, 'M', 'đ‘£„'), + (0x118A5, 'M', 'đ‘£…'), + (0x118A6, 'M', 'đ‘£†'), + ] + +def _seg_58() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x118A7, 'M', 'đ‘£‡'), + (0x118A8, 'M', 'đ‘£ˆ'), + (0x118A9, 'M', 'đ‘£‰'), + (0x118AA, 'M', 'đ‘£'), + (0x118AB, 'M', 'đ‘£‹'), + (0x118AC, 'M', 'đ‘£Œ'), + (0x118AD, 'M', 'đ‘£'), + (0x118AE, 'M', 'đ‘£'), + (0x118AF, 'M', 'đ‘£'), + (0x118B0, 'M', 'đ‘£'), + (0x118B1, 'M', 'đ‘£‘'), + (0x118B2, 'M', 'đ‘£’'), + (0x118B3, 'M', 'đ‘£“'), + (0x118B4, 'M', 'đ‘£”'), + (0x118B5, 'M', 'đ‘£•'), + (0x118B6, 'M', 'đ‘£–'), + (0x118B7, 'M', 'đ‘£—'), + (0x118B8, 'M', 'đ‘£˜'), + (0x118B9, 'M', 'đ‘£™'), + (0x118BA, 'M', 'đ‘£'), + (0x118BB, 'M', 'đ‘£›'), + (0x118BC, 'M', 'đ‘£œ'), + (0x118BD, 'M', 'đ‘£'), + (0x118BE, 'M', 'đ‘£'), + (0x118BF, 'M', 'đ‘£Ÿ'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11907, 'X'), + (0x11909, 'V'), + (0x1190A, 'X'), + (0x1190C, 'V'), + (0x11914, 'X'), + (0x11915, 'V'), + (0x11917, 'X'), + (0x11918, 'V'), + (0x11936, 'X'), + (0x11937, 'V'), + (0x11939, 'X'), + (0x1193B, 'V'), + (0x11947, 'X'), + (0x11950, 'V'), + (0x1195A, 'X'), + (0x119A0, 'V'), + (0x119A8, 'X'), + (0x119AA, 'V'), + (0x119D8, 'X'), + (0x119DA, 'V'), + (0x119E5, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11AA3, 'X'), + (0x11AB0, 'V'), + (0x11AF9, 'X'), + (0x11B00, 'V'), + (0x11B0A, 'X'), + (0x11C00, 'V'), + (0x11C09, 'X'), + (0x11C0A, 'V'), + (0x11C37, 'X'), + (0x11C38, 'V'), + (0x11C46, 'X'), + (0x11C50, 'V'), + (0x11C6D, 'X'), + (0x11C70, 'V'), + (0x11C90, 'X'), + (0x11C92, 'V'), + (0x11CA8, 'X'), + (0x11CA9, 'V'), + (0x11CB7, 'X'), + (0x11D00, 'V'), + (0x11D07, 'X'), + (0x11D08, 'V'), + (0x11D0A, 'X'), + (0x11D0B, 'V'), + (0x11D37, 'X'), + (0x11D3A, 'V'), + (0x11D3B, 'X'), + (0x11D3C, 'V'), + (0x11D3E, 'X'), + (0x11D3F, 'V'), + (0x11D48, 'X'), + (0x11D50, 'V'), + (0x11D5A, 'X'), + (0x11D60, 'V'), + (0x11D66, 'X'), + (0x11D67, 'V'), + (0x11D69, 'X'), + (0x11D6A, 'V'), + (0x11D8F, 'X'), + (0x11D90, 'V'), + (0x11D92, 'X'), + (0x11D93, 'V'), + (0x11D99, 'X'), + (0x11DA0, 'V'), + (0x11DAA, 'X'), + (0x11EE0, 'V'), + (0x11EF9, 'X'), + (0x11F00, 'V'), + ] + +def _seg_59() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x11F11, 'X'), + (0x11F12, 'V'), + (0x11F3B, 'X'), + (0x11F3E, 'V'), + (0x11F5A, 'X'), + (0x11FB0, 'V'), + (0x11FB1, 'X'), + (0x11FC0, 'V'), + (0x11FF2, 'X'), + (0x11FFF, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x12F90, 'V'), + (0x12FF3, 'X'), + (0x13000, 'V'), + (0x13430, 'X'), + (0x13440, 'V'), + (0x13456, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16ABF, 'X'), + (0x16AC0, 'V'), + (0x16ACA, 'X'), + (0x16AD0, 'V'), + (0x16AEE, 'X'), + (0x16AF0, 'V'), + (0x16AF6, 'X'), + (0x16B00, 'V'), + (0x16B46, 'X'), + (0x16B50, 'V'), + (0x16B5A, 'X'), + (0x16B5B, 'V'), + (0x16B62, 'X'), + (0x16B63, 'V'), + (0x16B78, 'X'), + (0x16B7D, 'V'), + (0x16B90, 'X'), + (0x16E40, 'M', 'đ–¹ '), + (0x16E41, 'M', 'đ–¹¡'), + (0x16E42, 'M', 'đ–¹¢'), + (0x16E43, 'M', 'đ–¹£'), + (0x16E44, 'M', 'đ–¹¤'), + (0x16E45, 'M', 'đ–¹¥'), + (0x16E46, 'M', 'đ–¹¦'), + (0x16E47, 'M', 'đ–¹§'), + (0x16E48, 'M', 'đ–¹¨'), + (0x16E49, 'M', 'đ–¹©'), + (0x16E4A, 'M', 'đ–¹ª'), + (0x16E4B, 'M', 'đ–¹«'), + (0x16E4C, 'M', 'đ–¹¬'), + (0x16E4D, 'M', 'đ–¹­'), + (0x16E4E, 'M', 'đ–¹®'), + (0x16E4F, 'M', 'đ–¹¯'), + (0x16E50, 'M', 'đ–¹°'), + (0x16E51, 'M', 'đ–¹±'), + (0x16E52, 'M', 'đ–¹²'), + (0x16E53, 'M', 'đ–¹³'), + (0x16E54, 'M', 'đ–¹´'), + (0x16E55, 'M', 'đ–¹µ'), + (0x16E56, 'M', 'đ–¹¶'), + (0x16E57, 'M', 'đ–¹·'), + (0x16E58, 'M', 'đ–¹¸'), + (0x16E59, 'M', 'đ–¹¹'), + (0x16E5A, 'M', 'đ–¹º'), + (0x16E5B, 'M', 'đ–¹»'), + (0x16E5C, 'M', 'đ–¹¼'), + (0x16E5D, 'M', 'đ–¹½'), + (0x16E5E, 'M', 'đ–¹¾'), + (0x16E5F, 'M', 'đ–¹¿'), + (0x16E60, 'V'), + (0x16E9B, 'X'), + (0x16F00, 'V'), + (0x16F4B, 'X'), + (0x16F4F, 'V'), + (0x16F88, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE5, 'X'), + (0x16FF0, 'V'), + (0x16FF2, 'X'), + (0x17000, 'V'), + (0x187F8, 'X'), + (0x18800, 'V'), + (0x18CD6, 'X'), + (0x18D00, 'V'), + (0x18D09, 'X'), + (0x1AFF0, 'V'), + ] + +def _seg_60() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1AFF4, 'X'), + (0x1AFF5, 'V'), + (0x1AFFC, 'X'), + (0x1AFFD, 'V'), + (0x1AFFF, 'X'), + (0x1B000, 'V'), + (0x1B123, 'X'), + (0x1B132, 'V'), + (0x1B133, 'X'), + (0x1B150, 'V'), + (0x1B153, 'X'), + (0x1B155, 'V'), + (0x1B156, 'X'), + (0x1B164, 'V'), + (0x1B168, 'X'), + (0x1B170, 'V'), + (0x1B2FC, 'X'), + (0x1BC00, 'V'), + (0x1BC6B, 'X'), + (0x1BC70, 'V'), + (0x1BC7D, 'X'), + (0x1BC80, 'V'), + (0x1BC89, 'X'), + (0x1BC90, 'V'), + (0x1BC9A, 'X'), + (0x1BC9C, 'V'), + (0x1BCA0, 'I'), + (0x1BCA4, 'X'), + (0x1CF00, 'V'), + (0x1CF2E, 'X'), + (0x1CF30, 'V'), + (0x1CF47, 'X'), + (0x1CF50, 'V'), + (0x1CFC4, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', 'đ…—đ…¥'), + (0x1D15F, 'M', 'đ…˜đ…¥'), + (0x1D160, 'M', 'đ…˜đ…¥đ…®'), + (0x1D161, 'M', 'đ…˜đ…¥đ…¯'), + (0x1D162, 'M', 'đ…˜đ…¥đ…°'), + (0x1D163, 'M', 'đ…˜đ…¥đ…±'), + (0x1D164, 'M', 'đ…˜đ…¥đ…²'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', 'đ†¹đ…¥'), + (0x1D1BC, 'M', 'đ†ºđ…¥'), + (0x1D1BD, 'M', 'đ†¹đ…¥đ…®'), + (0x1D1BE, 'M', 'đ†ºđ…¥đ…®'), + (0x1D1BF, 'M', 'đ†¹đ…¥đ…¯'), + (0x1D1C0, 'M', 'đ†ºđ…¥đ…¯'), + (0x1D1C1, 'V'), + (0x1D1EB, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D2C0, 'V'), + (0x1D2D4, 'X'), + (0x1D2E0, 'V'), + (0x1D2F4, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D379, 'X'), + (0x1D400, 'M', 'a'), + (0x1D401, 'M', 'b'), + (0x1D402, 'M', 'c'), + (0x1D403, 'M', 'd'), + (0x1D404, 'M', 'e'), + (0x1D405, 'M', 'f'), + (0x1D406, 'M', 'g'), + (0x1D407, 'M', 'h'), + (0x1D408, 'M', 'i'), + (0x1D409, 'M', 'j'), + (0x1D40A, 'M', 'k'), + (0x1D40B, 'M', 'l'), + (0x1D40C, 'M', 'm'), + (0x1D40D, 'M', 'n'), + (0x1D40E, 'M', 'o'), + (0x1D40F, 'M', 'p'), + (0x1D410, 'M', 'q'), + (0x1D411, 'M', 'r'), + (0x1D412, 'M', 's'), + (0x1D413, 'M', 't'), + (0x1D414, 'M', 'u'), + (0x1D415, 'M', 'v'), + (0x1D416, 'M', 'w'), + (0x1D417, 'M', 'x'), + (0x1D418, 'M', 'y'), + (0x1D419, 'M', 'z'), + (0x1D41A, 'M', 'a'), + (0x1D41B, 'M', 'b'), + (0x1D41C, 'M', 'c'), + (0x1D41D, 'M', 'd'), + (0x1D41E, 'M', 'e'), + (0x1D41F, 'M', 'f'), + (0x1D420, 'M', 'g'), + ] + +def _seg_61() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D421, 'M', 'h'), + (0x1D422, 'M', 'i'), + (0x1D423, 'M', 'j'), + (0x1D424, 'M', 'k'), + (0x1D425, 'M', 'l'), + (0x1D426, 'M', 'm'), + (0x1D427, 'M', 'n'), + (0x1D428, 'M', 'o'), + (0x1D429, 'M', 'p'), + (0x1D42A, 'M', 'q'), + (0x1D42B, 'M', 'r'), + (0x1D42C, 'M', 's'), + (0x1D42D, 'M', 't'), + (0x1D42E, 'M', 'u'), + (0x1D42F, 'M', 'v'), + (0x1D430, 'M', 'w'), + (0x1D431, 'M', 'x'), + (0x1D432, 'M', 'y'), + (0x1D433, 'M', 'z'), + (0x1D434, 'M', 'a'), + (0x1D435, 'M', 'b'), + (0x1D436, 'M', 'c'), + (0x1D437, 'M', 'd'), + (0x1D438, 'M', 'e'), + (0x1D439, 'M', 'f'), + (0x1D43A, 'M', 'g'), + (0x1D43B, 'M', 'h'), + (0x1D43C, 'M', 'i'), + (0x1D43D, 'M', 'j'), + (0x1D43E, 'M', 'k'), + (0x1D43F, 'M', 'l'), + (0x1D440, 'M', 'm'), + (0x1D441, 'M', 'n'), + (0x1D442, 'M', 'o'), + (0x1D443, 'M', 'p'), + (0x1D444, 'M', 'q'), + (0x1D445, 'M', 'r'), + (0x1D446, 'M', 's'), + (0x1D447, 'M', 't'), + (0x1D448, 'M', 'u'), + (0x1D449, 'M', 'v'), + (0x1D44A, 'M', 'w'), + (0x1D44B, 'M', 'x'), + (0x1D44C, 'M', 'y'), + (0x1D44D, 'M', 'z'), + (0x1D44E, 'M', 'a'), + (0x1D44F, 'M', 'b'), + (0x1D450, 'M', 'c'), + (0x1D451, 'M', 'd'), + (0x1D452, 'M', 'e'), + (0x1D453, 'M', 'f'), + (0x1D454, 'M', 'g'), + (0x1D455, 'X'), + (0x1D456, 'M', 'i'), + (0x1D457, 'M', 'j'), + (0x1D458, 'M', 'k'), + (0x1D459, 'M', 'l'), + (0x1D45A, 'M', 'm'), + (0x1D45B, 'M', 'n'), + (0x1D45C, 'M', 'o'), + (0x1D45D, 'M', 'p'), + (0x1D45E, 'M', 'q'), + (0x1D45F, 'M', 'r'), + (0x1D460, 'M', 's'), + (0x1D461, 'M', 't'), + (0x1D462, 'M', 'u'), + (0x1D463, 'M', 'v'), + (0x1D464, 'M', 'w'), + (0x1D465, 'M', 'x'), + (0x1D466, 'M', 'y'), + (0x1D467, 'M', 'z'), + (0x1D468, 'M', 'a'), + (0x1D469, 'M', 'b'), + (0x1D46A, 'M', 'c'), + (0x1D46B, 'M', 'd'), + (0x1D46C, 'M', 'e'), + (0x1D46D, 'M', 'f'), + (0x1D46E, 'M', 'g'), + (0x1D46F, 'M', 'h'), + (0x1D470, 'M', 'i'), + (0x1D471, 'M', 'j'), + (0x1D472, 'M', 'k'), + (0x1D473, 'M', 'l'), + (0x1D474, 'M', 'm'), + (0x1D475, 'M', 'n'), + (0x1D476, 'M', 'o'), + (0x1D477, 'M', 'p'), + (0x1D478, 'M', 'q'), + (0x1D479, 'M', 'r'), + (0x1D47A, 'M', 's'), + (0x1D47B, 'M', 't'), + (0x1D47C, 'M', 'u'), + (0x1D47D, 'M', 'v'), + (0x1D47E, 'M', 'w'), + (0x1D47F, 'M', 'x'), + (0x1D480, 'M', 'y'), + (0x1D481, 'M', 'z'), + (0x1D482, 'M', 'a'), + (0x1D483, 'M', 'b'), + (0x1D484, 'M', 'c'), + ] + +def _seg_62() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D485, 'M', 'd'), + (0x1D486, 'M', 'e'), + (0x1D487, 'M', 'f'), + (0x1D488, 'M', 'g'), + (0x1D489, 'M', 'h'), + (0x1D48A, 'M', 'i'), + (0x1D48B, 'M', 'j'), + (0x1D48C, 'M', 'k'), + (0x1D48D, 'M', 'l'), + (0x1D48E, 'M', 'm'), + (0x1D48F, 'M', 'n'), + (0x1D490, 'M', 'o'), + (0x1D491, 'M', 'p'), + (0x1D492, 'M', 'q'), + (0x1D493, 'M', 'r'), + (0x1D494, 'M', 's'), + (0x1D495, 'M', 't'), + (0x1D496, 'M', 'u'), + (0x1D497, 'M', 'v'), + (0x1D498, 'M', 'w'), + (0x1D499, 'M', 'x'), + (0x1D49A, 'M', 'y'), + (0x1D49B, 'M', 'z'), + (0x1D49C, 'M', 'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', 'c'), + (0x1D49F, 'M', 'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', 'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', 'j'), + (0x1D4A6, 'M', 'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', 'n'), + (0x1D4AA, 'M', 'o'), + (0x1D4AB, 'M', 'p'), + (0x1D4AC, 'M', 'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', 's'), + (0x1D4AF, 'M', 't'), + (0x1D4B0, 'M', 'u'), + (0x1D4B1, 'M', 'v'), + (0x1D4B2, 'M', 'w'), + (0x1D4B3, 'M', 'x'), + (0x1D4B4, 'M', 'y'), + (0x1D4B5, 'M', 'z'), + (0x1D4B6, 'M', 'a'), + (0x1D4B7, 'M', 'b'), + (0x1D4B8, 'M', 'c'), + (0x1D4B9, 'M', 'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', 'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', 'h'), + (0x1D4BE, 'M', 'i'), + (0x1D4BF, 'M', 'j'), + (0x1D4C0, 'M', 'k'), + (0x1D4C1, 'M', 'l'), + (0x1D4C2, 'M', 'm'), + (0x1D4C3, 'M', 'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', 'p'), + (0x1D4C6, 'M', 'q'), + (0x1D4C7, 'M', 'r'), + (0x1D4C8, 'M', 's'), + (0x1D4C9, 'M', 't'), + (0x1D4CA, 'M', 'u'), + (0x1D4CB, 'M', 'v'), + (0x1D4CC, 'M', 'w'), + (0x1D4CD, 'M', 'x'), + (0x1D4CE, 'M', 'y'), + (0x1D4CF, 'M', 'z'), + (0x1D4D0, 'M', 'a'), + (0x1D4D1, 'M', 'b'), + (0x1D4D2, 'M', 'c'), + (0x1D4D3, 'M', 'd'), + (0x1D4D4, 'M', 'e'), + (0x1D4D5, 'M', 'f'), + (0x1D4D6, 'M', 'g'), + (0x1D4D7, 'M', 'h'), + (0x1D4D8, 'M', 'i'), + (0x1D4D9, 'M', 'j'), + (0x1D4DA, 'M', 'k'), + (0x1D4DB, 'M', 'l'), + (0x1D4DC, 'M', 'm'), + (0x1D4DD, 'M', 'n'), + (0x1D4DE, 'M', 'o'), + (0x1D4DF, 'M', 'p'), + (0x1D4E0, 'M', 'q'), + (0x1D4E1, 'M', 'r'), + (0x1D4E2, 'M', 's'), + (0x1D4E3, 'M', 't'), + (0x1D4E4, 'M', 'u'), + (0x1D4E5, 'M', 'v'), + (0x1D4E6, 'M', 'w'), + (0x1D4E7, 'M', 'x'), + (0x1D4E8, 'M', 'y'), + (0x1D4E9, 'M', 'z'), + (0x1D4EA, 'M', 'a'), + (0x1D4EB, 'M', 'b'), + ] + +def _seg_63() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D4EC, 'M', 'c'), + (0x1D4ED, 'M', 'd'), + (0x1D4EE, 'M', 'e'), + (0x1D4EF, 'M', 'f'), + (0x1D4F0, 'M', 'g'), + (0x1D4F1, 'M', 'h'), + (0x1D4F2, 'M', 'i'), + (0x1D4F3, 'M', 'j'), + (0x1D4F4, 'M', 'k'), + (0x1D4F5, 'M', 'l'), + (0x1D4F6, 'M', 'm'), + (0x1D4F7, 'M', 'n'), + (0x1D4F8, 'M', 'o'), + (0x1D4F9, 'M', 'p'), + (0x1D4FA, 'M', 'q'), + (0x1D4FB, 'M', 'r'), + (0x1D4FC, 'M', 's'), + (0x1D4FD, 'M', 't'), + (0x1D4FE, 'M', 'u'), + (0x1D4FF, 'M', 'v'), + (0x1D500, 'M', 'w'), + (0x1D501, 'M', 'x'), + (0x1D502, 'M', 'y'), + (0x1D503, 'M', 'z'), + (0x1D504, 'M', 'a'), + (0x1D505, 'M', 'b'), + (0x1D506, 'X'), + (0x1D507, 'M', 'd'), + (0x1D508, 'M', 'e'), + (0x1D509, 'M', 'f'), + (0x1D50A, 'M', 'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', 'j'), + (0x1D50E, 'M', 'k'), + (0x1D50F, 'M', 'l'), + (0x1D510, 'M', 'm'), + (0x1D511, 'M', 'n'), + (0x1D512, 'M', 'o'), + (0x1D513, 'M', 'p'), + (0x1D514, 'M', 'q'), + (0x1D515, 'X'), + (0x1D516, 'M', 's'), + (0x1D517, 'M', 't'), + (0x1D518, 'M', 'u'), + (0x1D519, 'M', 'v'), + (0x1D51A, 'M', 'w'), + (0x1D51B, 'M', 'x'), + (0x1D51C, 'M', 'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', 'a'), + (0x1D51F, 'M', 'b'), + (0x1D520, 'M', 'c'), + (0x1D521, 'M', 'd'), + (0x1D522, 'M', 'e'), + (0x1D523, 'M', 'f'), + (0x1D524, 'M', 'g'), + (0x1D525, 'M', 'h'), + (0x1D526, 'M', 'i'), + (0x1D527, 'M', 'j'), + (0x1D528, 'M', 'k'), + (0x1D529, 'M', 'l'), + (0x1D52A, 'M', 'm'), + (0x1D52B, 'M', 'n'), + (0x1D52C, 'M', 'o'), + (0x1D52D, 'M', 'p'), + (0x1D52E, 'M', 'q'), + (0x1D52F, 'M', 'r'), + (0x1D530, 'M', 's'), + (0x1D531, 'M', 't'), + (0x1D532, 'M', 'u'), + (0x1D533, 'M', 'v'), + (0x1D534, 'M', 'w'), + (0x1D535, 'M', 'x'), + (0x1D536, 'M', 'y'), + (0x1D537, 'M', 'z'), + (0x1D538, 'M', 'a'), + (0x1D539, 'M', 'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', 'd'), + (0x1D53C, 'M', 'e'), + (0x1D53D, 'M', 'f'), + (0x1D53E, 'M', 'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', 'i'), + (0x1D541, 'M', 'j'), + (0x1D542, 'M', 'k'), + (0x1D543, 'M', 'l'), + (0x1D544, 'M', 'm'), + (0x1D545, 'X'), + (0x1D546, 'M', 'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', 's'), + (0x1D54B, 'M', 't'), + (0x1D54C, 'M', 'u'), + (0x1D54D, 'M', 'v'), + (0x1D54E, 'M', 'w'), + (0x1D54F, 'M', 'x'), + (0x1D550, 'M', 'y'), + (0x1D551, 'X'), + (0x1D552, 'M', 'a'), + ] + +def _seg_64() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D553, 'M', 'b'), + (0x1D554, 'M', 'c'), + (0x1D555, 'M', 'd'), + (0x1D556, 'M', 'e'), + (0x1D557, 'M', 'f'), + (0x1D558, 'M', 'g'), + (0x1D559, 'M', 'h'), + (0x1D55A, 'M', 'i'), + (0x1D55B, 'M', 'j'), + (0x1D55C, 'M', 'k'), + (0x1D55D, 'M', 'l'), + (0x1D55E, 'M', 'm'), + (0x1D55F, 'M', 'n'), + (0x1D560, 'M', 'o'), + (0x1D561, 'M', 'p'), + (0x1D562, 'M', 'q'), + (0x1D563, 'M', 'r'), + (0x1D564, 'M', 's'), + (0x1D565, 'M', 't'), + (0x1D566, 'M', 'u'), + (0x1D567, 'M', 'v'), + (0x1D568, 'M', 'w'), + (0x1D569, 'M', 'x'), + (0x1D56A, 'M', 'y'), + (0x1D56B, 'M', 'z'), + (0x1D56C, 'M', 'a'), + (0x1D56D, 'M', 'b'), + (0x1D56E, 'M', 'c'), + (0x1D56F, 'M', 'd'), + (0x1D570, 'M', 'e'), + (0x1D571, 'M', 'f'), + (0x1D572, 'M', 'g'), + (0x1D573, 'M', 'h'), + (0x1D574, 'M', 'i'), + (0x1D575, 'M', 'j'), + (0x1D576, 'M', 'k'), + (0x1D577, 'M', 'l'), + (0x1D578, 'M', 'm'), + (0x1D579, 'M', 'n'), + (0x1D57A, 'M', 'o'), + (0x1D57B, 'M', 'p'), + (0x1D57C, 'M', 'q'), + (0x1D57D, 'M', 'r'), + (0x1D57E, 'M', 's'), + (0x1D57F, 'M', 't'), + (0x1D580, 'M', 'u'), + (0x1D581, 'M', 'v'), + (0x1D582, 'M', 'w'), + (0x1D583, 'M', 'x'), + (0x1D584, 'M', 'y'), + (0x1D585, 'M', 'z'), + (0x1D586, 'M', 'a'), + (0x1D587, 'M', 'b'), + (0x1D588, 'M', 'c'), + (0x1D589, 'M', 'd'), + (0x1D58A, 'M', 'e'), + (0x1D58B, 'M', 'f'), + (0x1D58C, 'M', 'g'), + (0x1D58D, 'M', 'h'), + (0x1D58E, 'M', 'i'), + (0x1D58F, 'M', 'j'), + (0x1D590, 'M', 'k'), + (0x1D591, 'M', 'l'), + (0x1D592, 'M', 'm'), + (0x1D593, 'M', 'n'), + (0x1D594, 'M', 'o'), + (0x1D595, 'M', 'p'), + (0x1D596, 'M', 'q'), + (0x1D597, 'M', 'r'), + (0x1D598, 'M', 's'), + (0x1D599, 'M', 't'), + (0x1D59A, 'M', 'u'), + (0x1D59B, 'M', 'v'), + (0x1D59C, 'M', 'w'), + (0x1D59D, 'M', 'x'), + (0x1D59E, 'M', 'y'), + (0x1D59F, 'M', 'z'), + (0x1D5A0, 'M', 'a'), + (0x1D5A1, 'M', 'b'), + (0x1D5A2, 'M', 'c'), + (0x1D5A3, 'M', 'd'), + (0x1D5A4, 'M', 'e'), + (0x1D5A5, 'M', 'f'), + (0x1D5A6, 'M', 'g'), + (0x1D5A7, 'M', 'h'), + (0x1D5A8, 'M', 'i'), + (0x1D5A9, 'M', 'j'), + (0x1D5AA, 'M', 'k'), + (0x1D5AB, 'M', 'l'), + (0x1D5AC, 'M', 'm'), + (0x1D5AD, 'M', 'n'), + (0x1D5AE, 'M', 'o'), + (0x1D5AF, 'M', 'p'), + (0x1D5B0, 'M', 'q'), + (0x1D5B1, 'M', 'r'), + (0x1D5B2, 'M', 's'), + (0x1D5B3, 'M', 't'), + (0x1D5B4, 'M', 'u'), + (0x1D5B5, 'M', 'v'), + (0x1D5B6, 'M', 'w'), + ] + +def _seg_65() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D5B7, 'M', 'x'), + (0x1D5B8, 'M', 'y'), + (0x1D5B9, 'M', 'z'), + (0x1D5BA, 'M', 'a'), + (0x1D5BB, 'M', 'b'), + (0x1D5BC, 'M', 'c'), + (0x1D5BD, 'M', 'd'), + (0x1D5BE, 'M', 'e'), + (0x1D5BF, 'M', 'f'), + (0x1D5C0, 'M', 'g'), + (0x1D5C1, 'M', 'h'), + (0x1D5C2, 'M', 'i'), + (0x1D5C3, 'M', 'j'), + (0x1D5C4, 'M', 'k'), + (0x1D5C5, 'M', 'l'), + (0x1D5C6, 'M', 'm'), + (0x1D5C7, 'M', 'n'), + (0x1D5C8, 'M', 'o'), + (0x1D5C9, 'M', 'p'), + (0x1D5CA, 'M', 'q'), + (0x1D5CB, 'M', 'r'), + (0x1D5CC, 'M', 's'), + (0x1D5CD, 'M', 't'), + (0x1D5CE, 'M', 'u'), + (0x1D5CF, 'M', 'v'), + (0x1D5D0, 'M', 'w'), + (0x1D5D1, 'M', 'x'), + (0x1D5D2, 'M', 'y'), + (0x1D5D3, 'M', 'z'), + (0x1D5D4, 'M', 'a'), + (0x1D5D5, 'M', 'b'), + (0x1D5D6, 'M', 'c'), + (0x1D5D7, 'M', 'd'), + (0x1D5D8, 'M', 'e'), + (0x1D5D9, 'M', 'f'), + (0x1D5DA, 'M', 'g'), + (0x1D5DB, 'M', 'h'), + (0x1D5DC, 'M', 'i'), + (0x1D5DD, 'M', 'j'), + (0x1D5DE, 'M', 'k'), + (0x1D5DF, 'M', 'l'), + (0x1D5E0, 'M', 'm'), + (0x1D5E1, 'M', 'n'), + (0x1D5E2, 'M', 'o'), + (0x1D5E3, 'M', 'p'), + (0x1D5E4, 'M', 'q'), + (0x1D5E5, 'M', 'r'), + (0x1D5E6, 'M', 's'), + (0x1D5E7, 'M', 't'), + (0x1D5E8, 'M', 'u'), + (0x1D5E9, 'M', 'v'), + (0x1D5EA, 'M', 'w'), + (0x1D5EB, 'M', 'x'), + (0x1D5EC, 'M', 'y'), + (0x1D5ED, 'M', 'z'), + (0x1D5EE, 'M', 'a'), + (0x1D5EF, 'M', 'b'), + (0x1D5F0, 'M', 'c'), + (0x1D5F1, 'M', 'd'), + (0x1D5F2, 'M', 'e'), + (0x1D5F3, 'M', 'f'), + (0x1D5F4, 'M', 'g'), + (0x1D5F5, 'M', 'h'), + (0x1D5F6, 'M', 'i'), + (0x1D5F7, 'M', 'j'), + (0x1D5F8, 'M', 'k'), + (0x1D5F9, 'M', 'l'), + (0x1D5FA, 'M', 'm'), + (0x1D5FB, 'M', 'n'), + (0x1D5FC, 'M', 'o'), + (0x1D5FD, 'M', 'p'), + (0x1D5FE, 'M', 'q'), + (0x1D5FF, 'M', 'r'), + (0x1D600, 'M', 's'), + (0x1D601, 'M', 't'), + (0x1D602, 'M', 'u'), + (0x1D603, 'M', 'v'), + (0x1D604, 'M', 'w'), + (0x1D605, 'M', 'x'), + (0x1D606, 'M', 'y'), + (0x1D607, 'M', 'z'), + (0x1D608, 'M', 'a'), + (0x1D609, 'M', 'b'), + (0x1D60A, 'M', 'c'), + (0x1D60B, 'M', 'd'), + (0x1D60C, 'M', 'e'), + (0x1D60D, 'M', 'f'), + (0x1D60E, 'M', 'g'), + (0x1D60F, 'M', 'h'), + (0x1D610, 'M', 'i'), + (0x1D611, 'M', 'j'), + (0x1D612, 'M', 'k'), + (0x1D613, 'M', 'l'), + (0x1D614, 'M', 'm'), + (0x1D615, 'M', 'n'), + (0x1D616, 'M', 'o'), + (0x1D617, 'M', 'p'), + (0x1D618, 'M', 'q'), + (0x1D619, 'M', 'r'), + (0x1D61A, 'M', 's'), + ] + +def _seg_66() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D61B, 'M', 't'), + (0x1D61C, 'M', 'u'), + (0x1D61D, 'M', 'v'), + (0x1D61E, 'M', 'w'), + (0x1D61F, 'M', 'x'), + (0x1D620, 'M', 'y'), + (0x1D621, 'M', 'z'), + (0x1D622, 'M', 'a'), + (0x1D623, 'M', 'b'), + (0x1D624, 'M', 'c'), + (0x1D625, 'M', 'd'), + (0x1D626, 'M', 'e'), + (0x1D627, 'M', 'f'), + (0x1D628, 'M', 'g'), + (0x1D629, 'M', 'h'), + (0x1D62A, 'M', 'i'), + (0x1D62B, 'M', 'j'), + (0x1D62C, 'M', 'k'), + (0x1D62D, 'M', 'l'), + (0x1D62E, 'M', 'm'), + (0x1D62F, 'M', 'n'), + (0x1D630, 'M', 'o'), + (0x1D631, 'M', 'p'), + (0x1D632, 'M', 'q'), + (0x1D633, 'M', 'r'), + (0x1D634, 'M', 's'), + (0x1D635, 'M', 't'), + (0x1D636, 'M', 'u'), + (0x1D637, 'M', 'v'), + (0x1D638, 'M', 'w'), + (0x1D639, 'M', 'x'), + (0x1D63A, 'M', 'y'), + (0x1D63B, 'M', 'z'), + (0x1D63C, 'M', 'a'), + (0x1D63D, 'M', 'b'), + (0x1D63E, 'M', 'c'), + (0x1D63F, 'M', 'd'), + (0x1D640, 'M', 'e'), + (0x1D641, 'M', 'f'), + (0x1D642, 'M', 'g'), + (0x1D643, 'M', 'h'), + (0x1D644, 'M', 'i'), + (0x1D645, 'M', 'j'), + (0x1D646, 'M', 'k'), + (0x1D647, 'M', 'l'), + (0x1D648, 'M', 'm'), + (0x1D649, 'M', 'n'), + (0x1D64A, 'M', 'o'), + (0x1D64B, 'M', 'p'), + (0x1D64C, 'M', 'q'), + (0x1D64D, 'M', 'r'), + (0x1D64E, 'M', 's'), + (0x1D64F, 'M', 't'), + (0x1D650, 'M', 'u'), + (0x1D651, 'M', 'v'), + (0x1D652, 'M', 'w'), + (0x1D653, 'M', 'x'), + (0x1D654, 'M', 'y'), + (0x1D655, 'M', 'z'), + (0x1D656, 'M', 'a'), + (0x1D657, 'M', 'b'), + (0x1D658, 'M', 'c'), + (0x1D659, 'M', 'd'), + (0x1D65A, 'M', 'e'), + (0x1D65B, 'M', 'f'), + (0x1D65C, 'M', 'g'), + (0x1D65D, 'M', 'h'), + (0x1D65E, 'M', 'i'), + (0x1D65F, 'M', 'j'), + (0x1D660, 'M', 'k'), + (0x1D661, 'M', 'l'), + (0x1D662, 'M', 'm'), + (0x1D663, 'M', 'n'), + (0x1D664, 'M', 'o'), + (0x1D665, 'M', 'p'), + (0x1D666, 'M', 'q'), + (0x1D667, 'M', 'r'), + (0x1D668, 'M', 's'), + (0x1D669, 'M', 't'), + (0x1D66A, 'M', 'u'), + (0x1D66B, 'M', 'v'), + (0x1D66C, 'M', 'w'), + (0x1D66D, 'M', 'x'), + (0x1D66E, 'M', 'y'), + (0x1D66F, 'M', 'z'), + (0x1D670, 'M', 'a'), + (0x1D671, 'M', 'b'), + (0x1D672, 'M', 'c'), + (0x1D673, 'M', 'd'), + (0x1D674, 'M', 'e'), + (0x1D675, 'M', 'f'), + (0x1D676, 'M', 'g'), + (0x1D677, 'M', 'h'), + (0x1D678, 'M', 'i'), + (0x1D679, 'M', 'j'), + (0x1D67A, 'M', 'k'), + (0x1D67B, 'M', 'l'), + (0x1D67C, 'M', 'm'), + (0x1D67D, 'M', 'n'), + (0x1D67E, 'M', 'o'), + ] + +def _seg_67() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D67F, 'M', 'p'), + (0x1D680, 'M', 'q'), + (0x1D681, 'M', 'r'), + (0x1D682, 'M', 's'), + (0x1D683, 'M', 't'), + (0x1D684, 'M', 'u'), + (0x1D685, 'M', 'v'), + (0x1D686, 'M', 'w'), + (0x1D687, 'M', 'x'), + (0x1D688, 'M', 'y'), + (0x1D689, 'M', 'z'), + (0x1D68A, 'M', 'a'), + (0x1D68B, 'M', 'b'), + (0x1D68C, 'M', 'c'), + (0x1D68D, 'M', 'd'), + (0x1D68E, 'M', 'e'), + (0x1D68F, 'M', 'f'), + (0x1D690, 'M', 'g'), + (0x1D691, 'M', 'h'), + (0x1D692, 'M', 'i'), + (0x1D693, 'M', 'j'), + (0x1D694, 'M', 'k'), + (0x1D695, 'M', 'l'), + (0x1D696, 'M', 'm'), + (0x1D697, 'M', 'n'), + (0x1D698, 'M', 'o'), + (0x1D699, 'M', 'p'), + (0x1D69A, 'M', 'q'), + (0x1D69B, 'M', 'r'), + (0x1D69C, 'M', 's'), + (0x1D69D, 'M', 't'), + (0x1D69E, 'M', 'u'), + (0x1D69F, 'M', 'v'), + (0x1D6A0, 'M', 'w'), + (0x1D6A1, 'M', 'x'), + (0x1D6A2, 'M', 'y'), + (0x1D6A3, 'M', 'z'), + (0x1D6A4, 'M', 'ı'), + (0x1D6A5, 'M', 'È·'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', 'α'), + (0x1D6A9, 'M', 'β'), + (0x1D6AA, 'M', 'γ'), + (0x1D6AB, 'M', 'δ'), + (0x1D6AC, 'M', 'ε'), + (0x1D6AD, 'M', 'ζ'), + (0x1D6AE, 'M', 'η'), + (0x1D6AF, 'M', 'θ'), + (0x1D6B0, 'M', 'ι'), + (0x1D6B1, 'M', 'κ'), + (0x1D6B2, 'M', 'λ'), + (0x1D6B3, 'M', 'μ'), + (0x1D6B4, 'M', 'ν'), + (0x1D6B5, 'M', 'ξ'), + (0x1D6B6, 'M', 'ο'), + (0x1D6B7, 'M', 'Ï€'), + (0x1D6B8, 'M', 'Ï'), + (0x1D6B9, 'M', 'θ'), + (0x1D6BA, 'M', 'σ'), + (0x1D6BB, 'M', 'Ï„'), + (0x1D6BC, 'M', 'Ï…'), + (0x1D6BD, 'M', 'φ'), + (0x1D6BE, 'M', 'χ'), + (0x1D6BF, 'M', 'ψ'), + (0x1D6C0, 'M', 'ω'), + (0x1D6C1, 'M', '∇'), + (0x1D6C2, 'M', 'α'), + (0x1D6C3, 'M', 'β'), + (0x1D6C4, 'M', 'γ'), + (0x1D6C5, 'M', 'δ'), + (0x1D6C6, 'M', 'ε'), + (0x1D6C7, 'M', 'ζ'), + (0x1D6C8, 'M', 'η'), + (0x1D6C9, 'M', 'θ'), + (0x1D6CA, 'M', 'ι'), + (0x1D6CB, 'M', 'κ'), + (0x1D6CC, 'M', 'λ'), + (0x1D6CD, 'M', 'μ'), + (0x1D6CE, 'M', 'ν'), + (0x1D6CF, 'M', 'ξ'), + (0x1D6D0, 'M', 'ο'), + (0x1D6D1, 'M', 'Ï€'), + (0x1D6D2, 'M', 'Ï'), + (0x1D6D3, 'M', 'σ'), + (0x1D6D5, 'M', 'Ï„'), + (0x1D6D6, 'M', 'Ï…'), + (0x1D6D7, 'M', 'φ'), + (0x1D6D8, 'M', 'χ'), + (0x1D6D9, 'M', 'ψ'), + (0x1D6DA, 'M', 'ω'), + (0x1D6DB, 'M', '∂'), + (0x1D6DC, 'M', 'ε'), + (0x1D6DD, 'M', 'θ'), + (0x1D6DE, 'M', 'κ'), + (0x1D6DF, 'M', 'φ'), + (0x1D6E0, 'M', 'Ï'), + (0x1D6E1, 'M', 'Ï€'), + (0x1D6E2, 'M', 'α'), + (0x1D6E3, 'M', 'β'), + (0x1D6E4, 'M', 'γ'), + ] + +def _seg_68() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D6E5, 'M', 'δ'), + (0x1D6E6, 'M', 'ε'), + (0x1D6E7, 'M', 'ζ'), + (0x1D6E8, 'M', 'η'), + (0x1D6E9, 'M', 'θ'), + (0x1D6EA, 'M', 'ι'), + (0x1D6EB, 'M', 'κ'), + (0x1D6EC, 'M', 'λ'), + (0x1D6ED, 'M', 'μ'), + (0x1D6EE, 'M', 'ν'), + (0x1D6EF, 'M', 'ξ'), + (0x1D6F0, 'M', 'ο'), + (0x1D6F1, 'M', 'Ï€'), + (0x1D6F2, 'M', 'Ï'), + (0x1D6F3, 'M', 'θ'), + (0x1D6F4, 'M', 'σ'), + (0x1D6F5, 'M', 'Ï„'), + (0x1D6F6, 'M', 'Ï…'), + (0x1D6F7, 'M', 'φ'), + (0x1D6F8, 'M', 'χ'), + (0x1D6F9, 'M', 'ψ'), + (0x1D6FA, 'M', 'ω'), + (0x1D6FB, 'M', '∇'), + (0x1D6FC, 'M', 'α'), + (0x1D6FD, 'M', 'β'), + (0x1D6FE, 'M', 'γ'), + (0x1D6FF, 'M', 'δ'), + (0x1D700, 'M', 'ε'), + (0x1D701, 'M', 'ζ'), + (0x1D702, 'M', 'η'), + (0x1D703, 'M', 'θ'), + (0x1D704, 'M', 'ι'), + (0x1D705, 'M', 'κ'), + (0x1D706, 'M', 'λ'), + (0x1D707, 'M', 'μ'), + (0x1D708, 'M', 'ν'), + (0x1D709, 'M', 'ξ'), + (0x1D70A, 'M', 'ο'), + (0x1D70B, 'M', 'Ï€'), + (0x1D70C, 'M', 'Ï'), + (0x1D70D, 'M', 'σ'), + (0x1D70F, 'M', 'Ï„'), + (0x1D710, 'M', 'Ï…'), + (0x1D711, 'M', 'φ'), + (0x1D712, 'M', 'χ'), + (0x1D713, 'M', 'ψ'), + (0x1D714, 'M', 'ω'), + (0x1D715, 'M', '∂'), + (0x1D716, 'M', 'ε'), + (0x1D717, 'M', 'θ'), + (0x1D718, 'M', 'κ'), + (0x1D719, 'M', 'φ'), + (0x1D71A, 'M', 'Ï'), + (0x1D71B, 'M', 'Ï€'), + (0x1D71C, 'M', 'α'), + (0x1D71D, 'M', 'β'), + (0x1D71E, 'M', 'γ'), + (0x1D71F, 'M', 'δ'), + (0x1D720, 'M', 'ε'), + (0x1D721, 'M', 'ζ'), + (0x1D722, 'M', 'η'), + (0x1D723, 'M', 'θ'), + (0x1D724, 'M', 'ι'), + (0x1D725, 'M', 'κ'), + (0x1D726, 'M', 'λ'), + (0x1D727, 'M', 'μ'), + (0x1D728, 'M', 'ν'), + (0x1D729, 'M', 'ξ'), + (0x1D72A, 'M', 'ο'), + (0x1D72B, 'M', 'Ï€'), + (0x1D72C, 'M', 'Ï'), + (0x1D72D, 'M', 'θ'), + (0x1D72E, 'M', 'σ'), + (0x1D72F, 'M', 'Ï„'), + (0x1D730, 'M', 'Ï…'), + (0x1D731, 'M', 'φ'), + (0x1D732, 'M', 'χ'), + (0x1D733, 'M', 'ψ'), + (0x1D734, 'M', 'ω'), + (0x1D735, 'M', '∇'), + (0x1D736, 'M', 'α'), + (0x1D737, 'M', 'β'), + (0x1D738, 'M', 'γ'), + (0x1D739, 'M', 'δ'), + (0x1D73A, 'M', 'ε'), + (0x1D73B, 'M', 'ζ'), + (0x1D73C, 'M', 'η'), + (0x1D73D, 'M', 'θ'), + (0x1D73E, 'M', 'ι'), + (0x1D73F, 'M', 'κ'), + (0x1D740, 'M', 'λ'), + (0x1D741, 'M', 'μ'), + (0x1D742, 'M', 'ν'), + (0x1D743, 'M', 'ξ'), + (0x1D744, 'M', 'ο'), + (0x1D745, 'M', 'Ï€'), + (0x1D746, 'M', 'Ï'), + (0x1D747, 'M', 'σ'), + (0x1D749, 'M', 'Ï„'), + (0x1D74A, 'M', 'Ï…'), + ] + +def _seg_69() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D74B, 'M', 'φ'), + (0x1D74C, 'M', 'χ'), + (0x1D74D, 'M', 'ψ'), + (0x1D74E, 'M', 'ω'), + (0x1D74F, 'M', '∂'), + (0x1D750, 'M', 'ε'), + (0x1D751, 'M', 'θ'), + (0x1D752, 'M', 'κ'), + (0x1D753, 'M', 'φ'), + (0x1D754, 'M', 'Ï'), + (0x1D755, 'M', 'Ï€'), + (0x1D756, 'M', 'α'), + (0x1D757, 'M', 'β'), + (0x1D758, 'M', 'γ'), + (0x1D759, 'M', 'δ'), + (0x1D75A, 'M', 'ε'), + (0x1D75B, 'M', 'ζ'), + (0x1D75C, 'M', 'η'), + (0x1D75D, 'M', 'θ'), + (0x1D75E, 'M', 'ι'), + (0x1D75F, 'M', 'κ'), + (0x1D760, 'M', 'λ'), + (0x1D761, 'M', 'μ'), + (0x1D762, 'M', 'ν'), + (0x1D763, 'M', 'ξ'), + (0x1D764, 'M', 'ο'), + (0x1D765, 'M', 'Ï€'), + (0x1D766, 'M', 'Ï'), + (0x1D767, 'M', 'θ'), + (0x1D768, 'M', 'σ'), + (0x1D769, 'M', 'Ï„'), + (0x1D76A, 'M', 'Ï…'), + (0x1D76B, 'M', 'φ'), + (0x1D76C, 'M', 'χ'), + (0x1D76D, 'M', 'ψ'), + (0x1D76E, 'M', 'ω'), + (0x1D76F, 'M', '∇'), + (0x1D770, 'M', 'α'), + (0x1D771, 'M', 'β'), + (0x1D772, 'M', 'γ'), + (0x1D773, 'M', 'δ'), + (0x1D774, 'M', 'ε'), + (0x1D775, 'M', 'ζ'), + (0x1D776, 'M', 'η'), + (0x1D777, 'M', 'θ'), + (0x1D778, 'M', 'ι'), + (0x1D779, 'M', 'κ'), + (0x1D77A, 'M', 'λ'), + (0x1D77B, 'M', 'μ'), + (0x1D77C, 'M', 'ν'), + (0x1D77D, 'M', 'ξ'), + (0x1D77E, 'M', 'ο'), + (0x1D77F, 'M', 'Ï€'), + (0x1D780, 'M', 'Ï'), + (0x1D781, 'M', 'σ'), + (0x1D783, 'M', 'Ï„'), + (0x1D784, 'M', 'Ï…'), + (0x1D785, 'M', 'φ'), + (0x1D786, 'M', 'χ'), + (0x1D787, 'M', 'ψ'), + (0x1D788, 'M', 'ω'), + (0x1D789, 'M', '∂'), + (0x1D78A, 'M', 'ε'), + (0x1D78B, 'M', 'θ'), + (0x1D78C, 'M', 'κ'), + (0x1D78D, 'M', 'φ'), + (0x1D78E, 'M', 'Ï'), + (0x1D78F, 'M', 'Ï€'), + (0x1D790, 'M', 'α'), + (0x1D791, 'M', 'β'), + (0x1D792, 'M', 'γ'), + (0x1D793, 'M', 'δ'), + (0x1D794, 'M', 'ε'), + (0x1D795, 'M', 'ζ'), + (0x1D796, 'M', 'η'), + (0x1D797, 'M', 'θ'), + (0x1D798, 'M', 'ι'), + (0x1D799, 'M', 'κ'), + (0x1D79A, 'M', 'λ'), + (0x1D79B, 'M', 'μ'), + (0x1D79C, 'M', 'ν'), + (0x1D79D, 'M', 'ξ'), + (0x1D79E, 'M', 'ο'), + (0x1D79F, 'M', 'Ï€'), + (0x1D7A0, 'M', 'Ï'), + (0x1D7A1, 'M', 'θ'), + (0x1D7A2, 'M', 'σ'), + (0x1D7A3, 'M', 'Ï„'), + (0x1D7A4, 'M', 'Ï…'), + (0x1D7A5, 'M', 'φ'), + (0x1D7A6, 'M', 'χ'), + (0x1D7A7, 'M', 'ψ'), + (0x1D7A8, 'M', 'ω'), + (0x1D7A9, 'M', '∇'), + (0x1D7AA, 'M', 'α'), + (0x1D7AB, 'M', 'β'), + (0x1D7AC, 'M', 'γ'), + (0x1D7AD, 'M', 'δ'), + (0x1D7AE, 'M', 'ε'), + (0x1D7AF, 'M', 'ζ'), + ] + +def _seg_70() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D7B0, 'M', 'η'), + (0x1D7B1, 'M', 'θ'), + (0x1D7B2, 'M', 'ι'), + (0x1D7B3, 'M', 'κ'), + (0x1D7B4, 'M', 'λ'), + (0x1D7B5, 'M', 'μ'), + (0x1D7B6, 'M', 'ν'), + (0x1D7B7, 'M', 'ξ'), + (0x1D7B8, 'M', 'ο'), + (0x1D7B9, 'M', 'Ï€'), + (0x1D7BA, 'M', 'Ï'), + (0x1D7BB, 'M', 'σ'), + (0x1D7BD, 'M', 'Ï„'), + (0x1D7BE, 'M', 'Ï…'), + (0x1D7BF, 'M', 'φ'), + (0x1D7C0, 'M', 'χ'), + (0x1D7C1, 'M', 'ψ'), + (0x1D7C2, 'M', 'ω'), + (0x1D7C3, 'M', '∂'), + (0x1D7C4, 'M', 'ε'), + (0x1D7C5, 'M', 'θ'), + (0x1D7C6, 'M', 'κ'), + (0x1D7C7, 'M', 'φ'), + (0x1D7C8, 'M', 'Ï'), + (0x1D7C9, 'M', 'Ï€'), + (0x1D7CA, 'M', 'Ï'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', '0'), + (0x1D7CF, 'M', '1'), + (0x1D7D0, 'M', '2'), + (0x1D7D1, 'M', '3'), + (0x1D7D2, 'M', '4'), + (0x1D7D3, 'M', '5'), + (0x1D7D4, 'M', '6'), + (0x1D7D5, 'M', '7'), + (0x1D7D6, 'M', '8'), + (0x1D7D7, 'M', '9'), + (0x1D7D8, 'M', '0'), + (0x1D7D9, 'M', '1'), + (0x1D7DA, 'M', '2'), + (0x1D7DB, 'M', '3'), + (0x1D7DC, 'M', '4'), + (0x1D7DD, 'M', '5'), + (0x1D7DE, 'M', '6'), + (0x1D7DF, 'M', '7'), + (0x1D7E0, 'M', '8'), + (0x1D7E1, 'M', '9'), + (0x1D7E2, 'M', '0'), + (0x1D7E3, 'M', '1'), + (0x1D7E4, 'M', '2'), + (0x1D7E5, 'M', '3'), + (0x1D7E6, 'M', '4'), + (0x1D7E7, 'M', '5'), + (0x1D7E8, 'M', '6'), + (0x1D7E9, 'M', '7'), + (0x1D7EA, 'M', '8'), + (0x1D7EB, 'M', '9'), + (0x1D7EC, 'M', '0'), + (0x1D7ED, 'M', '1'), + (0x1D7EE, 'M', '2'), + (0x1D7EF, 'M', '3'), + (0x1D7F0, 'M', '4'), + (0x1D7F1, 'M', '5'), + (0x1D7F2, 'M', '6'), + (0x1D7F3, 'M', '7'), + (0x1D7F4, 'M', '8'), + (0x1D7F5, 'M', '9'), + (0x1D7F6, 'M', '0'), + (0x1D7F7, 'M', '1'), + (0x1D7F8, 'M', '2'), + (0x1D7F9, 'M', '3'), + (0x1D7FA, 'M', '4'), + (0x1D7FB, 'M', '5'), + (0x1D7FC, 'M', '6'), + (0x1D7FD, 'M', '7'), + (0x1D7FE, 'M', '8'), + (0x1D7FF, 'M', '9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1DF00, 'V'), + (0x1DF1F, 'X'), + (0x1DF25, 'V'), + (0x1DF2B, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E030, 'M', 'Đ°'), + (0x1E031, 'M', 'б'), + (0x1E032, 'M', 'Đ²'), + ] + +def _seg_71() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E033, 'M', 'Đ³'), + (0x1E034, 'M', 'Đ´'), + (0x1E035, 'M', 'е'), + (0x1E036, 'M', 'ж'), + (0x1E037, 'M', 'Đ·'), + (0x1E038, 'M', 'и'), + (0x1E039, 'M', 'Đº'), + (0x1E03A, 'M', 'Đ»'), + (0x1E03B, 'M', 'Đ¼'), + (0x1E03C, 'M', 'Đ¾'), + (0x1E03D, 'M', 'Đ¿'), + (0x1E03E, 'M', 'Ñ€'), + (0x1E03F, 'M', 'Ñ'), + (0x1E040, 'M', 'Ñ‚'), + (0x1E041, 'M', 'у'), + (0x1E042, 'M', 'Ñ„'), + (0x1E043, 'M', 'Ñ…'), + (0x1E044, 'M', 'ц'), + (0x1E045, 'M', 'ч'), + (0x1E046, 'M', 'ш'), + (0x1E047, 'M', 'Ñ‹'), + (0x1E048, 'M', 'Ñ'), + (0x1E049, 'M', 'Ñ'), + (0x1E04A, 'M', 'ê‰'), + (0x1E04B, 'M', 'Ó™'), + (0x1E04C, 'M', 'Ñ–'), + (0x1E04D, 'M', 'ј'), + (0x1E04E, 'M', 'Ó©'), + (0x1E04F, 'M', '̉¯'), + (0x1E050, 'M', 'Ó'), + (0x1E051, 'M', 'Đ°'), + (0x1E052, 'M', 'б'), + (0x1E053, 'M', 'Đ²'), + (0x1E054, 'M', 'Đ³'), + (0x1E055, 'M', 'Đ´'), + (0x1E056, 'M', 'е'), + (0x1E057, 'M', 'ж'), + (0x1E058, 'M', 'Đ·'), + (0x1E059, 'M', 'и'), + (0x1E05A, 'M', 'Đº'), + (0x1E05B, 'M', 'Đ»'), + (0x1E05C, 'M', 'Đ¾'), + (0x1E05D, 'M', 'Đ¿'), + (0x1E05E, 'M', 'Ñ'), + (0x1E05F, 'M', 'у'), + (0x1E060, 'M', 'Ñ„'), + (0x1E061, 'M', 'Ñ…'), + (0x1E062, 'M', 'ц'), + (0x1E063, 'M', 'ч'), + (0x1E064, 'M', 'ш'), + (0x1E065, 'M', 'Ñ'), + (0x1E066, 'M', 'Ñ‹'), + (0x1E067, 'M', '̉‘'), + (0x1E068, 'M', 'Ñ–'), + (0x1E069, 'M', 'Ñ•'), + (0x1E06A, 'M', 'ÑŸ'), + (0x1E06B, 'M', '̉«'), + (0x1E06C, 'M', 'ꙑ'), + (0x1E06D, 'M', '̉±'), + (0x1E06E, 'X'), + (0x1E08F, 'V'), + (0x1E090, 'X'), + (0x1E100, 'V'), + (0x1E12D, 'X'), + (0x1E130, 'V'), + (0x1E13E, 'X'), + (0x1E140, 'V'), + (0x1E14A, 'X'), + (0x1E14E, 'V'), + (0x1E150, 'X'), + (0x1E290, 'V'), + (0x1E2AF, 'X'), + (0x1E2C0, 'V'), + (0x1E2FA, 'X'), + (0x1E2FF, 'V'), + (0x1E300, 'X'), + (0x1E4D0, 'V'), + (0x1E4FA, 'X'), + (0x1E7E0, 'V'), + (0x1E7E7, 'X'), + (0x1E7E8, 'V'), + (0x1E7EC, 'X'), + (0x1E7ED, 'V'), + (0x1E7EF, 'X'), + (0x1E7F0, 'V'), + (0x1E7FF, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', 'đ¤¢'), + (0x1E901, 'M', 'đ¤£'), + (0x1E902, 'M', 'đ¤¤'), + (0x1E903, 'M', 'đ¤¥'), + (0x1E904, 'M', 'đ¤¦'), + (0x1E905, 'M', 'đ¤§'), + (0x1E906, 'M', 'đ¤¨'), + (0x1E907, 'M', 'đ¤©'), + (0x1E908, 'M', 'đ¤ª'), + (0x1E909, 'M', 'đ¤«'), + ] + +def _seg_72() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E90A, 'M', 'đ¤¬'), + (0x1E90B, 'M', 'đ¤­'), + (0x1E90C, 'M', 'đ¤®'), + (0x1E90D, 'M', 'đ¤¯'), + (0x1E90E, 'M', 'đ¤°'), + (0x1E90F, 'M', 'đ¤±'), + (0x1E910, 'M', 'đ¤²'), + (0x1E911, 'M', 'đ¤³'), + (0x1E912, 'M', 'đ¤´'), + (0x1E913, 'M', 'đ¤µ'), + (0x1E914, 'M', 'đ¤¶'), + (0x1E915, 'M', 'đ¤·'), + (0x1E916, 'M', 'đ¤¸'), + (0x1E917, 'M', 'đ¤¹'), + (0x1E918, 'M', 'đ¤º'), + (0x1E919, 'M', 'đ¤»'), + (0x1E91A, 'M', 'đ¤¼'), + (0x1E91B, 'M', 'đ¤½'), + (0x1E91C, 'M', 'đ¤¾'), + (0x1E91D, 'M', 'đ¤¿'), + (0x1E91E, 'M', 'đ¥€'), + (0x1E91F, 'M', 'đ¥'), + (0x1E920, 'M', 'đ¥‚'), + (0x1E921, 'M', 'đ¥ƒ'), + (0x1E922, 'V'), + (0x1E94C, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + (0x1EC71, 'V'), + (0x1ECB5, 'X'), + (0x1ED01, 'V'), + (0x1ED3E, 'X'), + (0x1EE00, 'M', 'ا'), + (0x1EE01, 'M', 'ب'), + (0x1EE02, 'M', 'ج'), + (0x1EE03, 'M', 'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', 'Ùˆ'), + (0x1EE06, 'M', 'ز'), + (0x1EE07, 'M', 'Ø­'), + (0x1EE08, 'M', 'Ø·'), + (0x1EE09, 'M', 'Ù'), + (0x1EE0A, 'M', 'Ùƒ'), + (0x1EE0B, 'M', 'Ù„'), + (0x1EE0C, 'M', 'Ù…'), + (0x1EE0D, 'M', 'Ù†'), + (0x1EE0E, 'M', 'س'), + (0x1EE0F, 'M', 'ع'), + (0x1EE10, 'M', 'Ù'), + (0x1EE11, 'M', 'ص'), + (0x1EE12, 'M', 'Ù‚'), + (0x1EE13, 'M', 'ر'), + (0x1EE14, 'M', 'Ø´'), + (0x1EE15, 'M', 'ت'), + (0x1EE16, 'M', 'Ø«'), + (0x1EE17, 'M', 'Ø®'), + (0x1EE18, 'M', 'Ø°'), + (0x1EE19, 'M', 'ض'), + (0x1EE1A, 'M', 'ظ'), + (0x1EE1B, 'M', 'غ'), + (0x1EE1C, 'M', 'Ù®'), + (0x1EE1D, 'M', 'Úº'), + (0x1EE1E, 'M', 'Ú¡'), + (0x1EE1F, 'M', 'Ù¯'), + (0x1EE20, 'X'), + (0x1EE21, 'M', 'ب'), + (0x1EE22, 'M', 'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', 'Ù‡'), + (0x1EE25, 'X'), + (0x1EE27, 'M', 'Ø­'), + (0x1EE28, 'X'), + (0x1EE29, 'M', 'Ù'), + (0x1EE2A, 'M', 'Ùƒ'), + (0x1EE2B, 'M', 'Ù„'), + (0x1EE2C, 'M', 'Ù…'), + (0x1EE2D, 'M', 'Ù†'), + (0x1EE2E, 'M', 'س'), + (0x1EE2F, 'M', 'ع'), + (0x1EE30, 'M', 'Ù'), + (0x1EE31, 'M', 'ص'), + (0x1EE32, 'M', 'Ù‚'), + (0x1EE33, 'X'), + (0x1EE34, 'M', 'Ø´'), + (0x1EE35, 'M', 'ت'), + (0x1EE36, 'M', 'Ø«'), + (0x1EE37, 'M', 'Ø®'), + (0x1EE38, 'X'), + (0x1EE39, 'M', 'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', 'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', 'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', 'Ø­'), + (0x1EE48, 'X'), + (0x1EE49, 'M', 'Ù'), + (0x1EE4A, 'X'), + ] + +def _seg_73() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EE4B, 'M', 'Ù„'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', 'Ù†'), + (0x1EE4E, 'M', 'س'), + (0x1EE4F, 'M', 'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', 'ص'), + (0x1EE52, 'M', 'Ù‚'), + (0x1EE53, 'X'), + (0x1EE54, 'M', 'Ø´'), + (0x1EE55, 'X'), + (0x1EE57, 'M', 'Ø®'), + (0x1EE58, 'X'), + (0x1EE59, 'M', 'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', 'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', 'Úº'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', 'Ù¯'), + (0x1EE60, 'X'), + (0x1EE61, 'M', 'ب'), + (0x1EE62, 'M', 'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', 'Ù‡'), + (0x1EE65, 'X'), + (0x1EE67, 'M', 'Ø­'), + (0x1EE68, 'M', 'Ø·'), + (0x1EE69, 'M', 'Ù'), + (0x1EE6A, 'M', 'Ùƒ'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', 'Ù…'), + (0x1EE6D, 'M', 'Ù†'), + (0x1EE6E, 'M', 'س'), + (0x1EE6F, 'M', 'ع'), + (0x1EE70, 'M', 'Ù'), + (0x1EE71, 'M', 'ص'), + (0x1EE72, 'M', 'Ù‚'), + (0x1EE73, 'X'), + (0x1EE74, 'M', 'Ø´'), + (0x1EE75, 'M', 'ت'), + (0x1EE76, 'M', 'Ø«'), + (0x1EE77, 'M', 'Ø®'), + (0x1EE78, 'X'), + (0x1EE79, 'M', 'ض'), + (0x1EE7A, 'M', 'ظ'), + (0x1EE7B, 'M', 'غ'), + (0x1EE7C, 'M', 'Ù®'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', 'Ú¡'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', 'ا'), + (0x1EE81, 'M', 'ب'), + (0x1EE82, 'M', 'ج'), + (0x1EE83, 'M', 'د'), + (0x1EE84, 'M', 'Ù‡'), + (0x1EE85, 'M', 'Ùˆ'), + (0x1EE86, 'M', 'ز'), + (0x1EE87, 'M', 'Ø­'), + (0x1EE88, 'M', 'Ø·'), + (0x1EE89, 'M', 'Ù'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', 'Ù„'), + (0x1EE8C, 'M', 'Ù…'), + (0x1EE8D, 'M', 'Ù†'), + (0x1EE8E, 'M', 'س'), + (0x1EE8F, 'M', 'ع'), + (0x1EE90, 'M', 'Ù'), + (0x1EE91, 'M', 'ص'), + (0x1EE92, 'M', 'Ù‚'), + (0x1EE93, 'M', 'ر'), + (0x1EE94, 'M', 'Ø´'), + (0x1EE95, 'M', 'ت'), + (0x1EE96, 'M', 'Ø«'), + (0x1EE97, 'M', 'Ø®'), + (0x1EE98, 'M', 'Ø°'), + (0x1EE99, 'M', 'ض'), + (0x1EE9A, 'M', 'ظ'), + (0x1EE9B, 'M', 'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', 'ب'), + (0x1EEA2, 'M', 'ج'), + (0x1EEA3, 'M', 'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', 'Ùˆ'), + (0x1EEA6, 'M', 'ز'), + (0x1EEA7, 'M', 'Ø­'), + (0x1EEA8, 'M', 'Ø·'), + (0x1EEA9, 'M', 'Ù'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', 'Ù„'), + (0x1EEAC, 'M', 'Ù…'), + (0x1EEAD, 'M', 'Ù†'), + (0x1EEAE, 'M', 'س'), + (0x1EEAF, 'M', 'ع'), + (0x1EEB0, 'M', 'Ù'), + (0x1EEB1, 'M', 'ص'), + (0x1EEB2, 'M', 'Ù‚'), + (0x1EEB3, 'M', 'ر'), + (0x1EEB4, 'M', 'Ø´'), + ] + +def _seg_74() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EEB5, 'M', 'ت'), + (0x1EEB6, 'M', 'Ø«'), + (0x1EEB7, 'M', 'Ø®'), + (0x1EEB8, 'M', 'Ø°'), + (0x1EEB9, 'M', 'ض'), + (0x1EEBA, 'M', 'ظ'), + (0x1EEBB, 'M', 'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0C0, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0F6, 'X'), + (0x1F101, '3', '0,'), + (0x1F102, '3', '1,'), + (0x1F103, '3', '2,'), + (0x1F104, '3', '3,'), + (0x1F105, '3', '4,'), + (0x1F106, '3', '5,'), + (0x1F107, '3', '6,'), + (0x1F108, '3', '7,'), + (0x1F109, '3', '8,'), + (0x1F10A, '3', '9,'), + (0x1F10B, 'V'), + (0x1F110, '3', '(a)'), + (0x1F111, '3', '(b)'), + (0x1F112, '3', '(c)'), + (0x1F113, '3', '(d)'), + (0x1F114, '3', '(e)'), + (0x1F115, '3', '(f)'), + (0x1F116, '3', '(g)'), + (0x1F117, '3', '(h)'), + (0x1F118, '3', '(i)'), + (0x1F119, '3', '(j)'), + (0x1F11A, '3', '(k)'), + (0x1F11B, '3', '(l)'), + (0x1F11C, '3', '(m)'), + (0x1F11D, '3', '(n)'), + (0x1F11E, '3', '(o)'), + (0x1F11F, '3', '(p)'), + (0x1F120, '3', '(q)'), + (0x1F121, '3', '(r)'), + (0x1F122, '3', '(s)'), + (0x1F123, '3', '(t)'), + (0x1F124, '3', '(u)'), + (0x1F125, '3', '(v)'), + (0x1F126, '3', '(w)'), + (0x1F127, '3', '(x)'), + (0x1F128, '3', '(y)'), + (0x1F129, '3', '(z)'), + (0x1F12A, 'M', '〔s〕'), + (0x1F12B, 'M', 'c'), + (0x1F12C, 'M', 'r'), + (0x1F12D, 'M', 'cd'), + (0x1F12E, 'M', 'wz'), + (0x1F12F, 'V'), + (0x1F130, 'M', 'a'), + (0x1F131, 'M', 'b'), + (0x1F132, 'M', 'c'), + (0x1F133, 'M', 'd'), + (0x1F134, 'M', 'e'), + (0x1F135, 'M', 'f'), + (0x1F136, 'M', 'g'), + (0x1F137, 'M', 'h'), + (0x1F138, 'M', 'i'), + (0x1F139, 'M', 'j'), + (0x1F13A, 'M', 'k'), + (0x1F13B, 'M', 'l'), + (0x1F13C, 'M', 'm'), + (0x1F13D, 'M', 'n'), + (0x1F13E, 'M', 'o'), + (0x1F13F, 'M', 'p'), + (0x1F140, 'M', 'q'), + (0x1F141, 'M', 'r'), + (0x1F142, 'M', 's'), + (0x1F143, 'M', 't'), + (0x1F144, 'M', 'u'), + (0x1F145, 'M', 'v'), + (0x1F146, 'M', 'w'), + (0x1F147, 'M', 'x'), + (0x1F148, 'M', 'y'), + (0x1F149, 'M', 'z'), + (0x1F14A, 'M', 'hv'), + (0x1F14B, 'M', 'mv'), + (0x1F14C, 'M', 'sd'), + (0x1F14D, 'M', 'ss'), + (0x1F14E, 'M', 'ppv'), + (0x1F14F, 'M', 'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', 'mc'), + (0x1F16B, 'M', 'md'), + ] + +def _seg_75() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F16C, 'M', 'mr'), + (0x1F16D, 'V'), + (0x1F190, 'M', 'dj'), + (0x1F191, 'V'), + (0x1F1AE, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', 'ă»ă‹'), + (0x1F201, 'M', 'ă‚³ă‚³'), + (0x1F202, 'M', 'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', '手'), + (0x1F211, 'M', 'å­—'), + (0x1F212, 'M', 'åŒ'), + (0x1F213, 'M', 'ăƒ‡'), + (0x1F214, 'M', '二'), + (0x1F215, 'M', 'å¤'), + (0x1F216, 'M', '解'), + (0x1F217, 'M', '天'), + (0x1F218, 'M', '交'), + (0x1F219, 'M', '映'), + (0x1F21A, 'M', 'ç„¡'), + (0x1F21B, 'M', 'æ–™'), + (0x1F21C, 'M', 'å‰'), + (0x1F21D, 'M', '後'), + (0x1F21E, 'M', 'å†'), + (0x1F21F, 'M', 'æ–°'), + (0x1F220, 'M', 'åˆ'), + (0x1F221, 'M', '終'), + (0x1F222, 'M', '生'), + (0x1F223, 'M', '販'), + (0x1F224, 'M', '声'), + (0x1F225, 'M', 'å¹'), + (0x1F226, 'M', 'æ¼”'), + (0x1F227, 'M', 'æ•'), + (0x1F228, 'M', 'æ•'), + (0x1F229, 'M', '一'), + (0x1F22A, 'M', '三'), + (0x1F22B, 'M', 'é'), + (0x1F22C, 'M', 'å·¦'), + (0x1F22D, 'M', '中'), + (0x1F22E, 'M', 'å³'), + (0x1F22F, 'M', '指'), + (0x1F230, 'M', 'èµ°'), + (0x1F231, 'M', '打'), + (0x1F232, 'M', 'ç¦'), + (0x1F233, 'M', '空'), + (0x1F234, 'M', 'åˆ'), + (0x1F235, 'M', '満'), + (0x1F236, 'M', '有'), + (0x1F237, 'M', '月'), + (0x1F238, 'M', '申'), + (0x1F239, 'M', '割'), + (0x1F23A, 'M', 'å–¶'), + (0x1F23B, 'M', 'é…'), + (0x1F23C, 'X'), + (0x1F240, 'M', 'ă€”æœ¬ă€•'), + (0x1F241, 'M', '〔三〕'), + (0x1F242, 'M', 'ă€”äºŒă€•'), + (0x1F243, 'M', 'ă€”å®‰ă€•'), + (0x1F244, 'M', 'ă€”ç‚¹ă€•'), + (0x1F245, 'M', 'ă€”æ‰“ă€•'), + (0x1F246, 'M', '〔盗〕'), + (0x1F247, 'M', '〔å‹ă€•'), + (0x1F248, 'M', 'ă€”æ•—ă€•'), + (0x1F249, 'X'), + (0x1F250, 'M', 'å¾—'), + (0x1F251, 'M', 'å¯'), + (0x1F252, 'X'), + (0x1F260, 'V'), + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D8, 'X'), + (0x1F6DC, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6FD, 'X'), + (0x1F700, 'V'), + (0x1F777, 'X'), + (0x1F77B, 'V'), + (0x1F7DA, 'X'), + (0x1F7E0, 'V'), + (0x1F7EC, 'X'), + (0x1F7F0, 'V'), + (0x1F7F1, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F8B0, 'V'), + (0x1F8B2, 'X'), + (0x1F900, 'V'), + (0x1FA54, 'X'), + (0x1FA60, 'V'), + (0x1FA6E, 'X'), + ] + +def _seg_76() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FA70, 'V'), + (0x1FA7D, 'X'), + (0x1FA80, 'V'), + (0x1FA89, 'X'), + (0x1FA90, 'V'), + (0x1FABE, 'X'), + (0x1FABF, 'V'), + (0x1FAC6, 'X'), + (0x1FACE, 'V'), + (0x1FADC, 'X'), + (0x1FAE0, 'V'), + (0x1FAE9, 'X'), + (0x1FAF0, 'V'), + (0x1FAF9, 'X'), + (0x1FB00, 'V'), + (0x1FB93, 'X'), + (0x1FB94, 'V'), + (0x1FBCB, 'X'), + (0x1FBF0, 'M', '0'), + (0x1FBF1, 'M', '1'), + (0x1FBF2, 'M', '2'), + (0x1FBF3, 'M', '3'), + (0x1FBF4, 'M', '4'), + (0x1FBF5, 'M', '5'), + (0x1FBF6, 'M', '6'), + (0x1FBF7, 'M', '7'), + (0x1FBF8, 'M', '8'), + (0x1FBF9, 'M', '9'), + (0x1FBFA, 'X'), + (0x20000, 'V'), + (0x2A6E0, 'X'), + (0x2A700, 'V'), + (0x2B73A, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', '丽'), + (0x2F801, 'M', '丸'), + (0x2F802, 'M', 'ä¹'), + (0x2F803, 'M', 'đ „¢'), + (0x2F804, 'M', 'ä½ '), + (0x2F805, 'M', 'ä¾®'), + (0x2F806, 'M', 'ä¾»'), + (0x2F807, 'M', '倂'), + (0x2F808, 'M', 'åº'), + (0x2F809, 'M', 'å‚™'), + (0x2F80A, 'M', '僧'), + (0x2F80B, 'M', 'åƒ'), + (0x2F80C, 'M', 'ă’'), + (0x2F80D, 'M', 'đ ˜º'), + (0x2F80E, 'M', 'å…'), + (0x2F80F, 'M', 'å…”'), + (0x2F810, 'M', 'å…¤'), + (0x2F811, 'M', 'å…·'), + (0x2F812, 'M', 'đ ”œ'), + (0x2F813, 'M', 'ă’¹'), + (0x2F814, 'M', 'å…§'), + (0x2F815, 'M', 'å†'), + (0x2F816, 'M', 'đ •‹'), + (0x2F817, 'M', '冗'), + (0x2F818, 'M', '冤'), + (0x2F819, 'M', '仌'), + (0x2F81A, 'M', '冬'), + (0x2F81B, 'M', '况'), + (0x2F81C, 'M', 'đ©‡Ÿ'), + (0x2F81D, 'M', '凵'), + (0x2F81E, 'M', '刃'), + (0x2F81F, 'M', 'ă“Ÿ'), + (0x2F820, 'M', '刻'), + (0x2F821, 'M', '剆'), + (0x2F822, 'M', '割'), + (0x2F823, 'M', '剷'), + (0x2F824, 'M', '㔕'), + (0x2F825, 'M', '勇'), + (0x2F826, 'M', '勉'), + (0x2F827, 'M', '勤'), + (0x2F828, 'M', '勺'), + (0x2F829, 'M', '包'), + (0x2F82A, 'M', '匆'), + (0x2F82B, 'M', '北'), + (0x2F82C, 'M', 'å‰'), + (0x2F82D, 'M', 'å‘'), + (0x2F82E, 'M', 'å'), + (0x2F82F, 'M', 'å³'), + (0x2F830, 'M', 'å½'), + (0x2F831, 'M', 'å¿'), + (0x2F834, 'M', '𠨬'), + (0x2F835, 'M', 'ç°'), + (0x2F836, 'M', 'å'), + (0x2F837, 'M', 'åŸ'), + (0x2F838, 'M', 'đ ­£'), + (0x2F839, 'M', 'å«'), + (0x2F83A, 'M', 'å±'), + (0x2F83B, 'M', 'å†'), + (0x2F83C, 'M', 'å’'), + (0x2F83D, 'M', 'å¸'), + (0x2F83E, 'M', '呈'), + ] + +def _seg_77() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F83F, 'M', '周'), + (0x2F840, 'M', 'å’¢'), + (0x2F841, 'M', '哶'), + (0x2F842, 'M', 'å”'), + (0x2F843, 'M', 'å•“'), + (0x2F844, 'M', 'å•£'), + (0x2F845, 'M', 'å–„'), + (0x2F847, 'M', 'å–™'), + (0x2F848, 'M', 'å–«'), + (0x2F849, 'M', 'å–³'), + (0x2F84A, 'M', 'å—‚'), + (0x2F84B, 'M', '圖'), + (0x2F84C, 'M', '嘆'), + (0x2F84D, 'M', '圗'), + (0x2F84E, 'M', '噑'), + (0x2F84F, 'M', 'å™´'), + (0x2F850, 'M', '切'), + (0x2F851, 'M', '壮'), + (0x2F852, 'M', 'åŸ'), + (0x2F853, 'M', '埴'), + (0x2F854, 'M', 'å '), + (0x2F855, 'M', 'å‹'), + (0x2F856, 'M', 'å ²'), + (0x2F857, 'M', 'å ±'), + (0x2F858, 'M', '墬'), + (0x2F859, 'M', 'đ¡“¤'), + (0x2F85A, 'M', '売'), + (0x2F85B, 'M', '壷'), + (0x2F85C, 'M', '夆'), + (0x2F85D, 'M', 'å¤'), + (0x2F85E, 'M', '夢'), + (0x2F85F, 'M', '奢'), + (0x2F860, 'M', 'đ¡¨'), + (0x2F861, 'M', 'đ¡›ª'), + (0x2F862, 'M', '姬'), + (0x2F863, 'M', '娛'), + (0x2F864, 'M', '娧'), + (0x2F865, 'M', '姘'), + (0x2F866, 'M', '婦'), + (0x2F867, 'M', 'ă›®'), + (0x2F868, 'X'), + (0x2F869, 'M', '嬈'), + (0x2F86A, 'M', '嬾'), + (0x2F86C, 'M', 'đ¡§ˆ'), + (0x2F86D, 'M', '寃'), + (0x2F86E, 'M', '寘'), + (0x2F86F, 'M', '寧'), + (0x2F870, 'M', '寳'), + (0x2F871, 'M', 'đ¡¬˜'), + (0x2F872, 'M', '寿'), + (0x2F873, 'M', 'å°†'), + (0x2F874, 'X'), + (0x2F875, 'M', 'å°¢'), + (0x2F876, 'M', 'ă'), + (0x2F877, 'M', 'å± '), + (0x2F878, 'M', 'å±®'), + (0x2F879, 'M', 'å³€'), + (0x2F87A, 'M', 'å²'), + (0x2F87B, 'M', 'đ¡·¤'), + (0x2F87C, 'M', '嵃'), + (0x2F87D, 'M', 'đ¡·¦'), + (0x2F87E, 'M', 'åµ®'), + (0x2F87F, 'M', '嵫'), + (0x2F880, 'M', 'åµ¼'), + (0x2F881, 'M', 'å·¡'), + (0x2F882, 'M', 'å·¢'), + (0x2F883, 'M', 'ă ¯'), + (0x2F884, 'M', 'å·½'), + (0x2F885, 'M', '帨'), + (0x2F886, 'M', '帽'), + (0x2F887, 'M', '幩'), + (0x2F888, 'M', 'ă¡¢'), + (0x2F889, 'M', 'đ¢†ƒ'), + (0x2F88A, 'M', 'ă¡¼'), + (0x2F88B, 'M', '庰'), + (0x2F88C, 'M', '庳'), + (0x2F88D, 'M', '庶'), + (0x2F88E, 'M', 'å»'), + (0x2F88F, 'M', 'đª’'), + (0x2F890, 'M', '廾'), + (0x2F891, 'M', 'đ¢Œ±'), + (0x2F893, 'M', 'èˆ'), + (0x2F894, 'M', 'å¼¢'), + (0x2F896, 'M', 'ă£‡'), + (0x2F897, 'M', 'đ£¸'), + (0x2F898, 'M', 'đ¦‡'), + (0x2F899, 'M', 'å½¢'), + (0x2F89A, 'M', '彫'), + (0x2F89B, 'M', 'ă££'), + (0x2F89C, 'M', 'å¾'), + (0x2F89D, 'M', 'å¿'), + (0x2F89E, 'M', 'å¿—'), + (0x2F89F, 'M', '忹'), + (0x2F8A0, 'M', 'æ‚'), + (0x2F8A1, 'M', 'ă¤º'), + (0x2F8A2, 'M', 'ă¤œ'), + (0x2F8A3, 'M', 'æ‚”'), + (0x2F8A4, 'M', 'đ¢›”'), + (0x2F8A5, 'M', '惇'), + (0x2F8A6, 'M', 'æ…ˆ'), + ] + +def _seg_78() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F8A7, 'M', 'æ…Œ'), + (0x2F8A8, 'M', 'æ…'), + (0x2F8A9, 'M', 'æ…Œ'), + (0x2F8AA, 'M', 'æ…º'), + (0x2F8AB, 'M', 'æ†'), + (0x2F8AC, 'M', '憲'), + (0x2F8AD, 'M', '憤'), + (0x2F8AE, 'M', '憯'), + (0x2F8AF, 'M', 'æ‡'), + (0x2F8B0, 'M', '懲'), + (0x2F8B1, 'M', '懶'), + (0x2F8B2, 'M', 'æˆ'), + (0x2F8B3, 'M', '戛'), + (0x2F8B4, 'M', 'æ‰'), + (0x2F8B5, 'M', 'æ±'), + (0x2F8B6, 'M', 'æ‹”'), + (0x2F8B7, 'M', 'æ'), + (0x2F8B8, 'M', 'đ¢¬Œ'), + (0x2F8B9, 'M', '挽'), + (0x2F8BA, 'M', '拼'), + (0x2F8BB, 'M', 'æ¨'), + (0x2F8BC, 'M', 'æƒ'), + (0x2F8BD, 'M', 'æ¤'), + (0x2F8BE, 'M', 'đ¢¯±'), + (0x2F8BF, 'M', 'æ¢'), + (0x2F8C0, 'M', 'æ…'), + (0x2F8C1, 'M', 'æ©'), + (0x2F8C2, 'M', '㨮'), + (0x2F8C3, 'M', 'æ‘©'), + (0x2F8C4, 'M', '摾'), + (0x2F8C5, 'M', 'æ’'), + (0x2F8C6, 'M', 'æ‘·'), + (0x2F8C7, 'M', '㩬'), + (0x2F8C8, 'M', 'æ•'), + (0x2F8C9, 'M', '敬'), + (0x2F8CA, 'M', 'đ£€'), + (0x2F8CB, 'M', 'æ—£'), + (0x2F8CC, 'M', '書'), + (0x2F8CD, 'M', '晉'), + (0x2F8CE, 'M', '㬙'), + (0x2F8CF, 'M', 'æ‘'), + (0x2F8D0, 'M', 'ă¬ˆ'), + (0x2F8D1, 'M', '㫤'), + (0x2F8D2, 'M', '冒'), + (0x2F8D3, 'M', '冕'), + (0x2F8D4, 'M', '最'), + (0x2F8D5, 'M', 'æœ'), + (0x2F8D6, 'M', 'è‚­'), + (0x2F8D7, 'M', 'ä™'), + (0x2F8D8, 'M', '朗'), + (0x2F8D9, 'M', '望'), + (0x2F8DA, 'M', '朡'), + (0x2F8DB, 'M', 'æ'), + (0x2F8DC, 'M', 'æ“'), + (0x2F8DD, 'M', 'đ£ƒ'), + (0x2F8DE, 'M', 'ă­‰'), + (0x2F8DF, 'M', '柺'), + (0x2F8E0, 'M', 'æ…'), + (0x2F8E1, 'M', 'æ¡’'), + (0x2F8E2, 'M', '梅'), + (0x2F8E3, 'M', 'đ£‘­'), + (0x2F8E4, 'M', 'æ¢'), + (0x2F8E5, 'M', 'æ Ÿ'), + (0x2F8E6, 'M', '椔'), + (0x2F8E7, 'M', 'ă®'), + (0x2F8E8, 'M', '楂'), + (0x2F8E9, 'M', '榣'), + (0x2F8EA, 'M', '槪'), + (0x2F8EB, 'M', '檨'), + (0x2F8EC, 'M', 'đ££'), + (0x2F8ED, 'M', 'æ«›'), + (0x2F8EE, 'M', 'ă°˜'), + (0x2F8EF, 'M', '次'), + (0x2F8F0, 'M', 'đ£¢§'), + (0x2F8F1, 'M', 'æ­”'), + (0x2F8F2, 'M', 'ă±'), + (0x2F8F3, 'M', 'æ­²'), + (0x2F8F4, 'M', '殟'), + (0x2F8F5, 'M', '殺'), + (0x2F8F6, 'M', 'æ®»'), + (0x2F8F7, 'M', 'đ£ª'), + (0x2F8F8, 'M', 'đ¡´‹'), + (0x2F8F9, 'M', 'đ£«º'), + (0x2F8FA, 'M', 'æ±'), + (0x2F8FB, 'M', 'đ£²¼'), + (0x2F8FC, 'M', '沿'), + (0x2F8FD, 'M', 'æ³'), + (0x2F8FE, 'M', '汧'), + (0x2F8FF, 'M', 'æ´–'), + (0x2F900, 'M', 'æ´¾'), + (0x2F901, 'M', 'æµ·'), + (0x2F902, 'M', 'æµ'), + (0x2F903, 'M', '浩'), + (0x2F904, 'M', '浸'), + (0x2F905, 'M', '涅'), + (0x2F906, 'M', 'đ£´'), + (0x2F907, 'M', 'æ´´'), + (0x2F908, 'M', '港'), + (0x2F909, 'M', 'æ¹®'), + (0x2F90A, 'M', 'ă´³'), + ] + +def _seg_79() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F90B, 'M', '滋'), + (0x2F90C, 'M', '滇'), + (0x2F90D, 'M', 'đ£»‘'), + (0x2F90E, 'M', 'æ·¹'), + (0x2F90F, 'M', 'æ½®'), + (0x2F910, 'M', 'đ£½'), + (0x2F911, 'M', 'đ£¾'), + (0x2F912, 'M', '濆'), + (0x2F913, 'M', '瀹'), + (0x2F914, 'M', 'ç€'), + (0x2F915, 'M', '瀛'), + (0x2F916, 'M', '㶖'), + (0x2F917, 'M', 'ç'), + (0x2F918, 'M', 'ç½'), + (0x2F919, 'M', 'ç·'), + (0x2F91A, 'M', 'ç‚­'), + (0x2F91B, 'M', 'đ ”¥'), + (0x2F91C, 'M', 'ç……'), + (0x2F91D, 'M', 'đ¤‰£'), + (0x2F91E, 'M', '熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', '爨'), + (0x2F921, 'M', '爵'), + (0x2F922, 'M', 'ç‰'), + (0x2F923, 'M', 'đ¤˜ˆ'), + (0x2F924, 'M', 'ç€'), + (0x2F925, 'M', 'ç•'), + (0x2F926, 'M', 'đ¤œµ'), + (0x2F927, 'M', '𤠔'), + (0x2F928, 'M', 'çº'), + (0x2F929, 'M', 'ç‹'), + (0x2F92A, 'M', 'ăº¬'), + (0x2F92B, 'M', 'ç¥'), + (0x2F92C, 'M', 'ăº¸'), + (0x2F92E, 'M', '瑇'), + (0x2F92F, 'M', 'ç‘œ'), + (0x2F930, 'M', '瑱'), + (0x2F931, 'M', 'ç’…'), + (0x2F932, 'M', 'ç“'), + (0x2F933, 'M', 'ă¼›'), + (0x2F934, 'M', '甤'), + (0x2F935, 'M', '𤰶'), + (0x2F936, 'M', '甾'), + (0x2F937, 'M', 'đ¤²’'), + (0x2F938, 'M', 'ç•°'), + (0x2F939, 'M', 'đ¢†Ÿ'), + (0x2F93A, 'M', 'ç˜'), + (0x2F93B, 'M', 'đ¤¾¡'), + (0x2F93C, 'M', 'đ¤¾¸'), + (0x2F93D, 'M', 'đ¥„'), + (0x2F93E, 'M', 'ă¿¼'), + (0x2F93F, 'M', '䀈'), + (0x2F940, 'M', 'ç›´'), + (0x2F941, 'M', 'đ¥ƒ³'), + (0x2F942, 'M', 'đ¥ƒ²'), + (0x2F943, 'M', 'đ¥„™'), + (0x2F944, 'M', 'đ¥„³'), + (0x2F945, 'M', 'çœ'), + (0x2F946, 'M', '真'), + (0x2F948, 'M', 'ç'), + (0x2F949, 'M', '䀹'), + (0x2F94A, 'M', 'ç‹'), + (0x2F94B, 'M', 'ä†'), + (0x2F94C, 'M', 'ä‚–'), + (0x2F94D, 'M', 'đ¥'), + (0x2F94E, 'M', 'ç¡'), + (0x2F94F, 'M', '碌'), + (0x2F950, 'M', '磌'), + (0x2F951, 'M', '䃣'), + (0x2F952, 'M', 'đ¥˜¦'), + (0x2F953, 'M', '祖'), + (0x2F954, 'M', 'đ¥'), + (0x2F955, 'M', 'đ¥›…'), + (0x2F956, 'M', 'ç¦'), + (0x2F957, 'M', '秫'), + (0x2F958, 'M', '䄯'), + (0x2F959, 'M', 'ç©€'), + (0x2F95A, 'M', 'ç©'), + (0x2F95B, 'M', 'ç©'), + (0x2F95C, 'M', 'đ¥¥¼'), + (0x2F95D, 'M', 'đ¥ª§'), + (0x2F95F, 'X'), + (0x2F960, 'M', '䈂'), + (0x2F961, 'M', 'đ¥®«'), + (0x2F962, 'M', '篆'), + (0x2F963, 'M', '築'), + (0x2F964, 'M', '䈧'), + (0x2F965, 'M', 'đ¥²€'), + (0x2F966, 'M', 'ç³’'), + (0x2F967, 'M', 'ä '), + (0x2F968, 'M', '糨'), + (0x2F969, 'M', 'ç³£'), + (0x2F96A, 'M', 'ç´€'), + (0x2F96B, 'M', 'đ¥¾†'), + (0x2F96C, 'M', 'çµ£'), + (0x2F96D, 'M', 'äŒ'), + (0x2F96E, 'M', 'ç·‡'), + (0x2F96F, 'M', '縂'), + (0x2F970, 'M', 'ç¹…'), + (0x2F971, 'M', '䌴'), + ] + +def _seg_80() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F972, 'M', 'đ¦ˆ¨'), + (0x2F973, 'M', '𦉇'), + (0x2F974, 'M', 'ä™'), + (0x2F975, 'M', '𦋙'), + (0x2F976, 'M', '罺'), + (0x2F977, 'M', 'đ¦Œ¾'), + (0x2F978, 'M', '羕'), + (0x2F979, 'M', '翺'), + (0x2F97A, 'M', '者'), + (0x2F97B, 'M', 'đ¦“'), + (0x2F97C, 'M', 'đ¦”£'), + (0x2F97D, 'M', 'è '), + (0x2F97E, 'M', '𦖨'), + (0x2F97F, 'M', 'è°'), + (0x2F980, 'M', 'đ£Ÿ'), + (0x2F981, 'M', 'ä•'), + (0x2F982, 'M', '育'), + (0x2F983, 'M', '脃'), + (0x2F984, 'M', 'ä‹'), + (0x2F985, 'M', '脾'), + (0x2F986, 'M', '媵'), + (0x2F987, 'M', 'đ¦§'), + (0x2F988, 'M', 'đ¦µ'), + (0x2F989, 'M', 'đ£“'), + (0x2F98A, 'M', 'đ£œ'), + (0x2F98B, 'M', 'èˆ'), + (0x2F98C, 'M', '舄'), + (0x2F98D, 'M', 'è¾'), + (0x2F98E, 'M', 'ä‘«'), + (0x2F98F, 'M', 'è‘'), + (0x2F990, 'M', 'è‹'), + (0x2F991, 'M', 'è'), + (0x2F992, 'M', 'å³'), + (0x2F993, 'M', 'è±'), + (0x2F994, 'M', 'è³'), + (0x2F995, 'M', 'è½'), + (0x2F996, 'M', '苦'), + (0x2F997, 'M', 'đ¦¬¼'), + (0x2F998, 'M', 'è‹¥'), + (0x2F999, 'M', 'èŒ'), + (0x2F99A, 'M', 'è£'), + (0x2F99B, 'M', 'è­'), + (0x2F99C, 'M', '茣'), + (0x2F99D, 'M', 'è½'), + (0x2F99E, 'M', 'è§'), + (0x2F99F, 'M', 'è‘—'), + (0x2F9A0, 'M', 'è“'), + (0x2F9A1, 'M', 'è'), + (0x2F9A2, 'M', 'èŒ'), + (0x2F9A3, 'M', 'èœ'), + (0x2F9A4, 'M', '𦰶'), + (0x2F9A5, 'M', '𦵫'), + (0x2F9A6, 'M', 'đ¦³•'), + (0x2F9A7, 'M', '䔫'), + (0x2F9A8, 'M', '蓱'), + (0x2F9A9, 'M', '蓳'), + (0x2F9AA, 'M', 'è”–'), + (0x2F9AB, 'M', 'đ§'), + (0x2F9AC, 'M', '蕤'), + (0x2F9AD, 'M', 'đ¦¼¬'), + (0x2F9AE, 'M', 'ä•'), + (0x2F9AF, 'M', 'ä•¡'), + (0x2F9B0, 'M', 'đ¦¾±'), + (0x2F9B1, 'M', 'đ§ƒ’'), + (0x2F9B2, 'M', 'ä•«'), + (0x2F9B3, 'M', 'è™'), + (0x2F9B4, 'M', '虜'), + (0x2F9B5, 'M', '虧'), + (0x2F9B6, 'M', '虩'), + (0x2F9B7, 'M', 'è©'), + (0x2F9B8, 'M', 'èˆ'), + (0x2F9B9, 'M', 'èœ'), + (0x2F9BA, 'M', '蛢'), + (0x2F9BB, 'M', 'è¹'), + (0x2F9BC, 'M', '蜨'), + (0x2F9BD, 'M', 'è«'), + (0x2F9BE, 'M', 'è†'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', '蟡'), + (0x2F9C1, 'M', 'è '), + (0x2F9C2, 'M', 'ä—¹'), + (0x2F9C3, 'M', 'è¡ '), + (0x2F9C4, 'M', 'è¡£'), + (0x2F9C5, 'M', '𧙧'), + (0x2F9C6, 'M', '裗'), + (0x2F9C7, 'M', 'è£'), + (0x2F9C8, 'M', '䘵'), + (0x2F9C9, 'M', '裺'), + (0x2F9CA, 'M', 'ă’»'), + (0x2F9CB, 'M', 'đ§¢®'), + (0x2F9CC, 'M', 'đ§¥¦'), + (0x2F9CD, 'M', 'ä¾'), + (0x2F9CE, 'M', '䛇'), + (0x2F9CF, 'M', '誠'), + (0x2F9D0, 'M', 'è«­'), + (0x2F9D1, 'M', 'è®'), + (0x2F9D2, 'M', '豕'), + (0x2F9D3, 'M', 'đ§²¨'), + (0x2F9D4, 'M', '貫'), + (0x2F9D5, 'M', 'è³'), + ] + +def _seg_81() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F9D6, 'M', 'è´›'), + (0x2F9D7, 'M', 'èµ·'), + (0x2F9D8, 'M', 'đ§¼¯'), + (0x2F9D9, 'M', 'đ  „'), + (0x2F9DA, 'M', 'è·‹'), + (0x2F9DB, 'M', '趼'), + (0x2F9DC, 'M', 'è·°'), + (0x2F9DD, 'M', 'đ £'), + (0x2F9DE, 'M', 'è»”'), + (0x2F9DF, 'M', '輸'), + (0x2F9E0, 'M', '𨗒'), + (0x2F9E1, 'M', '𨗭'), + (0x2F9E2, 'M', 'é‚”'), + (0x2F9E3, 'M', '郱'), + (0x2F9E4, 'M', 'é„‘'), + (0x2F9E5, 'M', 'đ¨œ®'), + (0x2F9E6, 'M', 'é„›'), + (0x2F9E7, 'M', '鈸'), + (0x2F9E8, 'M', 'é‹—'), + (0x2F9E9, 'M', '鋘'), + (0x2F9EA, 'M', '鉼'), + (0x2F9EB, 'M', 'é¹'), + (0x2F9EC, 'M', 'é•'), + (0x2F9ED, 'M', 'đ¨¯º'), + (0x2F9EE, 'M', 'é–‹'), + (0x2F9EF, 'M', '䦕'), + (0x2F9F0, 'M', 'é–·'), + (0x2F9F1, 'M', '𨵷'), + (0x2F9F2, 'M', '䧦'), + (0x2F9F3, 'M', '雃'), + (0x2F9F4, 'M', '嶲'), + (0x2F9F5, 'M', '霣'), + (0x2F9F6, 'M', 'đ©……'), + (0x2F9F7, 'M', 'đ©ˆ'), + (0x2F9F8, 'M', 'ä©®'), + (0x2F9F9, 'M', '䩶'), + (0x2F9FA, 'M', '韠'), + (0x2F9FB, 'M', 'đ©'), + (0x2F9FC, 'M', '䪲'), + (0x2F9FD, 'M', 'đ©’–'), + (0x2F9FE, 'M', 'é ‹'), + (0x2FA00, 'M', 'é ©'), + (0x2FA01, 'M', 'đ©–¶'), + (0x2FA02, 'M', '飢'), + (0x2FA03, 'M', '䬳'), + (0x2FA04, 'M', '餩'), + (0x2FA05, 'M', '馧'), + (0x2FA06, 'M', '駂'), + (0x2FA07, 'M', '駾'), + (0x2FA08, 'M', 'ä¯'), + (0x2FA09, 'M', '𩬰'), + (0x2FA0A, 'M', '鬒'), + (0x2FA0B, 'M', 'é±€'), + (0x2FA0C, 'M', 'é³½'), + (0x2FA0D, 'M', 'ä³'), + (0x2FA0E, 'M', 'ä³­'), + (0x2FA0F, 'M', '鵧'), + (0x2FA10, 'M', 'đªƒ'), + (0x2FA11, 'M', '䳸'), + (0x2FA12, 'M', 'đª„…'), + (0x2FA13, 'M', 'đªˆ'), + (0x2FA14, 'M', 'đª‘'), + (0x2FA15, 'M', '麻'), + (0x2FA16, 'M', 'äµ–'), + (0x2FA17, 'M', '黹'), + (0x2FA18, 'M', '黾'), + (0x2FA19, 'M', 'é¼…'), + (0x2FA1A, 'M', 'é¼'), + (0x2FA1B, 'M', 'é¼–'), + (0x2FA1C, 'M', 'é¼»'), + (0x2FA1D, 'M', 'đª˜€'), + (0x2FA1E, 'X'), + (0x30000, 'V'), + (0x3134B, 'X'), + (0x31350, 'V'), + (0x323B0, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() + + _seg_78() + + _seg_79() + + _seg_80() + + _seg_81() +) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/LICENSE b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/METADATA b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/METADATA new file mode 100644 index 0000000..6272503 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/METADATA @@ -0,0 +1,134 @@ +Metadata-Version: 2.1 +Name: importlib-metadata +Version: 6.7.0 +Summary: Read metadata from Python packages +Home-page: https://github.com/python/importlib_metadata +Author: Jason R. Coombs +Author-email: jaraco@jaraco.com +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.7 +License-File: LICENSE +Requires-Dist: zipp (>=0.5) +Requires-Dist: typing-extensions (>=3.6.4) ; python_version < "3.8" +Provides-Extra: docs +Requires-Dist: sphinx (>=3.5) ; extra == 'docs' +Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs' +Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' +Requires-Dist: furo ; extra == 'docs' +Requires-Dist: sphinx-lint ; extra == 'docs' +Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs' +Provides-Extra: perf +Requires-Dist: ipython ; extra == 'perf' +Provides-Extra: testing +Requires-Dist: pytest (>=6) ; extra == 'testing' +Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing' +Requires-Dist: pytest-cov ; extra == 'testing' +Requires-Dist: pytest-enabler (>=1.3) ; extra == 'testing' +Requires-Dist: pytest-ruff ; extra == 'testing' +Requires-Dist: packaging ; extra == 'testing' +Requires-Dist: pyfakefs ; extra == 'testing' +Requires-Dist: flufl.flake8 ; extra == 'testing' +Requires-Dist: pytest-perf (>=0.9.2) ; extra == 'testing' +Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: importlib-resources (>=1.3) ; (python_version < "3.9") and extra == 'testing' + +.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg + :target: https://pypi.org/project/importlib_metadata + +.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg + +.. image:: https://github.com/python/importlib_metadata/workflows/tests/badge.svg + :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Code style: Black + +.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest + :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2023-informational + :target: https://blog.jaraco.com/skeleton + +.. image:: https://tidelift.com/badges/package/pypi/importlib-metadata + :target: https://tidelift.com/subscription/pkg/pypi-importlib-metadata?utm_source=pypi-importlib-metadata&utm_medium=readme + +Library to access the metadata for a Python package. + +This package supplies third-party access to the functionality of +`importlib.metadata `_ +including improvements added to subsequent Python versions. + + +Compatibility +============= + +New features are introduced in this third-party library and later merged +into CPython. The following table indicates which versions of this library +were contributed to different versions in the standard library: + +.. list-table:: + :header-rows: 1 + + * - importlib_metadata + - stdlib + * - 6.5 + - 3.12 + * - 4.13 + - 3.11 + * - 4.6 + - 3.10 + * - 1.4 + - 3.8 + + +Usage +===== + +See the `online documentation `_ +for usage details. + +`Finder authors +`_ can +also add support for custom package installers. See the above documentation +for details. + + +Caveats +======= + +This project primarily supports third-party packages installed by PyPA +tools (or other conforming packages). It does not support: + +- Packages in the stdlib. +- Packages installed without metadata. + +Project details +=============== + + * Project home: https://github.com/python/importlib_metadata + * Report bugs at: https://github.com/python/importlib_metadata/issues + * Code hosting: https://github.com/python/importlib_metadata + * Documentation: https://importlib-metadata.readthedocs.io/ + +For Enterprise +============== + +Available as part of the Tidelift Subscription. + +This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. + +`Learn more `_. + +Security Contact +================ + +To report a security vulnerability, please use the +`Tidelift security contact `_. +Tidelift will coordinate the fix and disclosure. diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/RECORD b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/RECORD new file mode 100644 index 0000000..84393ca --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/RECORD @@ -0,0 +1,25 @@ +importlib_metadata-6.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +importlib_metadata-6.7.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 +importlib_metadata-6.7.0.dist-info/METADATA,sha256=JDrzuuLRE3CxIRXLeXdZGGFDrVlEXUvt-chm0-s-TtI,4878 +importlib_metadata-6.7.0.dist-info/RECORD,, +importlib_metadata-6.7.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92 +importlib_metadata-6.7.0.dist-info/top_level.txt,sha256=CO3fD9yylANiXkrMo4qHLV_mqXL2sC5JFKgt1yWAT-A,19 +importlib_metadata/__init__.py,sha256=MQx_tU_lZg-7U91wdrlrsDt0MGPXkpraLevB8LO1NNc,30724 +importlib_metadata/__pycache__/__init__.cpython-37.pyc,, +importlib_metadata/__pycache__/_adapters.cpython-37.pyc,, +importlib_metadata/__pycache__/_collections.cpython-37.pyc,, +importlib_metadata/__pycache__/_compat.cpython-37.pyc,, +importlib_metadata/__pycache__/_functools.cpython-37.pyc,, +importlib_metadata/__pycache__/_itertools.cpython-37.pyc,, +importlib_metadata/__pycache__/_meta.cpython-37.pyc,, +importlib_metadata/__pycache__/_py39compat.cpython-37.pyc,, +importlib_metadata/__pycache__/_text.cpython-37.pyc,, +importlib_metadata/_adapters.py,sha256=i8S6Ib1OQjcILA-l4gkzktMZe18TaeUNI49PLRp6OBU,2454 +importlib_metadata/_collections.py,sha256=CJ0OTCHIjWA0ZIVS4voORAsn2R4R2cQBEtPsZEJpASY,743 +importlib_metadata/_compat.py,sha256=xaiD8pwYYPCWkVgR30411iT4OmLbSbSAigzhp0nTROw,1735 +importlib_metadata/_functools.py,sha256=PsY2-4rrKX4RVeRC1oGp1lB1pmC9eKN88_f-bD9uOoA,2895 +importlib_metadata/_itertools.py,sha256=cvr_2v8BRbxcIl5x5ldfqdHjhI8Yi8s8yk50G_nm6jQ,2068 +importlib_metadata/_meta.py,sha256=I2AuaUMr5a6cTdZleV9WpyqUCSooqqV-zSzr1qn7FMw,1615 +importlib_metadata/_py39compat.py,sha256=2Tk5twb_VgLCY-1NEAQjdZp_S9OFMC-pUzP2isuaPsQ,1098 +importlib_metadata/_text.py,sha256=HCsFksZpJLeTP3NEk_ngrAeXVRRtTrtyh9eOABoRP4A,2166 +importlib_metadata/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/WHEEL new file mode 100644 index 0000000..1f37c02 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/top_level.txt new file mode 100644 index 0000000..bbb0754 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata-6.7.0.dist-info/top_level.txt @@ -0,0 +1 @@ +importlib_metadata diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__init__.py b/.venv/lib/python3.7/site-packages/importlib_metadata/__init__.py new file mode 100644 index 0000000..8147d2f --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/__init__.py @@ -0,0 +1,1015 @@ +import os +import re +import abc +import csv +import sys +import zipp +import email +import inspect +import pathlib +import operator +import textwrap +import warnings +import functools +import itertools +import posixpath +import collections + +from . import _adapters, _meta, _py39compat +from ._collections import FreezableDefaultDict, Pair +from ._compat import ( + NullFinder, + StrPath, + install, + pypy_partial, +) +from ._functools import method_cache, pass_none +from ._itertools import always_iterable, unique_everseen +from ._meta import PackageMetadata, SimplePath + +from contextlib import suppress +from importlib import import_module +from importlib.abc import MetaPathFinder +from itertools import starmap +from typing import Iterable, List, Mapping, Optional, Set, cast + +__all__ = [ + 'Distribution', + 'DistributionFinder', + 'PackageMetadata', + 'PackageNotFoundError', + 'distribution', + 'distributions', + 'entry_points', + 'files', + 'metadata', + 'packages_distributions', + 'requires', + 'version', +] + + +class PackageNotFoundError(ModuleNotFoundError): + """The package was not found.""" + + def __str__(self) -> str: + return f"No package metadata was found for {self.name}" + + @property + def name(self) -> str: # type: ignore[override] + (name,) = self.args + return name + + +class Sectioned: + """ + A simple entry point config parser for performance + + >>> for item in Sectioned.read(Sectioned._sample): + ... print(item) + Pair(name='sec1', value='# comments ignored') + Pair(name='sec1', value='a = 1') + Pair(name='sec1', value='b = 2') + Pair(name='sec2', value='a = 2') + + >>> res = Sectioned.section_pairs(Sectioned._sample) + >>> item = next(res) + >>> item.name + 'sec1' + >>> item.value + Pair(name='a', value='1') + >>> item = next(res) + >>> item.value + Pair(name='b', value='2') + >>> item = next(res) + >>> item.name + 'sec2' + >>> item.value + Pair(name='a', value='2') + >>> list(res) + [] + """ + + _sample = textwrap.dedent( + """ + [sec1] + # comments ignored + a = 1 + b = 2 + + [sec2] + a = 2 + """ + ).lstrip() + + @classmethod + def section_pairs(cls, text): + return ( + section._replace(value=Pair.parse(section.value)) + for section in cls.read(text, filter_=cls.valid) + if section.name is not None + ) + + @staticmethod + def read(text, filter_=None): + lines = filter(filter_, map(str.strip, text.splitlines())) + name = None + for value in lines: + section_match = value.startswith('[') and value.endswith(']') + if section_match: + name = value.strip('[]') + continue + yield Pair(name, value) + + @staticmethod + def valid(line: str): + return line and not line.startswith('#') + + +class DeprecatedTuple: + """ + Provide subscript item access for backward compatibility. + + >>> recwarn = getfixture('recwarn') + >>> ep = EntryPoint(name='name', value='value', group='group') + >>> ep[:] + ('name', 'value', 'group') + >>> ep[0] + 'name' + >>> len(recwarn) + 1 + """ + + # Do not remove prior to 2023-05-01 or Python 3.13 + _warn = functools.partial( + warnings.warn, + "EntryPoint tuple interface is deprecated. Access members by name.", + DeprecationWarning, + stacklevel=pypy_partial(2), + ) + + def __getitem__(self, item): + self._warn() + return self._key()[item] + + +class EntryPoint(DeprecatedTuple): + """An entry point as defined by Python packaging conventions. + + See `the packaging docs on entry points + `_ + for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] + """ + + pattern = re.compile( + r'(?P[\w.]+)\s*' + r'(:\s*(?P[\w.]+)\s*)?' + r'((?P\[.*\])\s*)?$' + ) + """ + A regular expression describing the syntax for an entry point, + which might look like: + + - module + - package.module + - package.module:attribute + - package.module:object.attribute + - package.module:attr [extra1, extra2] + + Other combinations are possible as well. + + The expression is lenient about whitespace around the ':', + following the attr, and following any extras. + """ + + name: str + value: str + group: str + + dist: Optional['Distribution'] = None + + def __init__(self, name: str, value: str, group: str) -> None: + vars(self).update(name=name, value=value, group=group) + + def load(self): + """Load the entry point from its definition. If only a module + is indicated by the value, return that module. Otherwise, + return the named object. + """ + match = self.pattern.match(self.value) + module = import_module(match.group('module')) + attrs = filter(None, (match.group('attr') or '').split('.')) + return functools.reduce(getattr, attrs, module) + + @property + def module(self) -> str: + match = self.pattern.match(self.value) + assert match is not None + return match.group('module') + + @property + def attr(self) -> str: + match = self.pattern.match(self.value) + assert match is not None + return match.group('attr') + + @property + def extras(self) -> List[str]: + match = self.pattern.match(self.value) + assert match is not None + return re.findall(r'\w+', match.group('extras') or '') + + def _for(self, dist): + vars(self).update(dist=dist) + return self + + def matches(self, **params): + """ + EntryPoint matches the given parameters. + + >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') + >>> ep.matches(group='foo') + True + >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') + True + >>> ep.matches(group='foo', name='other') + False + >>> ep.matches() + True + >>> ep.matches(extras=['extra1', 'extra2']) + True + >>> ep.matches(module='bing') + True + >>> ep.matches(attr='bong') + True + """ + attrs = (getattr(self, param) for param in params) + return all(map(operator.eq, params.values(), attrs)) + + def _key(self): + return self.name, self.value, self.group + + def __lt__(self, other): + return self._key() < other._key() + + def __eq__(self, other): + return self._key() == other._key() + + def __setattr__(self, name, value): + raise AttributeError("EntryPoint objects are immutable.") + + def __repr__(self): + return ( + f'EntryPoint(name={self.name!r}, value={self.value!r}, ' + f'group={self.group!r})' + ) + + def __hash__(self) -> int: + return hash(self._key()) + + +class EntryPoints(tuple): + """ + An immutable collection of selectable EntryPoint objects. + """ + + __slots__ = () + + def __getitem__(self, name: str) -> EntryPoint: # type: ignore[override] + """ + Get the EntryPoint in self matching name. + """ + try: + return next(iter(self.select(name=name))) + except StopIteration: + raise KeyError(name) + + def select(self, **params): + """ + Select entry points from self that match the + given parameters (typically group and/or name). + """ + return EntryPoints(ep for ep in self if _py39compat.ep_matches(ep, **params)) + + @property + def names(self) -> Set[str]: + """ + Return the set of all names of all entry points. + """ + return {ep.name for ep in self} + + @property + def groups(self) -> Set[str]: + """ + Return the set of all groups of all entry points. + """ + return {ep.group for ep in self} + + @classmethod + def _from_text_for(cls, text, dist): + return cls(ep._for(dist) for ep in cls._from_text(text)) + + @staticmethod + def _from_text(text): + return ( + EntryPoint(name=item.value.name, value=item.value.value, group=item.name) + for item in Sectioned.section_pairs(text or '') + ) + + +class PackagePath(pathlib.PurePosixPath): + """A reference to a path in a package""" + + hash: Optional["FileHash"] + size: int + dist: "Distribution" + + def read_text(self, encoding: str = 'utf-8') -> str: # type: ignore[override] + with self.locate().open(encoding=encoding) as stream: + return stream.read() + + def read_binary(self) -> bytes: + with self.locate().open('rb') as stream: + return stream.read() + + def locate(self) -> pathlib.Path: + """Return a path-like object for this path""" + return self.dist.locate_file(self) + + +class FileHash: + def __init__(self, spec: str) -> None: + self.mode, _, self.value = spec.partition('=') + + def __repr__(self) -> str: + return f'' + + +class DeprecatedNonAbstract: + def __new__(cls, *args, **kwargs): + all_names = { + name for subclass in inspect.getmro(cls) for name in vars(subclass) + } + abstract = { + name + for name in all_names + if getattr(getattr(cls, name), '__isabstractmethod__', False) + } + if abstract: + warnings.warn( + f"Unimplemented abstract methods {abstract}", + DeprecationWarning, + stacklevel=2, + ) + return super().__new__(cls) + + +class Distribution(DeprecatedNonAbstract): + """A Python distribution package.""" + + @abc.abstractmethod + def read_text(self, filename) -> Optional[str]: + """Attempt to load metadata file given by the name. + + :param filename: The name of the file in the distribution info. + :return: The text if found, otherwise None. + """ + + @abc.abstractmethod + def locate_file(self, path: StrPath) -> pathlib.Path: + """ + Given a path to a file in this distribution, return a path + to it. + """ + + @classmethod + def from_name(cls, name: str) -> "Distribution": + """Return the Distribution for the given package name. + + :param name: The name of the distribution package to search for. + :return: The Distribution instance (or subclass thereof) for the named + package, if found. + :raises PackageNotFoundError: When the named package's distribution + metadata cannot be found. + :raises ValueError: When an invalid value is supplied for name. + """ + if not name: + raise ValueError("A distribution name is required.") + try: + return next(iter(cls.discover(name=name))) + except StopIteration: + raise PackageNotFoundError(name) + + @classmethod + def discover(cls, **kwargs) -> Iterable["Distribution"]: + """Return an iterable of Distribution objects for all packages. + + Pass a ``context`` or pass keyword arguments for constructing + a context. + + :context: A ``DistributionFinder.Context`` object. + :return: Iterable of Distribution objects for all packages. + """ + context = kwargs.pop('context', None) + if context and kwargs: + raise ValueError("cannot accept context and kwargs") + context = context or DistributionFinder.Context(**kwargs) + return itertools.chain.from_iterable( + resolver(context) for resolver in cls._discover_resolvers() + ) + + @staticmethod + def at(path: StrPath) -> "Distribution": + """Return a Distribution for the indicated metadata path + + :param path: a string or path-like object + :return: a concrete Distribution instance for the path + """ + return PathDistribution(pathlib.Path(path)) + + @staticmethod + def _discover_resolvers(): + """Search the meta_path for resolvers.""" + declared = ( + getattr(finder, 'find_distributions', None) for finder in sys.meta_path + ) + return filter(None, declared) + + @property + def metadata(self) -> _meta.PackageMetadata: + """Return the parsed metadata for this Distribution. + + The returned object will have keys that name the various bits of + metadata. See PEP 566 for details. + """ + opt_text = ( + self.read_text('METADATA') + or self.read_text('PKG-INFO') + # This last clause is here to support old egg-info files. Its + # effect is to just end up using the PathDistribution's self._path + # (which points to the egg-info file) attribute unchanged. + or self.read_text('') + ) + text = cast(str, opt_text) + return _adapters.Message(email.message_from_string(text)) + + @property + def name(self) -> str: + """Return the 'Name' metadata for the distribution package.""" + return self.metadata['Name'] + + @property + def _normalized_name(self): + """Return a normalized version of the name.""" + return Prepared.normalize(self.name) + + @property + def version(self) -> str: + """Return the 'Version' metadata for the distribution package.""" + return self.metadata['Version'] + + @property + def entry_points(self) -> EntryPoints: + return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) + + @property + def files(self) -> Optional[List[PackagePath]]: + """Files in this distribution. + + :return: List of PackagePath for this distribution or None + + Result is `None` if the metadata file that enumerates files + (i.e. RECORD for dist-info, or installed-files.txt or + SOURCES.txt for egg-info) is missing. + Result may be empty if the metadata exists but is empty. + """ + + def make_file(name, hash=None, size_str=None): + result = PackagePath(name) + result.hash = FileHash(hash) if hash else None + result.size = int(size_str) if size_str else None + result.dist = self + return result + + @pass_none + def make_files(lines): + return starmap(make_file, csv.reader(lines)) + + @pass_none + def skip_missing_files(package_paths): + return list(filter(lambda path: path.locate().exists(), package_paths)) + + return skip_missing_files( + make_files( + self._read_files_distinfo() + or self._read_files_egginfo_installed() + or self._read_files_egginfo_sources() + ) + ) + + def _read_files_distinfo(self): + """ + Read the lines of RECORD + """ + text = self.read_text('RECORD') + return text and text.splitlines() + + def _read_files_egginfo_installed(self): + """ + Read installed-files.txt and return lines in a similar + CSV-parsable format as RECORD: each file must be placed + relative to the site-packages directory and must also be + quoted (since file names can contain literal commas). + + This file is written when the package is installed by pip, + but it might not be written for other installation methods. + Assume the file is accurate if it exists. + """ + text = self.read_text('installed-files.txt') + # Prepend the .egg-info/ subdir to the lines in this file. + # But this subdir is only available from PathDistribution's + # self._path. + subdir = getattr(self, '_path', None) + if not text or not subdir: + return + + paths = ( + (subdir / name) + .resolve() + .relative_to(self.locate_file('').resolve()) + .as_posix() + for name in text.splitlines() + ) + return map('"{}"'.format, paths) + + def _read_files_egginfo_sources(self): + """ + Read SOURCES.txt and return lines in a similar CSV-parsable + format as RECORD: each file name must be quoted (since it + might contain literal commas). + + Note that SOURCES.txt is not a reliable source for what + files are installed by a package. This file is generated + for a source archive, and the files that are present + there (e.g. setup.py) may not correctly reflect the files + that are present after the package has been installed. + """ + text = self.read_text('SOURCES.txt') + return text and map('"{}"'.format, text.splitlines()) + + @property + def requires(self) -> Optional[List[str]]: + """Generated requirements specified for this Distribution""" + reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() + return reqs and list(reqs) + + def _read_dist_info_reqs(self): + return self.metadata.get_all('Requires-Dist') + + def _read_egg_info_reqs(self): + source = self.read_text('requires.txt') + return pass_none(self._deps_from_requires_text)(source) + + @classmethod + def _deps_from_requires_text(cls, source): + return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) + + @staticmethod + def _convert_egg_info_reqs_to_simple_reqs(sections): + """ + Historically, setuptools would solicit and store 'extra' + requirements, including those with environment markers, + in separate sections. More modern tools expect each + dependency to be defined separately, with any relevant + extras and environment markers attached directly to that + requirement. This method converts the former to the + latter. See _test_deps_from_requires_text for an example. + """ + + def make_condition(name): + return name and f'extra == "{name}"' + + def quoted_marker(section): + section = section or '' + extra, sep, markers = section.partition(':') + if extra and markers: + markers = f'({markers})' + conditions = list(filter(None, [markers, make_condition(extra)])) + return '; ' + ' and '.join(conditions) if conditions else '' + + def url_req_space(req): + """ + PEP 508 requires a space between the url_spec and the quoted_marker. + Ref python/importlib_metadata#357. + """ + # '@' is uniquely indicative of a url_req. + return ' ' * ('@' in req) + + for section in sections: + space = url_req_space(section.value) + yield section.value + space + quoted_marker(section.name) + + +class DistributionFinder(MetaPathFinder): + """ + A MetaPathFinder capable of discovering installed distributions. + """ + + class Context: + """ + Keyword arguments presented by the caller to + ``distributions()`` or ``Distribution.discover()`` + to narrow the scope of a search for distributions + in all DistributionFinders. + + Each DistributionFinder may expect any parameters + and should attempt to honor the canonical + parameters defined below when appropriate. + """ + + name = None + """ + Specific name for which a distribution finder should match. + A name of ``None`` matches all distributions. + """ + + def __init__(self, **kwargs): + vars(self).update(kwargs) + + @property + def path(self) -> List[str]: + """ + The sequence of directory path that a distribution finder + should search. + + Typically refers to Python installed package paths such as + "site-packages" directories and defaults to ``sys.path``. + """ + return vars(self).get('path', sys.path) + + @abc.abstractmethod + def find_distributions(self, context=Context()) -> Iterable[Distribution]: + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the ``context``, + a DistributionFinder.Context instance. + """ + + +class FastPath: + """ + Micro-optimized class for searching a path for + children. + + >>> FastPath('').children() + ['...'] + """ + + @functools.lru_cache() # type: ignore + def __new__(cls, root): + return super().__new__(cls) + + def __init__(self, root): + self.root = root + + def joinpath(self, child): + return pathlib.Path(self.root, child) + + def children(self): + with suppress(Exception): + return os.listdir(self.root or '.') + with suppress(Exception): + return self.zip_children() + return [] + + def zip_children(self): + zip_path = zipp.Path(self.root) + names = zip_path.root.namelist() + self.joinpath = zip_path.joinpath + + return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) + + def search(self, name): + return self.lookup(self.mtime).search(name) + + @property + def mtime(self): + with suppress(OSError): + return os.stat(self.root).st_mtime + self.lookup.cache_clear() + + @method_cache + def lookup(self, mtime): + return Lookup(self) + + +class Lookup: + def __init__(self, path: FastPath): + base = os.path.basename(path.root).lower() + base_is_egg = base.endswith(".egg") + self.infos = FreezableDefaultDict(list) + self.eggs = FreezableDefaultDict(list) + + for child in path.children(): + low = child.lower() + if low.endswith((".dist-info", ".egg-info")): + # rpartition is faster than splitext and suitable for this purpose. + name = low.rpartition(".")[0].partition("-")[0] + normalized = Prepared.normalize(name) + self.infos[normalized].append(path.joinpath(child)) + elif base_is_egg and low == "egg-info": + name = base.rpartition(".")[0].partition("-")[0] + legacy_normalized = Prepared.legacy_normalize(name) + self.eggs[legacy_normalized].append(path.joinpath(child)) + + self.infos.freeze() + self.eggs.freeze() + + def search(self, prepared): + infos = ( + self.infos[prepared.normalized] + if prepared + else itertools.chain.from_iterable(self.infos.values()) + ) + eggs = ( + self.eggs[prepared.legacy_normalized] + if prepared + else itertools.chain.from_iterable(self.eggs.values()) + ) + return itertools.chain(infos, eggs) + + +class Prepared: + """ + A prepared search for metadata on a possibly-named package. + """ + + normalized = None + legacy_normalized = None + + def __init__(self, name): + self.name = name + if name is None: + return + self.normalized = self.normalize(name) + self.legacy_normalized = self.legacy_normalize(name) + + @staticmethod + def normalize(name): + """ + PEP 503 normalization plus dashes as underscores. + """ + return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') + + @staticmethod + def legacy_normalize(name): + """ + Normalize the package name as found in the convention in + older packaging tools versions and specs. + """ + return name.lower().replace('-', '_') + + def __bool__(self): + return bool(self.name) + + +@install +class MetadataPathFinder(NullFinder, DistributionFinder): + """A degenerate finder for distribution packages on the file system. + + This finder supplies only a find_distributions() method for versions + of Python that do not have a PathFinder find_distributions(). + """ + + def find_distributions( + self, context=DistributionFinder.Context() + ) -> Iterable["PathDistribution"]: + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching ``context.name`` + (or all names if ``None`` indicated) along the paths in the list + of directories ``context.path``. + """ + found = self._search_paths(context.name, context.path) + return map(PathDistribution, found) + + @classmethod + def _search_paths(cls, name, paths): + """Find metadata directories in paths heuristically.""" + prepared = Prepared(name) + return itertools.chain.from_iterable( + path.search(prepared) for path in map(FastPath, paths) + ) + + def invalidate_caches(cls) -> None: + FastPath.__new__.cache_clear() + + +class PathDistribution(Distribution): + def __init__(self, path: SimplePath) -> None: + """Construct a distribution. + + :param path: SimplePath indicating the metadata directory. + """ + self._path = path + + def read_text(self, filename: StrPath) -> Optional[str]: + with suppress( + FileNotFoundError, + IsADirectoryError, + KeyError, + NotADirectoryError, + PermissionError, + ): + return self._path.joinpath(filename).read_text(encoding='utf-8') + + return None + + read_text.__doc__ = Distribution.read_text.__doc__ + + def locate_file(self, path: StrPath) -> pathlib.Path: + return self._path.parent / path + + @property + def _normalized_name(self): + """ + Performance optimization: where possible, resolve the + normalized name from the file system path. + """ + stem = os.path.basename(str(self._path)) + return ( + pass_none(Prepared.normalize)(self._name_from_stem(stem)) + or super()._normalized_name + ) + + @staticmethod + def _name_from_stem(stem): + """ + >>> PathDistribution._name_from_stem('foo-3.0.egg-info') + 'foo' + >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') + 'CherryPy' + >>> PathDistribution._name_from_stem('face.egg-info') + 'face' + >>> PathDistribution._name_from_stem('foo.bar') + """ + filename, ext = os.path.splitext(stem) + if ext not in ('.dist-info', '.egg-info'): + return + name, sep, rest = filename.partition('-') + return name + + +def distribution(distribution_name) -> Distribution: + """Get the ``Distribution`` instance for the named package. + + :param distribution_name: The name of the distribution package as a string. + :return: A ``Distribution`` instance (or subclass thereof). + """ + return Distribution.from_name(distribution_name) + + +def distributions(**kwargs) -> Iterable[Distribution]: + """Get all ``Distribution`` instances in the current environment. + + :return: An iterable of ``Distribution`` instances. + """ + return Distribution.discover(**kwargs) + + +def metadata(distribution_name) -> _meta.PackageMetadata: + """Get the metadata for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: A PackageMetadata containing the parsed metadata. + """ + return Distribution.from_name(distribution_name).metadata + + +def version(distribution_name) -> str: + """Get the version string for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: The version string for the package as defined in the package's + "Version" metadata key. + """ + return distribution(distribution_name).version + + +_unique = functools.partial( + unique_everseen, + key=_py39compat.normalized_name, +) +""" +Wrapper for ``distributions`` to return unique distributions by name. +""" + + +def entry_points(**params) -> EntryPoints: + """Return EntryPoint objects for all installed packages. + + Pass selection parameters (group or name) to filter the + result to entry points matching those properties (see + EntryPoints.select()). + + :return: EntryPoints for all installed packages. + """ + eps = itertools.chain.from_iterable( + dist.entry_points for dist in _unique(distributions()) + ) + return EntryPoints(eps).select(**params) + + +def files(distribution_name) -> Optional[List[PackagePath]]: + """Return a list of files for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: List of files composing the distribution. + """ + return distribution(distribution_name).files + + +def requires(distribution_name) -> Optional[List[str]]: + """ + Return a list of requirements for the named package. + + :return: An iterable of requirements, suitable for + packaging.requirement.Requirement. + """ + return distribution(distribution_name).requires + + +def packages_distributions() -> Mapping[str, List[str]]: + """ + Return a mapping of top-level packages to their + distributions. + + >>> import collections.abc + >>> pkgs = packages_distributions() + >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) + True + """ + pkg_to_dist = collections.defaultdict(list) + for dist in distributions(): + for pkg in _top_level_declared(dist) or _top_level_inferred(dist): + pkg_to_dist[pkg].append(dist.metadata['Name']) + return dict(pkg_to_dist) + + +def _top_level_declared(dist): + return (dist.read_text('top_level.txt') or '').split() + + +def _topmost(name: PackagePath) -> Optional[str]: + """ + Return the top-most parent as long as there is a parent. + """ + top, *rest = name.parts + return top if rest else None + + +def _get_toplevel_name(name: PackagePath) -> str: + """ + Infer a possibly importable module name from a name presumed on + sys.path. + + >>> _get_toplevel_name(PackagePath('foo.py')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo.pyc')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo/__init__.py')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo.pth')) + 'foo.pth' + >>> _get_toplevel_name(PackagePath('foo.dist-info')) + 'foo.dist-info' + """ + return _topmost(name) or ( + # python/typeshed#10328 + inspect.getmodulename(name) # type: ignore + or str(name) + ) + + +def _top_level_inferred(dist): + opt_names = set(map(_get_toplevel_name, always_iterable(dist.files))) + + def importable_name(name): + return '.' not in name + + return filter(importable_name, opt_names) diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad21cf9f27b33b53e7aa8c922be8ca5d53d78fc8 GIT binary patch literal 36573 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_collections.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_collections.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d61e1ffd97d850854e048b5ef65563cea7e28853 GIT binary patch literal 1512 zcmaJ>OK(#-6t?dpNmD9@=ZpkGo)w8iQwoAriO>w1*##tasgUJfJFPp;y%*aTLDUT@ z60GG1G zYs2CxboUqrNhCF7OnxUak?98_Q$-HxaXL=GlF1w_xgsa2%w_8|0edFtOVV$Dg;+8w za9p-@v2ZBpDgE0I3zO|7Mk%i9Ms9sflQef2IpB zex`(U8MNmUuS%vp(~e2yv_((mD^^?eMwOoV1I4C|7hYE-t0pl>fNR8J62O=M3=0^J z=~8yb$bjmt+IF{J#n|2Xghv@w_N1IUZO6?5Y8xBQ8FZ|HyAFdV zM^IT$kI5la?T8*@)sj(Y^NFoys_dtsy{~{YZ$s{yTG_D9`BXaxiE`dgLgtj2g!B*f zu1~`n=YZo$hi?DTw%*dyy0YHrz0E0rOX0=2iJzHx zQ5mBm_ij+Xvn{wVUfRWU=TG1mr8L?K_&jTv z&r|3QIaxk`l}aoIIi~RRQ{XuZ*$biVcfv(-e_ci%fpk4ROpYl0bRZUfI?3mG8Nbmd zU$Ni-l1@b(Qh322UT<{`Q*E>d*`|eYA@l03KTl>}w7eG9soQu^)LAm?;#CIGJnHB6 z2iUS#a6l!6^{99d?Lj5&9W8WKuHO6)rVVs_ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_compat.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d968c13619310ce11084130a90aca81bc71ef75 GIT binary patch literal 2117 zcmZuy&2Q936rUM;cb&~9gcQn$`eA{DSgBbAs6v$xfHRmP%VE5NWJvXTmOLGdhex@uRZZE^wjsp+YO<0GGou1ulIhx-+TM%+FF;u^UIHa zj(%?w@)r*NeFFHn4bA)togji{Bx>F?qHfG025**mxgYtI2v7K;HS(fXwE^}v*xON? zl1HQneIh%PuKtb^{ByHGGy9kn>>DCF!h1oY6%mLPcy}KV(G~s+BK$dvR>i95fwd>; z{+d{uwDeEXm+O-3pOEY4$dH{Q(MHijn^vY|qVA-Hu{_J_ z?)Egx?x%&2x(;@&;=wA%TnN z?2m2;&)tk06AGCq&8^bm5ZdBOZoz>N{!L{DxwJekxg8I>Zr>dtOlZe4+~dilRN993 zQe$Za249=B0%bR47uz_cG}Y8@l+y;j~Eb7@noJ3f0if87s1M z&u#zjRRd@5`?Uwo)+ozY-S%~`d;+nWQCT?y5oV_G7KNGzQVEz5Y6`Pk=%Cy{C zK(LivyKY7wUrn#1IR*(1Y~k60TYhAUm!>#TIe;`MD~&X4A`Ku?LV|VLrU`!G!=No` zx&#A31$#lBlV@iw&|~R7o3nf5N${K=((k>e?>+*h0%`v2Hy7uF^q|3O34W>5oF|o| z4O<(e(9C)0Fmk|w%ss&- zOr5n9#@?J^+}m|Gj&miZnT+H5d_2@@CX0AUN-UpQsX;IGCK4MTi?z?{&Im}eR@a>| zH~0a>w;KsK=9{huUeui&v5@96`sKKzj0SXe>3;<@xS6ShXXe&mv27bP2q$OYj>g@( zgWU<}`b@ur-zbW=F4Zew`w&`l;Y!fjq|UZf49q#j+{Q)kK_>}TG^l1Y@}w^q)}lF$ zTEYjsS{jj^?K}MMgct6+w7L*p<`W)X_zJLaX}>V{firHyLV{*O1jRs}qBIb0^HD?M z)P^|+eZll`B`s)$``m-l#wzp>nn5pwt2Wy%Vqn7OdSvSM%^o*!i~XswE-wza zPF-mO50Xg+_-2?PCD%6PSqSL^fbUd0)gsRxDLvswX?5}XwHpn(wU4U+y`apvg%X|D zr^^cBaVe0=ToxFkDqx9sz_X~6nz*c>3c2`}LDoGqLK$}s+{Ad0BGT?r9m2cMUSnB$ zjdGlAC^OiB^6_Olk>5h;c+x*vGi4f8zYiF8v$&LwGKz)j<-qf@xU-CbVyKz}$Jr^Qe~A%}Dg{&gVg>{^Y3HzGO;E4bN+^%g46 gd;nblDI2h!*Yz0PpzCbY3)X_o_0^!;rKh}q06SbPr~m)} literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_functools.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_functools.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8e66f752bbddb85412b11d9a0d737cbdf771ebb GIT binary patch literal 3095 zcmaJ@&2QT_6qjT>aonUBFzf@xK6qMeEVkQtS%9Dk+T}PjJ7id~TpU`YW2Ta*kyK&_ z?qO(vW|#d5!+O|Zhy6VRblqv^-FDi0q+~m-R{@m7ulF8*zaJm@)y77{gXfPQ|2+HV zj_3V_mGY^;&m$=MGk7tN`H^?xzW#~NR#?C)*ZxVss;qYHom7~A?6p?^hOypJ7~lsU zv{4q_gvyPVHjMYH|H}Kxd+ELOhXM0ha9w{6)>!r0n+E-08i1u5{chFs8U&uFil!t| zSwE!Vh!Z1;&eBvWL$r}fBxl4xv+HEkP$ClBA_wO@G*HuqCL!0IhBfzippBxT(QcZI zW0{bYD$2xJOfE-Ufe$bkb2E~R@NpW6P?%^!G`--O(8QX_62_GdrQ+>W@u3)VMp7jW zxO9IhS7t)M_E0EoAigMqxr``oGL@irYOE!l4K)8D;|cgEVmvrFAYnwcCQl}Z_}#N3 zJDm;!Vr^-%Pwtnk<=6H;a*;c@ZuKxeESA;OJQ{A13mRp-b=x@Fz}^lSVr6OZwOVQ+vH+Oeli$nq1`-GPB$BQ;? zaMsf9j*H+3u(zOE_Gk)}0;FWXNAyB~r%M3@3^))9*y%7SHz` zPfnb!=WT3>Qj=sv84v^zFb?~Q;y$_*W<*X;hglLDDI?vP<$-4F^mNNQr-f24Wfn0o za>1RI-7iU#Wq_7^126)V-^ZbtJWA2ifi3Kb0>IlNT>mkRIYAz1nQSbDBdU{4Lna)>3uqvCoGlOJpV$uityI@aQf?{CkyW3lOr0Jb5##T3+xXgpxlCY3$X z+j3F#izxQ3ueq(aCz0(UvGiQ5hcq(+c4M0`NpOQL=2C(lELTM;w`3I?uGE->t*5ha zc}x={LX8?iAy|wch=QPF&IygQv<64UqifS))8=i7|?YmlyO(_P^4UUcXoHb*x7E=cFbc5z_ttZOVtK#w96y{-FP19u9GUN zrXW?sX~bj5b<|>kXAEUbV1-8HJkv%DMQA%ac5>+B*$ht&N)^hdQ1lkO@MymAr{1gJ zdF95NR$lnet0tIwH~x8LT76ORy=isoPlKQFu=kHz)x2gVu!y|z#76fmRPt5LArzzX zdcU85#QXhLEwAE{l2@rZ)A`D?OZ=X!4Y(b8T#uca%j*x_o;biM|3LAs zK3VRo9N4PlYqO~HwOJa>?<}OARz=}`POaf<178?HD{u|A%er4*^tA#*+_DeXgS+)c zpx%X+nMUv`hik%XoW2Jys}b*&|I!=!?(zmI@u#SW%GGaHU{7)5VYGNI3bU#0-gJ44 zK)x4n`Es`+ym!TL%#kBJH0@+OF;ckJnZDs;1GyxH`%gcC{-$l7r;7Qg<|dBabY1wn z#8MMoxDm6(;i9nE4e$~COo6*+YwAM~KP+$R{{pvB6#F8hKt;{Qt>A|0DO60$&#Smz zM>b+?;YWp7L3lykzq&VD$Qx1uir#^-c@3qdq4r*B!ZGN(220-B%*^*Q^Nsgw>I10R fJ*ki~YtJ%iJN`$7v1D1q4^X@sbx`-~)yDCEp8IAB literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_itertools.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_itertools.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bccd42e6f185e56f593f1213655e457243af58b9 GIT binary patch literal 1995 zcmbtV&2Aev5GHq5wyfAq;0Eb+kRId}WE)P9i_sWH+5!#G3PEEug$+ZZM6R{g{wO46 zd)w8aP+z8pK2L$Y_S9GCsY9-`QVkVpQA#AZ={co@Z*rG=KhtwZxWWsZfbtsO!0#G&-V(q52g(zl77v0j(n1C- zQlc|(%qq4G>_+tfySm0flNp&hxpPgYZcaHJ)#dTs8*NtHoXngr$mQGB^UAlzQwJ$FC?%issusY;EEC=Iq3La;VPjEmvJslaK(1FJ4h4F z!bEku{zg#`F?!aIMB$D^R(R&zdEJa%JX37W%@=g^3y}{{!=K+A>UexO4#)ebL!;&W z=-G31_2MWz4C8SsbrkmZW1$&mnk|>Q)l%1()M*;2gK<_oEaU7NuZ>yHK>h>=;%(3k zTBp0%x19!#<|lV>r^=HF2`NE7$F9zB$Pq)#%_B{?Geb0OuC`=b(;VkB2WKb~P_viS z&D_j9qMcDgb|_|zVy+hw-ok~az{-L%~ zu{u6(G+^FNPEG(-z)RRWYQwWOJoo>$7h&G_Sai!WWkE7|*~0_=QtV=W@Uqmp>Qs{I zHI6}=h<)@ouJ&L~07E1j(Rvq;{<~{yoa*&D=s>Txij;`QI;-4Si;p?mc%Ov>Hp|u`0gEVb^*rj{fvZq#H z=`$s|IvWd1BfOezLkKZIwggC>+hI5uLa!Gpd$*E-O+QAlIOg|y)`yaI3PsQ41mT6- zG-+z+i**4VtYhGhP1Zbyqv^j43E)$BZAyg}CBgMj01pScsQ?Rys?=Pd-plICF#exd zy%N?-qsjM;kuxcnwwf_X_&0S>SNbj%ZqG4&D>Sq!bXuTOgrsDgnX{WT*!q~B8*LMrg z*e@DOZWLQ*$fPf&Or`G>F2-@bRbgRImBTg`#^T|YUD|LQtgjzY zxog&F2OozmW6@S>`*_&eiw}yHMXjG{p{(eNA@e>+YpwoSobpK|PAD!ZQ`5KI#>amF DD{Lfg literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_meta.cpython-37.pyc b/.venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_meta.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c034dd83a0ab047ea58783effab98473f0af8bc GIT binary patch literal 2837 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 dd = FreezableDefaultDict(list) + >>> dd[0].append('1') + >>> dd.freeze() + >>> dd[1] + [] + >>> len(dd) + 1 + """ + + def __missing__(self, key): + return getattr(self, '_frozen', super().__missing__)(key) + + def freeze(self): + self._frozen = lambda key: self.default_factory() + + +class Pair(collections.namedtuple('Pair', 'name value')): + @classmethod + def parse(cls, text): + return cls(*map(str.strip, text.split("=", 1))) diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_compat.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_compat.py new file mode 100644 index 0000000..b7abd09 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_compat.py @@ -0,0 +1,74 @@ +import os +import sys +import platform + +from typing import Union + + +__all__ = ['install', 'NullFinder', 'Protocol'] + + +try: + from typing import Protocol +except ImportError: # pragma: no cover + # Python 3.7 compatibility + from typing_extensions import Protocol # type: ignore + + +def install(cls): + """ + Class decorator for installation on sys.meta_path. + + Adds the backport DistributionFinder to sys.meta_path and + attempts to disable the finder functionality of the stdlib + DistributionFinder. + """ + sys.meta_path.append(cls()) + disable_stdlib_finder() + return cls + + +def disable_stdlib_finder(): + """ + Give the backport primacy for discovering path-based distributions + by monkey-patching the stdlib O_O. + + See #91 for more background for rationale on this sketchy + behavior. + """ + + def matches(finder): + return getattr( + finder, '__module__', None + ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions') + + for finder in filter(matches, sys.meta_path): # pragma: nocover + del finder.find_distributions + + +class NullFinder: + """ + A "Finder" (aka "MetaClassFinder") that never finds any modules, + but may find distributions. + """ + + @staticmethod + def find_spec(*args, **kwargs): + return None + + +def pypy_partial(val): + """ + Adjust for variable stacklevel on partial under PyPy. + + Workaround for #327. + """ + is_pypy = platform.python_implementation() == 'PyPy' + return val + is_pypy + + +if sys.version_info >= (3, 9): + StrPath = Union[str, os.PathLike[str]] +else: + # PathLike is only subscriptable at runtime in 3.9+ + StrPath = Union[str, "os.PathLike[str]"] # pragma: no cover diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_functools.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_functools.py new file mode 100644 index 0000000..71f66bd --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_functools.py @@ -0,0 +1,104 @@ +import types +import functools + + +# from jaraco.functools 3.3 +def method_cache(method, cache_wrapper=None): + """ + Wrap lru_cache to support storing the cache data in the object instances. + + Abstracts the common paradigm where the method explicitly saves an + underscore-prefixed protected property on first call and returns that + subsequently. + + >>> class MyClass: + ... calls = 0 + ... + ... @method_cache + ... def method(self, value): + ... self.calls += 1 + ... return value + + >>> a = MyClass() + >>> a.method(3) + 3 + >>> for x in range(75): + ... res = a.method(x) + >>> a.calls + 75 + + Note that the apparent behavior will be exactly like that of lru_cache + except that the cache is stored on each instance, so values in one + instance will not flush values from another, and when an instance is + deleted, so are the cached values for that instance. + + >>> b = MyClass() + >>> for x in range(35): + ... res = b.method(x) + >>> b.calls + 35 + >>> a.method(0) + 0 + >>> a.calls + 75 + + Note that if method had been decorated with ``functools.lru_cache()``, + a.calls would have been 76 (due to the cached value of 0 having been + flushed by the 'b' instance). + + Clear the cache with ``.cache_clear()`` + + >>> a.method.cache_clear() + + Same for a method that hasn't yet been called. + + >>> c = MyClass() + >>> c.method.cache_clear() + + Another cache wrapper may be supplied: + + >>> cache = functools.lru_cache(maxsize=2) + >>> MyClass.method2 = method_cache(lambda self: 3, cache_wrapper=cache) + >>> a = MyClass() + >>> a.method2() + 3 + + Caution - do not subsequently wrap the method with another decorator, such + as ``@property``, which changes the semantics of the function. + + See also + http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ + for another implementation and additional justification. + """ + cache_wrapper = cache_wrapper or functools.lru_cache() + + def wrapper(self, *args, **kwargs): + # it's the first call, replace the method with a cached, bound method + bound_method = types.MethodType(method, self) + cached_method = cache_wrapper(bound_method) + setattr(self, method.__name__, cached_method) + return cached_method(*args, **kwargs) + + # Support cache clear even before cache has been created. + wrapper.cache_clear = lambda: None + + return wrapper + + +# From jaraco.functools 3.3 +def pass_none(func): + """ + Wrap func so it's not called if its first param is None + + >>> print_text = pass_none(print) + >>> print_text('text') + text + >>> print_text(None) + """ + + @functools.wraps(func) + def wrapper(param, *args, **kwargs): + if param is not None: + return func(param, *args, **kwargs) + + return wrapper diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_itertools.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_itertools.py new file mode 100644 index 0000000..d4ca9b9 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_itertools.py @@ -0,0 +1,73 @@ +from itertools import filterfalse + + +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +# copied from more_itertools 8.8 +def always_iterable(obj, base_type=(str, bytes)): + """If *obj* is iterable, return an iterator over its items:: + + >>> obj = (1, 2, 3) + >>> list(always_iterable(obj)) + [1, 2, 3] + + If *obj* is not iterable, return a one-item iterable containing *obj*:: + + >>> obj = 1 + >>> list(always_iterable(obj)) + [1] + + If *obj* is ``None``, return an empty iterable: + + >>> obj = None + >>> list(always_iterable(None)) + [] + + By default, binary and text strings are not considered iterable:: + + >>> obj = 'foo' + >>> list(always_iterable(obj)) + ['foo'] + + If *base_type* is set, objects for which ``isinstance(obj, base_type)`` + returns ``True`` won't be considered iterable. + + >>> obj = {'a': 1} + >>> list(always_iterable(obj)) # Iterate over the dict's keys + ['a'] + >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit + [{'a': 1}] + + Set *base_type* to ``None`` to avoid any special handling and treat objects + Python considers iterable as iterable: + + >>> obj = 'foo' + >>> list(always_iterable(obj, base_type=None)) + ['f', 'o', 'o'] + """ + if obj is None: + return iter(()) + + if (base_type is not None) and isinstance(obj, base_type): + return iter((obj,)) + + try: + return iter(obj) + except TypeError: + return iter((obj,)) diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_meta.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_meta.py new file mode 100644 index 0000000..0c7e879 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_meta.py @@ -0,0 +1,63 @@ +from ._compat import Protocol +from typing import Any, Dict, Iterator, List, Optional, TypeVar, Union, overload + + +_T = TypeVar("_T") + + +class PackageMetadata(Protocol): + def __len__(self) -> int: + ... # pragma: no cover + + def __contains__(self, item: str) -> bool: + ... # pragma: no cover + + def __getitem__(self, key: str) -> str: + ... # pragma: no cover + + def __iter__(self) -> Iterator[str]: + ... # pragma: no cover + + @overload + def get(self, name: str, failobj: None = None) -> Optional[str]: + ... # pragma: no cover + + @overload + def get(self, name: str, failobj: _T) -> Union[str, _T]: + ... # pragma: no cover + + # overload per python/importlib_metadata#435 + @overload + def get_all(self, name: str, failobj: None = None) -> Optional[List[Any]]: + ... # pragma: no cover + + @overload + def get_all(self, name: str, failobj: _T) -> Union[List[Any], _T]: + """ + Return all values associated with a possibly multi-valued key. + """ + + @property + def json(self) -> Dict[str, Union[str, List[str]]]: + """ + A JSON-compatible form of the metadata. + """ + + +class SimplePath(Protocol[_T]): + """ + A minimal subset of pathlib.Path required by PathDistribution. + """ + + def joinpath(self, other: Union[str, _T]) -> _T: + ... # pragma: no cover + + def __truediv__(self, other: Union[str, _T]) -> _T: + ... # pragma: no cover + + @property + def parent(self) -> _T: + ... # pragma: no cover + + def read_text(self) -> str: + ... # pragma: no cover diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_py39compat.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_py39compat.py new file mode 100644 index 0000000..cde4558 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_py39compat.py @@ -0,0 +1,35 @@ +""" +Compatibility layer with Python 3.8/3.9 +""" +from typing import TYPE_CHECKING, Any, Optional + +if TYPE_CHECKING: # pragma: no cover + # Prevent circular imports on runtime. + from . import Distribution, EntryPoint +else: + Distribution = EntryPoint = Any + + +def normalized_name(dist: Distribution) -> Optional[str]: + """ + Honor name normalization for distributions that don't provide ``_normalized_name``. + """ + try: + return dist._normalized_name + except AttributeError: + from . import Prepared # -> delay to prevent circular imports. + + return Prepared.normalize(getattr(dist, "name", None) or dist.metadata['Name']) + + +def ep_matches(ep: EntryPoint, **params) -> bool: + """ + Workaround for ``EntryPoint`` objects without the ``matches`` method. + """ + try: + return ep.matches(**params) + except AttributeError: + from . import EntryPoint # -> delay to prevent circular imports. + + # Reconstruct the EntryPoint object to make sure it is compatible. + return EntryPoint(ep.name, ep.value, ep.group).matches(**params) diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/_text.py b/.venv/lib/python3.7/site-packages/importlib_metadata/_text.py new file mode 100644 index 0000000..c88cfbb --- /dev/null +++ b/.venv/lib/python3.7/site-packages/importlib_metadata/_text.py @@ -0,0 +1,99 @@ +import re + +from ._functools import method_cache + + +# from jaraco.text 3.5 +class FoldedCase(str): + """ + A case insensitive string class; behaves just like str + except compares equal when the only variation is case. + + >>> s = FoldedCase('hello world') + + >>> s == 'Hello World' + True + + >>> 'Hello World' == s + True + + >>> s != 'Hello World' + False + + >>> s.index('O') + 4 + + >>> s.split('O') + ['hell', ' w', 'rld'] + + >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) + ['alpha', 'Beta', 'GAMMA'] + + Sequence membership is straightforward. + + >>> "Hello World" in [s] + True + >>> s in ["Hello World"] + True + + You may test for set inclusion, but candidate and elements + must both be folded. + + >>> FoldedCase("Hello World") in {s} + True + >>> s in {FoldedCase("Hello World")} + True + + String inclusion works as long as the FoldedCase object + is on the right. + + >>> "hello" in FoldedCase("Hello World") + True + + But not if the FoldedCase object is on the left: + + >>> FoldedCase('hello') in 'Hello World' + False + + In that case, use in_: + + >>> FoldedCase('hello').in_('Hello World') + True + + >>> FoldedCase('hello') > FoldedCase('Hello') + False + """ + + def __lt__(self, other): + return self.lower() < other.lower() + + def __gt__(self, other): + return self.lower() > other.lower() + + def __eq__(self, other): + return self.lower() == other.lower() + + def __ne__(self, other): + return self.lower() != other.lower() + + def __hash__(self): + return hash(self.lower()) + + def __contains__(self, other): + return super().lower().__contains__(other.lower()) + + def in_(self, other): + "Does self appear in other?" + return self in FoldedCase(other) + + # cache lower since it's likely to be called frequently. + @method_cache + def lower(self): + return super().lower() + + def index(self, sub): + return self.lower().index(sub.lower()) + + def split(self, splitter=' ', maxsplit=0): + pattern = re.compile(re.escape(splitter), re.I) + return pattern.split(self, maxsplit) diff --git a/.venv/lib/python3.7/site-packages/importlib_metadata/py.typed b/.venv/lib/python3.7/site-packages/importlib_metadata/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/INSTALLER b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSE.txt b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSE.txt new file mode 100644 index 0000000..a76d0ed --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSE.txt @@ -0,0 +1,29 @@ +Copyright (c) 2004 Infrae. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + 3. Neither the name of Infrae nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSES.txt b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSES.txt new file mode 100644 index 0000000..9f97c18 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/LICENSES.txt @@ -0,0 +1,29 @@ +lxml is copyright Infrae and distributed under the BSD license (see +doc/licenses/BSD.txt), with the following exceptions: + +Some code, such a selftest.py, selftest2.py and +src/lxml/_elementpath.py are derived from ElementTree and +cElementTree. See doc/licenses/elementtree.txt for the license text. + +lxml.cssselect and lxml.html are copyright Ian Bicking and distributed +under the BSD license (see doc/licenses/BSD.txt). + +test.py, the test-runner script, is GPL and copyright Shuttleworth +Foundation. See doc/licenses/GPL.txt. It is believed the unchanged +inclusion of test.py to run the unit test suite falls under the +"aggregation" clause of the GPL and thus does not affect the license +of the rest of the package. + +The isoschematron implementation uses several XSL and RelaxNG resources: + * The (XML syntax) RelaxNG schema for schematron, copyright International + Organization for Standardization (see + src/lxml/isoschematron/resources/rng/iso-schematron.rng for the license + text) + * The skeleton iso-schematron-xlt1 pure-xslt schematron implementation + xsl stylesheets, copyright Rick Jelliffe and Academia Sinica Computing + Center, Taiwan (see the xsl files here for the license text: + src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/) + * The xsd/rng schema schematron extraction xsl transformations are unlicensed + and copyright the respective authors as noted (see + src/lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl and + src/lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl) diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/METADATA b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/METADATA new file mode 100644 index 0000000..1966fa8 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/METADATA @@ -0,0 +1,98 @@ +Metadata-Version: 2.1 +Name: lxml +Version: 4.9.3 +Summary: Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API. +Home-page: https://lxml.de/ +Author: lxml dev team +Author-email: lxml-dev@lxml.de +Maintainer: lxml dev team +Maintainer-email: lxml-dev@lxml.de +License: BSD-3-Clause +Project-URL: Source, https://github.com/lxml/lxml +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Cython +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: C +Classifier: Operating System :: OS Independent +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Topic :: Text Processing :: Markup :: XML +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.* +License-File: LICENSE.txt +License-File: LICENSES.txt +Provides-Extra: cssselect +Requires-Dist: cssselect (>=0.7) ; extra == 'cssselect' +Provides-Extra: html5 +Requires-Dist: html5lib ; extra == 'html5' +Provides-Extra: htmlsoup +Requires-Dist: BeautifulSoup4 ; extra == 'htmlsoup' +Provides-Extra: source +Requires-Dist: Cython (>=0.29.35) ; extra == 'source' + +lxml is a Pythonic, mature binding for the libxml2 and libxslt libraries. It +provides safe and convenient access to these libraries using the ElementTree +API. + +It extends the ElementTree API significantly to offer support for XPath, +RelaxNG, XML Schema, XSLT, C14N and much more. + +To contact the project, go to the `project home page +`_ or see our bug tracker at +https://launchpad.net/lxml + +In case you want to use the current in-development version of lxml, +you can get it from the github repository at +https://github.com/lxml/lxml . Note that this requires Cython to +build the sources, see the build instructions on the project home +page. To the same end, running ``easy_install lxml==dev`` will +install lxml from +https://github.com/lxml/lxml/tarball/master#egg=lxml-dev if you have +an appropriate version of Cython installed. + + +After an official release of a new stable series, bug fixes may become +available at +https://github.com/lxml/lxml/tree/lxml-4.9 . +Running ``easy_install lxml==4.9bugfix`` will install +the unreleased branch state from +https://github.com/lxml/lxml/tarball/lxml-4.9#egg=lxml-4.9bugfix +as soon as a maintenance branch has been established. Note that this +requires Cython to be installed at an appropriate version for the build. + +4.9.3 (2023-07-05) +================== + +Bugs fixed +---------- + +* ``lxml.objectify`` accepted non-decimal numbers like ``²²²`` as integers. + +* A memory leak in ``lxml.html.clean`` was resolved by switching to Cython 0.29.34+. + +* GH#348: URL checking in the HTML cleaner was improved. + Patch by Tim McCormack. + +* GH#371, GH#373: Some regex strings were changed to raw strings to fix Python warnings. + Patches by Jakub Wilk and Anthony Sottile. + +Other changes +------------- + +* Wheels include zlib 1.2.13, libxml2 2.10.3 and libxslt 1.1.38 + (zlib 1.2.12, libxml2 2.10.3 and libxslt 1.1.37 on Windows). + +* Built with Cython 0.29.36 to adapt to changes in Python 3.12. + + diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/RECORD b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/RECORD new file mode 100644 index 0000000..b4e7091 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/RECORD @@ -0,0 +1,121 @@ +lxml-4.9.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +lxml-4.9.3.dist-info/LICENSE.txt,sha256=ae20RcEzWoMS1MCScYR-mVbYTw2fck0SU0DMP612eyo,1488 +lxml-4.9.3.dist-info/LICENSES.txt,sha256=QdSd1AaqDhVIptXyGjDWv2OLPNlutyid00jYPtLkA5I,1514 +lxml-4.9.3.dist-info/METADATA,sha256=ouTlpw5jKGmdXvYLiEPvyuKJ3h3f33OUTWg-H2UA7po,3755 +lxml-4.9.3.dist-info/RECORD,, +lxml-4.9.3.dist-info/WHEEL,sha256=JpOby2QveraAndQEB6nypczr2FoqB0x0kNpkIeJiH1A,104 +lxml-4.9.3.dist-info/top_level.txt,sha256=NjD988wqaKq512nshNdLt-uDxsjkp4Bh51m6N-dhUrk,5 +lxml/ElementInclude.py,sha256=PSLeZFvCa76WHJulPLxcZXJtCI2-4dK2CtqPRiYOAQg,8560 +lxml/__init__.py,sha256=71f4Pgl0xksXqReX16a_Q4bf88TgXzKQnhEjGvLaQ10,575 +lxml/__pycache__/ElementInclude.cpython-37.pyc,, +lxml/__pycache__/__init__.cpython-37.pyc,, +lxml/__pycache__/_elementpath.cpython-37.pyc,, +lxml/__pycache__/builder.cpython-37.pyc,, +lxml/__pycache__/cssselect.cpython-37.pyc,, +lxml/__pycache__/doctestcompare.cpython-37.pyc,, +lxml/__pycache__/pyclasslookup.cpython-37.pyc,, +lxml/__pycache__/sax.cpython-37.pyc,, +lxml/__pycache__/usedoctest.cpython-37.pyc,, +lxml/_elementpath.cpython-37m-arm-linux-gnueabihf.so,sha256=TxV3yksi9Vr0YD23aXv-f2BtK578AKUDDhabYe1JUfY,348592 +lxml/_elementpath.py,sha256=wo6_CnGtKSkadI-krW8gbEZ1fVPTnIJINNwrdRfT_fw,10742 +lxml/apihelpers.pxi,sha256=X9VHTgQGjf6F3AgG4BTHFqzoUWUclScGjileIvCMtFc,64452 +lxml/builder.cpython-37m-arm-linux-gnueabihf.so,sha256=HVqbmz5vvHoC41BLJYsR41PtuM6gMG5o3oVV4jZ-Lm4,188260 +lxml/builder.py,sha256=_eBVChPcD4XhLe4cXC3USsuV3tzNyHcLLykZnHPCfyg,8147 +lxml/classlookup.pxi,sha256=AocnunTzIJiJE87ILWLy3FoiP7AiPoezGk-JJjrCQiM,22462 +lxml/cleanup.pxi,sha256=L65WiKrJSOODfqMLVMMR8SFE4_BwjVHeudnPAUZcxNc,8458 +lxml/cssselect.py,sha256=-4m3YmKAU-iXEJsnleNRQK4K7tPmAoRdhuikOqbUxBU,3364 +lxml/debug.pxi,sha256=GorntYkTOs2Bm_HzI5ck3yPNPZAGzc3L37sKOiOSCOY,3283 +lxml/docloader.pxi,sha256=DXwTMv2MR37LfVxtLmg9CFUMbHpuZ5X-AqXMF-sqzik,5783 +lxml/doctestcompare.py,sha256=dAjqNzMGJuDsxY0xOXwOWzEsq7gSfQf-6uuxZZwaNXM,18339 +lxml/dtd.pxi,sha256=-ytHvi8sDedEX2q9_3i3JbA1FUtSOhUzW3wpKKeUBZs,15219 +lxml/etree.cpython-37m-arm-linux-gnueabihf.so,sha256=RsBGVAlRvOhYszzPi4PagAWT0YuQje04AQ1vu2hxRaA,3840660 +lxml/etree.h,sha256=zH_dnQObaEbqPbLlrSjzkQU_f84P7NuBuCll5Psqads,8575 +lxml/etree.pyx,sha256=Pu0C0c2DDHA33CWnPnxRYGx4pi0uF63JtzaCbAIVnNk,132415 +lxml/etree_api.h,sha256=tgRCNFScrABi7OMWf9ouVJ33fW0Bd8j6mYMpEMsXqZU,17851 +lxml/extensions.pxi,sha256=RGenDcaZ-tJiw_EJKk9BTUSZFhcPU2CQ_c8FHwVO9k0,33241 +lxml/html/ElementSoup.py,sha256=s_dLobLMuKn2DhexR-iDXdZrMFg1RjLy1feHsIeZMpw,320 +lxml/html/__init__.py,sha256=rbuJ5hfzlh37D9AMd7Srj6D17l9wL6Rub0-IUVGVx04,64937 +lxml/html/__pycache__/ElementSoup.cpython-37.pyc,, +lxml/html/__pycache__/__init__.cpython-37.pyc,, +lxml/html/__pycache__/_diffcommand.cpython-37.pyc,, +lxml/html/__pycache__/_html5builder.cpython-37.pyc,, +lxml/html/__pycache__/_setmixin.cpython-37.pyc,, +lxml/html/__pycache__/builder.cpython-37.pyc,, +lxml/html/__pycache__/clean.cpython-37.pyc,, +lxml/html/__pycache__/defs.cpython-37.pyc,, +lxml/html/__pycache__/diff.cpython-37.pyc,, +lxml/html/__pycache__/formfill.cpython-37.pyc,, +lxml/html/__pycache__/html5parser.cpython-37.pyc,, +lxml/html/__pycache__/soupparser.cpython-37.pyc,, +lxml/html/__pycache__/usedoctest.cpython-37.pyc,, +lxml/html/_diffcommand.py,sha256=7-tz3udrgg0unGPAI8pa_uN4e7vW0MmgOXE43kKPdw8,2121 +lxml/html/_html5builder.py,sha256=cASxN0Tks3_vqCA_sXa1oCx_McyRL6VpuRLA1T-B58o,3246 +lxml/html/_setmixin.py,sha256=uVCgBUC4SJ7N9GotmlKHrhH7R4Kk7wGU3u1WmEJKGeM,1184 +lxml/html/builder.py,sha256=aRgS-Ea9bli-muGX0iUQGKAe9D93P8BspQ2WPuiWJcU,4492 +lxml/html/clean.cpython-37m-arm-linux-gnueabihf.so,sha256=-GdHY3Dc24feMuDycFK77PDP_KXkjby_XOBkLVqlvbQ,449092 +lxml/html/clean.py,sha256=LjnNRaN2xyc_m7Dd3XrDv9b_Anzv84pBUQQDUDsCK3U,28249 +lxml/html/defs.py,sha256=ZzOp2TmY9f_ein9GIcDPyN8-f5HVptzSj56umimWub4,4236 +lxml/html/diff.cpython-37m-arm-linux-gnueabihf.so,sha256=77sEhzVktv6YSQTWNXCPe4q8KLHRmt0pXAnce70MwAU,586556 +lxml/html/diff.py,sha256=_juYjb3u9ZIZTyC2_Jl0zpzmIJccFQgr9fWTK4YpO3E,30553 +lxml/html/formfill.py,sha256=9lnv7BnrQS0HOBY8ToeP1408xMN1wnltpsY-0CTGBpQ,9689 +lxml/html/html5parser.py,sha256=dnyC4cqHxywjZSzk0mu2L7THTZjxhg4yF4pncjusa_w,8634 +lxml/html/soupparser.py,sha256=tfdraMayPbMBCd2kGxUoTvNkhKUclfP3LmV9R85WKI4,10203 +lxml/html/usedoctest.py,sha256=tPlmVz4KK1GRKV5DJLrdVECeqsT9PlDzSqqTodVi5s0,249 +lxml/includes/__init__.pxd,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +lxml/includes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +lxml/includes/__pycache__/__init__.cpython-37.pyc,, +lxml/includes/c14n.pxd,sha256=pGf910mVH9IdBb7r_aE-J59axIQcqFH4Sx_Tm0PA1m0,1123 +lxml/includes/config.pxd,sha256=H6Mrl8It21hzRI2hzMId9W48QqkYYkoLT4dniLNmdTw,96 +lxml/includes/dtdvalid.pxd,sha256=Rf2vRBbM4O1AOiIsUk_5M7pV3Dz309sS7Ccd2zGFHT0,671 +lxml/includes/etree_defs.h,sha256=3EV64z9DyzIZG_21pSkzAI0F0bs_Zd7GQWbLC8H-8lI,15671 +lxml/includes/etreepublic.pxd,sha256=3cdjIVlfkeZWYUav4y_T2uHwAo8yUCTlCvNLEvsZ_aI,10122 +lxml/includes/htmlparser.pxd,sha256=Va2qbs5zVokERn57HbDY__CiBQOoCS4uI9wEfCnT6zk,2868 +lxml/includes/lxml-version.h,sha256=eiP5zGtOCiw2fc3tjHNZR2Z_7TPJWwtziHVwuMTK858,71 +lxml/includes/relaxng.pxd,sha256=12yapjqDZLF_HTlcuSXSoQpPGK1NU7fj7gzS1EF8kZw,2669 +lxml/includes/schematron.pxd,sha256=5_PUpLHTzzYZ_d-8d2OjKLdwtLIdOm7C20HFUAX8hD4,1640 +lxml/includes/tree.pxd,sha256=dtnXNbEfxV3-5kOwWYkYoCE8HT5zvFVNdKFaIBuNXBc,20091 +lxml/includes/uri.pxd,sha256=5wPtpGU1JtdmpZMTzR8EswazihP3dxkns6Fgo9NWOt8,139 +lxml/includes/xinclude.pxd,sha256=onXD71LVdAbXjUj82_SDtSixNsNh8xbu6Nd9x0V3bmM,852 +lxml/includes/xmlerror.pxd,sha256=JDY_9OKoW5nue7wFe1xft0vk1kmAzo6nVC5DmhKXWI0,58004 +lxml/includes/xmlparser.pxd,sha256=X6ab9_HX8gKoQVgdLy9tdsFEdYfayihV5dDhQ9LgGmA,10869 +lxml/includes/xmlschema.pxd,sha256=yYQFrIKAQ_feenENV24X2AZyBIYGBltRDm9qB7CYMww,1696 +lxml/includes/xpath.pxd,sha256=tKYAcwpbSRq8qrsZ2ISVYvEaLnCV9GadNC5o_f8Ua_g,5794 +lxml/includes/xslt.pxd,sha256=qBU-0dLhIMQFv58I4q1XkBq9QJpJzKEAK9qBFPXBj_g,8341 +lxml/isoschematron/__init__.py,sha256=NUoI0bb87VB2XePzFcMtwUasrUAQACfb3Z9dPaMz6Fs,12399 +lxml/isoschematron/__pycache__/__init__.cpython-37.pyc,, +lxml/isoschematron/resources/rng/iso-schematron.rng,sha256=VsWxPyi3iViJDDbjJJw0wWkEHkLrz9zoCA8zJLor9N4,18337 +lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl,sha256=ObebsB8Wt-d3uIA_U5NU85TpnQ3PxPX38TdOAqosMac,3172 +lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl,sha256=QweRrIIM-zFcgg98GXA2CaWfIbgVE0XKEeYSfvv67A0,4563 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_abstract_expand.xsl,sha256=xSZ_Ekq_I-62ZpiE5AqYYHwFW_qh855zt9V4_s7rbkY,11703 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_dsdl_include.xsl,sha256=x42QJ-dxQ1waPzydsCoQnp2Xj15y53nW43O7BuoDRHk,39957 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_message.xsl,sha256=Tr9BnO6pzjVWwhqJfm10UlvAy95EgfSCz2iMlrVGT6Q,2015 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_skeleton_for_xslt1.xsl,sha256=ue8q_88X4e_jsJizo31GRNBxNhdxkEE9fY20oq0Iqwk,71764 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_svrl_for_xslt1.xsl,sha256=BBAdsVSi5zAzeGepuN6gS1saQINDqITXKplmmj4dTWg,20382 +lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt,sha256=OGLiFswuLJEW5EPYKOeoauuCJFEtVa6jyzBE1OcJI98,3310 +lxml/iterparse.pxi,sha256=uYVCe5hRTf1MP6MdFD4nwvC_LhHXt4CaXkfigJMdHEU,16607 +lxml/lxml.etree.h,sha256=zH_dnQObaEbqPbLlrSjzkQU_f84P7NuBuCll5Psqads,8575 +lxml/lxml.etree_api.h,sha256=kkRNu4Gut2eFWdRGW2SEm_-1eKZERFGYlNNaHIyQYTc,17856 +lxml/nsclasses.pxi,sha256=84Y3KIXCUQNl64e5Cg0Bcqaq2jzCB8Mmndn07oY3osQ,9145 +lxml/objectify.cpython-37m-arm-linux-gnueabihf.so,sha256=VKr7Lm9sPFK_ymdSwOoppq1rvSs_1vcIDO2vI44WhVw,770868 +lxml/objectify.pyx,sha256=B8qHvDa2VWlU4Z9K3vaCCewjfZpvFNNqKH4E3fuP10Y,77053 +lxml/objectpath.pxi,sha256=32MJBiv1lOYCZpom_2oAW27yNauWrG7ym7_5SJEPk9U,11479 +lxml/parser.pxi,sha256=Nhjp3bkJcDav2cu4eEW-4SlGnnRQyiEbSh-La43vOx4,78247 +lxml/parsertarget.pxi,sha256=THBYdmmRYCoj68BEv-BMXR3_NI8ME9OWVJBdypAhuQY,6859 +lxml/proxy.pxi,sha256=Tna5v8R1eJ50mJbbBHHFEUr2ndiQo8eV1pzsYzXhj-c,23562 +lxml/public-api.pxi,sha256=LYxBK_CXxI7NLzzSCXQaNqRjpUhWuD1o4fK-W_NxVvQ,6660 +lxml/pyclasslookup.py,sha256=gLD1HM2HtITYYiGzjEOewSwbB7XkVx_NZv_quCt79Oc,92 +lxml/readonlytree.pxi,sha256=jIvwD-ctSm7WLK5yAPlev_xGddpCouqi-OpinOIP0RM,19048 +lxml/relaxng.pxi,sha256=xQWG3HsUEzTQIis9MUKDeOq25jOJJm3X1CgOWkQfEZ4,6085 +lxml/sax.cpython-37m-arm-linux-gnueabihf.so,sha256=sEOG3aaSKcFmlo9zL49fCCph1bBoZGNOgIG7k1TFgTQ,297708 +lxml/sax.py,sha256=xcs8RDKFWnqCbZpYdDuJPLIUTbThrCYnX9arDhxlgOY,9396 +lxml/saxparser.pxi,sha256=0R_0Pi0F9Y_1IWuJ_1AhaMp_I4kkubsovk1bt1RSRYc,32542 +lxml/schematron.pxi,sha256=6ZvkG5fDcBLYEdwSaXplwcgbp8eiBexEo6UZ6Tl-sug,5782 +lxml/serializer.pxi,sha256=Y0k1Knswc5bNkd7Qv094K5bfD_QyG-IYyWbhi6xRYqY,67999 +lxml/usedoctest.py,sha256=qRgZKQVcAZcl-zN0AIXVJnOsETUXz2nPXkxuzs1lGgk,230 +lxml/xinclude.pxi,sha256=LPL_U0dx-qLP2slshTaOkIObeI8q35BsTU-eViuNn9A,2460 +lxml/xmlerror.pxi,sha256=v0ky0Gp9dnwjoMcP9wZ3ukuyjDzRHi2huwdFC3v9sx4,49531 +lxml/xmlid.pxi,sha256=v7fXygmofM83LHmM7aZMELNkqIBvIRLc35gABWICfAE,6064 +lxml/xmlschema.pxi,sha256=FmDRpaEJXNmNV57nWnZlK_xKyqZt2rz2OLs3PO4iKhI,8079 +lxml/xpath.pxi,sha256=4-Su_FRyrBuj0GUcneqJcuFX8O0cjTlJqrztZBazgoY,19571 +lxml/xslt.pxi,sha256=-vxp7JNgRRLsupTDcZt4JIvIp1xpGPYYECv0BbR3BOg,36694 +lxml/xsltext.pxi,sha256=UJbJF6ZZrbgbBWDgDMUh5MpbNhEMEZ8kWqea_TLfZzA,11085 diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/WHEEL b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/WHEEL new file mode 100644 index 0000000..c3ee178 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: false +Tag: cp37-cp37m-linux_armv7l + diff --git a/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/top_level.txt b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/top_level.txt new file mode 100644 index 0000000..ab90481 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml-4.9.3.dist-info/top_level.txt @@ -0,0 +1 @@ +lxml diff --git a/.venv/lib/python3.7/site-packages/lxml/ElementInclude.py b/.venv/lib/python3.7/site-packages/lxml/ElementInclude.py new file mode 100644 index 0000000..2188433 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/ElementInclude.py @@ -0,0 +1,244 @@ +# +# ElementTree +# $Id: ElementInclude.py 1862 2004-06-18 07:31:02Z Fredrik $ +# +# limited xinclude support for element trees +# +# history: +# 2003-08-15 fl created +# 2003-11-14 fl fixed default loader +# +# Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2004 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + +""" +Limited XInclude support for the ElementTree package. + +While lxml.etree has full support for XInclude (see +`etree.ElementTree.xinclude()`), this module provides a simpler, pure +Python, ElementTree compatible implementation that supports a simple +form of custom URL resolvers. +""" + +from lxml import etree +try: + from urlparse import urljoin + from urllib2 import urlopen +except ImportError: + # Python 3 + from urllib.parse import urljoin + from urllib.request import urlopen + +XINCLUDE = "{http://www.w3.org/2001/XInclude}" + +XINCLUDE_INCLUDE = XINCLUDE + "include" +XINCLUDE_FALLBACK = XINCLUDE + "fallback" +XINCLUDE_ITER_TAG = XINCLUDE + "*" + +# For security reasons, the inclusion depth is limited to this read-only value by default. +DEFAULT_MAX_INCLUSION_DEPTH = 6 + + +## +# Fatal include error. + +class FatalIncludeError(etree.LxmlSyntaxError): + pass + + +class LimitedRecursiveIncludeError(FatalIncludeError): + pass + + +## +# ET compatible default loader. +# This loader reads an included resource from disk. +# +# @param href Resource reference. +# @param parse Parse mode. Either "xml" or "text". +# @param encoding Optional text encoding. +# @return The expanded resource. If the parse mode is "xml", this +# is an ElementTree instance. If the parse mode is "text", this +# is a Unicode string. If the loader fails, it can return None +# or raise an IOError exception. +# @throws IOError If the loader fails to load the resource. + +def default_loader(href, parse, encoding=None): + file = open(href, 'rb') + if parse == "xml": + data = etree.parse(file).getroot() + else: + data = file.read() + if not encoding: + encoding = 'utf-8' + data = data.decode(encoding) + file.close() + return data + + +## +# Default loader used by lxml.etree - handles custom resolvers properly +# + +def _lxml_default_loader(href, parse, encoding=None, parser=None): + if parse == "xml": + data = etree.parse(href, parser).getroot() + else: + if "://" in href: + f = urlopen(href) + else: + f = open(href, 'rb') + data = f.read() + f.close() + if not encoding: + encoding = 'utf-8' + data = data.decode(encoding) + return data + + +## +# Wrapper for ET compatibility - drops the parser + +def _wrap_et_loader(loader): + def load(href, parse, encoding=None, parser=None): + return loader(href, parse, encoding) + return load + + +## +# Expand XInclude directives. +# +# @param elem Root element. +# @param loader Optional resource loader. If omitted, it defaults +# to {@link default_loader}. If given, it should be a callable +# that implements the same interface as default_loader. +# @param base_url The base URL of the original file, to resolve +# relative include file references. +# @param max_depth The maximum number of recursive inclusions. +# Limited to reduce the risk of malicious content explosion. +# Pass None to disable the limitation. +# @throws LimitedRecursiveIncludeError If the {@link max_depth} was exceeded. +# @throws FatalIncludeError If the function fails to include a given +# resource, or if the tree contains malformed XInclude elements. +# @throws IOError If the function fails to load a given resource. +# @returns the node or its replacement if it was an XInclude node + +def include(elem, loader=None, base_url=None, + max_depth=DEFAULT_MAX_INCLUSION_DEPTH): + if max_depth is None: + max_depth = -1 + elif max_depth < 0: + raise ValueError("expected non-negative depth or None for 'max_depth', got %r" % max_depth) + + if base_url is None: + if hasattr(elem, 'getroot'): + tree = elem + elem = elem.getroot() + else: + tree = elem.getroottree() + if hasattr(tree, 'docinfo'): + base_url = tree.docinfo.URL + elif hasattr(elem, 'getroot'): + elem = elem.getroot() + _include(elem, loader, base_url, max_depth) + + +def _include(elem, loader=None, base_url=None, + max_depth=DEFAULT_MAX_INCLUSION_DEPTH, _parent_hrefs=None): + if loader is not None: + load_include = _wrap_et_loader(loader) + else: + load_include = _lxml_default_loader + + if _parent_hrefs is None: + _parent_hrefs = set() + + parser = elem.getroottree().parser + + include_elements = list( + elem.iter(XINCLUDE_ITER_TAG)) + + for e in include_elements: + if e.tag == XINCLUDE_INCLUDE: + # process xinclude directive + href = urljoin(base_url, e.get("href")) + parse = e.get("parse", "xml") + parent = e.getparent() + if parse == "xml": + if href in _parent_hrefs: + raise FatalIncludeError( + "recursive include of %r detected" % href + ) + if max_depth == 0: + raise LimitedRecursiveIncludeError( + "maximum xinclude depth reached when including file %s" % href) + node = load_include(href, parse, parser=parser) + if node is None: + raise FatalIncludeError( + "cannot load %r as %r" % (href, parse) + ) + node = _include(node, loader, href, max_depth - 1, {href} | _parent_hrefs) + if e.tail: + node.tail = (node.tail or "") + e.tail + if parent is None: + return node # replaced the root node! + parent.replace(e, node) + elif parse == "text": + text = load_include(href, parse, encoding=e.get("encoding")) + if text is None: + raise FatalIncludeError( + "cannot load %r as %r" % (href, parse) + ) + predecessor = e.getprevious() + if predecessor is not None: + predecessor.tail = (predecessor.tail or "") + text + elif parent is None: + return text # replaced the root node! + else: + parent.text = (parent.text or "") + text + (e.tail or "") + parent.remove(e) + else: + raise FatalIncludeError( + "unknown parse type in xi:include tag (%r)" % parse + ) + elif e.tag == XINCLUDE_FALLBACK: + parent = e.getparent() + if parent is not None and parent.tag != XINCLUDE_INCLUDE: + raise FatalIncludeError( + "xi:fallback tag must be child of xi:include (%r)" % e.tag + ) + else: + raise FatalIncludeError( + "Invalid element found in XInclude namespace (%r)" % e.tag + ) + return elem diff --git a/.venv/lib/python3.7/site-packages/lxml/__init__.py b/.venv/lib/python3.7/site-packages/lxml/__init__.py new file mode 100644 index 0000000..42400a0 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/__init__.py @@ -0,0 +1,23 @@ +# this is a package + +__version__ = "4.9.3" + + +def get_include(): + """ + Returns a list of header include paths (for lxml itself, libxml2 + and libxslt) needed to compile C code against lxml if it was built + with statically linked libraries. + """ + import os + lxml_path = __path__[0] + include_path = os.path.join(lxml_path, 'includes') + includes = [include_path, lxml_path] + + for name in os.listdir(include_path): + path = os.path.join(include_path, name) + if os.path.isdir(path): + includes.append(path) + + return includes + diff --git a/.venv/lib/python3.7/site-packages/lxml/__pycache__/ElementInclude.cpython-37.pyc b/.venv/lib/python3.7/site-packages/lxml/__pycache__/ElementInclude.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4499a3636b409138fca8026cf2b62e379975b47e GIT binary patch literal 3767 zcma)9%WoUU8J~TSTrMA?9+n-)X*WR(o2e|hPE!;~VAKye5u!4IAGJ%gU9UJpiPCa+ zJ-d`-bqExZi}unY#~gZ)dMH|;haUSE6g}s-hhBQ}zfcrtf8Q)A%Q|(5{dOMT%zWQ( zz87yd8ZN_g^}(Nb@-}1tqR#Yj(D)(V^q(M{bs0Cf85%>gYZ~nNCG@P&8rogkpcy+X z4a?oK!5*_{$!4Omk5~b&$Dg~-wM8Ud>wonyxMJk z!nn(8FBq>0b9?5{>b5Xa=M9WBL<{{{eu2;M)(fLM$KT+yd=9O7KF=3kugW(_(+7mR`0c zywy+)MU*|1LU>8g+X*(svg_V%0#=|=?7uB0q}C; zy_aQd-lG$y53ZrGx;h$ybq!da$qn3*na|z}vLKw?&8n2K?6j@i@%<MMGC6BGc`mEi z;4{3b3E~*K|9?wtFjpyOP^b<{HQH2VYFw{93HYLYHJ{ViU!m-p#H^-9T|!N0Q1Py0NmuJVmoEIlv#=$ z8sk#rW;Q^x09r|vj!GJw(gX@K?QmOzRGEN8;FLOY7H1q-uzlI0)&wF)gQNA83mBIq zlOzS?IU?tYEP}Ml@&dI98TkfCUeK?u0GR_gu1U~L zL6YCbOpknv9=bLXhwMdT%B^3sK49YJi|W`=2N z0id!DDSI-&Snj<1FCIyEbnubbPehM0Q4~klBC(11y(>H}l5ERED(b|M&^hVKFxZDB zVED?Cw;5;NWvQ(#ukg4xi25;H)%|f0j)V@Ec?Fp%$g&AjZQ`<&v*f!tIJXe|5l|P+u!3&$uSv>u?$13lTnh#>aVLkw?~}x zP%NW*L*K|E%mPl!cB*m?QOwY;X=iXyU`zM(Ze|`9=mYa@dtA;+K(?G!j)}MOm9hVg zs@!E?89)2S*ip{5lT~-juMGM3%vGjxj%wThr#Y_bw#g9^#xB}*IDAdH+|u0dsH(CN z9=^^R+*Z|z9ay}CVDgu&$;&5WC2+c`%qzdO#&uQKGJbTsGWtgCu~ zsp=LiT&3v&yq{(!04(X4V*{TTIE^asdU z({lbz73Y&)^<#rKAVotpCM&yV<$#`Z(6gzU;HYBnU#cdZpX}n~2F`8zt!U}wTSW#_O?Vc*#LRTqqO8*P7z=ziXANUf+&J_Q8=Q#QQlpaFUeJN1{Vs(i8c7(!23(>7XCKM_nO=Ec`&uTUP zii6WF5Q<{1X;UmSUDHG~YvOGgbwoBww5E=0phi>on&w4(=XAttf-c}Sk%)+!+P3*E ztfzfwheevROjI@cROD1jdhPRh#rF}&QO??w^NV`RK?p7?1bq)wj)#Md8@j;AYimRL z!%{^1dNH-Ex%1|vC&jaoNVBdpy;u2t=qEoS@;#95n|D|5-FmeC(Erh`C%(3c2Wy{q z{JX1PJp8mfvkpNXJjY*(eSOHOd#7lxt*o#&itSpRQ^4v(q0_bVaZ#$@d>?En-M0-W g0Ep27Om);S1U7z_U7oXBv+k@r?_98r`n+xY4^_ILa{vGU literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/lxml/__pycache__/__init__.cpython-37.pyc b/.venv/lib/python3.7/site-packages/lxml/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b82859b11ed0b263460e9b024ef513e85749b0a3 GIT binary patch literal 657 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 M)edCPXCP((0IkV0*8l(j literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/lxml/__pycache__/sax.cpython-37.pyc b/.venv/lib/python3.7/site-packages/lxml/__pycache__/sax.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bcfd24223076179eaf9cb724c1bd0959a229b8e6 GIT binary patch literal 8034 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 HRHOd`sse}1 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/lxml/__pycache__/usedoctest.cpython-37.pyc b/.venv/lib/python3.7/site-packages/lxml/__pycache__/usedoctest.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d74c37a9613b0544a81ba318c2e148cb476b943e GIT binary patch literal 388 zcmY+9&q~BF5XO_Vt83Wx83sJ{uq|E}DIy-#%d#N7Wb0;>O47upMR%V;-$P%iS3&R< zJeh90hy(fZ=bQP>@NEV{Nda$2VNw}h@_G!s#(S;LG~D6D1$dj zi3}Gc8f{-M&ALWcgEq2J2=}If+v_V>8*THdaHfnoU%LDO=X1^hAWc&!v^7-?>P4%# zaVUGl-aUcRJcBf_F-;E}5*);_r!5d+wW}T8`(C)>-+pEi(f0Vi5z&lGRH7g8CK|Pe zLiiLR+OXqP%$H@88nqQg>FQjmb}U4hYZT&xR0rPP$mwVQKq_goq$vcg zvTc*LU~AJhr2$g9NFP+JzUnJlYsH9B`?UHZRIONb|Mc1riUx^VHP3#(-`sPPo69E6 z^Z9(=zrgg|J2PkI%sFSy%$%9I`{4BzH@I9bW&OETk>XokP^n_TqZQdoc~o|>3aCj) zo1xyW)2;l3;dxm)ASeD@I^9#9r99PcGX#|KUaWv`re^{8k?u!2!vNkHnC_7<2xx^u zJTq8nbB*R&yuRs=_MZ?Ge$Yv_ew|k z57^p6eol4p>&uS(AGguZ^5;14=Q#LrmLvTi9OZwaM4?ZAKB)?U*8qT~G< z$NTFJ{=MJPzRx(yzuWP?26b3}tgqD}->*8_`!g#uAoG9UQU5az{6E|H%lx-H%1b-) zzwDs@e22W>?I`aeNB&I?{_JtQ&vew^<)DARLw>(^;M>qu0PVThAY_Pp0Y??y-Y zI~?t6a^T7a@?LVJf5q|sCr9~DJNQ-QX#cw%@0%U@Z*Ziqaq#C}M}05a7)JSj z#Fozf_KJhvLR&iX-{~m-2}k>PAdmIO{3op!K)%m)@N&Sn?QU87ifBx*iuXV^T>3A=8 z=_k$;Y(f6a5?Kj_4_@jHO$-#g0tgoEA-9Q0n`$p0-z`F;of z4{Y^O-wrz7FLB7nh9%2Zv|Luxw6y*% z#$Bnx4_x2WR6W10`8L#qx3VRRo2zfDYiY*wf@Mn#8ds zi1OvO6-)1|1MZ4Do11DD6XDjnrPa6AG&D3W#!Dq4>#nO=e2lWWLuWs>*rsYfStDA$G zknj4I#ntmxENfn}v<^*aw4vV6R7W~(85Y(wEnBkeZWeZ9-7?g+tQIl=`$6U6`g^MH zUQyFj3lyv6H#aU>W_!J%sd4EIjZI5y*jVxnMb|}}mozTBwWfJ-ecf_RB{@0VN@<1A zdP75FO|#Wx(giB&nrfOGo33wJVrThqEjKNVHbOUM*Vf+JSi1sxFhbmDF;q07T_Qh- z6HHtRBG_1o1S1)_a7lB$#V3*AP0MQQTG%2G^uhb;n(k_7yx+=V(ce&4)3mUz2Hd}E zxn#Yijy%u|CofRxaD^8C$gtr^ty)4FikM$_?~1x*i|eW@pzJIXWl%oXlN7VDWp#H| z-?U6KhRv&HanjC8t>N>VYnto8L<|3ei=i7$brj)sHOuRScwv;hSrpjiepk&Bs?r>4 z`)zgiU%xck`~cnsqr7H$JtZrzsE$nuLn*Bu0UTEOKy%%4O{Cf8*~@C@vquhN-n1N@ zWpP8zasxgtt?s@Af)$=|=W7QFz3O4uI7o+(I;! zSc<<9Rsj0q=!3(og`~CVFb&hZVZLfz5~ZNY(sp7*zO;U~H8z8ghPtJ7%bK-1X{L}; zT|F{uZI<`yTb4E6zf7yia0ASC40l>#|4qwj14%ym+WZG#<(Gm_cB6IUoazP3Xglvg zF0sZ`E|Y+;8GjR~YKk`1;ospda8sESYu0QPEBv&RQ&D$cU4uywP_)$N!^jXFqMgI8 zE=Ap5)39RLs+#H%jcTJgVurxi+6UCqx}}SkMg@($wdxzqSUzGT z$qa3TEF>0CZ59kx>$i%=#(P$<0!@b5;Vd(w*|BVtu^CZ!2&{?ZE!S2;;-z1j;-Of{ zX%ud9S#(24pI5iEW(iEB#T4q)k~>#44>$4FI*w#zb;}nwIlAk-C5!7vMo)5g*su#B z?Eb@|kP68p7^54cpIc?lZ&(6rX|{Y=>1lTLNPDNL8BQe4J8gHG%~2aB0}2*JZnK}8 zBcZf-m}?l7mMjKar2mYJ<>i>2h?M6yH%7_a8X6T1DdWH)t4 zOLxQ)!4{a}HVH7FN9r!Cv*tgyVOnPPoe^X`uvjWYeXqn+C;C83^-?{Ns9v(XntEN` z(6Y3ly1Kf~GdiF%ZqJuYWt&YDr}FIXWPVjIMt3}e;&^8 z-}dnLtc~7f{?~}sa7_|G$X&AJ9C}#y$a;$Db&?Js=~=_+^h=+Qc&|X8K>BJK9~Zbs zV7I^{0tW;R3iK{E@q7aP0t*Dz3v3p+U*KVZy#kL2JSs3yYnEFmut;Euz*2z~0>c6$ z0&4{}3v3a%Uf>3ST>|3*_X^x6ut(q_fky=%6L?bKfIwAe((MtLD=<%Bk-(V(O9h4m zh6Pp%tQA-{Q?gOJS^~-z=Xg7frA1)cbV<+3d|E&AaJI@ zpumv8GJ%x>s|3~yY!J9oU`$}Uzz%`C1nw5NU*JK3hXwWuOb9$Ka8TeWf!@1CUj-Hj z3=o1nv>IS75im9)U*$9u?Rp@T9;Y zfoh4gLtw7JLV-mBO9Yk*tPmI$7!g=2uvuV>!1V$*2<#FV7r0m8K7l;~4+%Uf@R-1p z0tW=DkC^T72+S3jC$LE1Oo62WLjuDBD+SgHtQXiKaHYTv0^0?~1@02KPvCxmhXfuL zcuZhI;DEqEfu4KJ_IL&62`mseQ(#bFNMM=3N`X}Z>jgFlTq!Unuw7t>z+D1&3*0a8 zpuocddj%#09v3($@RUF=HXb?7`2-dS3r7YXbX*emduz(BK!7ZKPgaF@V7fki7MpTGuzdj$>% zEV|FkS1hna;C_Jv0*3^K?l<$t1nw8uBhcGork4wh3EUvCSKtwW{s$z#z)FFg0*?yx zeALY66__h9Phg?IB7wyMO9Yk)EEiZQuu5R9zOqq)JvDAM9eaa^2(hhpn9!$GFCkXi zM+ncwc@@I*lsZP3uT+BYQl*X)UZzwZ;g#68CWND7fbe}d*F|_O_U;I8#@Q^wTQDKP zdU|>V&Sw$ciuF0+2Qg0}oQw57VFc@W!n?8WM_8{^0pUmB3n07)XT=DYDpf?dOsScK za2Ny$qd3<_*o3`A!uymeC2UbDMEFsq$_Q5~RZjQ`r78#?#5p&@?MhV=wklOcxK61> zgr8I@LbySxTEa&_cf_sU0#}Wn5Sx~{gxDj^Bg9^40U`Ee1BBS?EF^>vqloZq&`k&@ zN01N)n2HH;u%Lu+8t5j(LADU#bkI%s7SK(I4qZWr&CxL7TR}JB1)!U-0CW?+O{oas z+d((s45jJ`12~^Xc%f2J!i$t@CVYodErf+itt5P>QZd4J;d~9@#Y(LwEK+I%;k%V; zC%i_-#6 zSE+8oe^9E2uoQYr_b@L|ZGa3kbT_$kPra1-QD*beyC1@chIn&{kCVX z?OEBLPYsUbAFw_5*`5=&=cBggUfc5_+jF<=dB5#>ukCra?Ky6H?zBC(+n(3ko@2J> z7Ta^w_FQj!j@X{7Y|mlabGhv~WP2{LJqK;iMYiXF?K#i(?6*C8ZO_W~eCiDw|838G zw&#TH`Kax=*Y=a}ue#r7PvJ=fcwBev%% z+jH3VTyA>~*`7;m&q3RBk?lEPd(N{x`)$u&+q1GgpZcwh|F-8o+jGM9eAM>bYkNLq zd+xS9@3%egwLR~)J;!a&ownz8+w*$cbIkVKVtbC-p6hMT5!-W>?Ky0FF1J00Y|kaO z=b-Jm$o3qtJ?Gh;{kCVX?OEBLPrYvAzwNot_MEUiAGJOA+MW;Dp1W<&`)$vA`Ha5- z*iv8bttl0bC!aoj`qh@2oyMfdri2QGQy4mP8fNV@8m89S_L;EPdw=f#*;&S#Hme*D$uC{;S{DyIV!lta0Tb2l$wvctBowB@;!*l z3vM;8JpG=e3U=7iTa9<<^bUixT6r)f>UZYDD1vfE=gS7pXUU`BPNN01xB~ICJ81Gn zsjbFNp&wJbXH{^Ut=={R{GEoWVZJA@&0slh@H-E5l19G!dN-y9FrFQL5AI5!5s7oL zk9C_{9Roaq(2cMQfmb-nkY06OmKvCS*(+;h7Ez8Mpgha42M(G z!J`;y4S7zNIP;%{`~l?e(QVtV+tw^?L%Z_9pY*v%-^li%ZL1~i z)ala)$V1Xge!f-We~WnXle{q70bK|_V$+Sa#(A2*k7zuLztEvK>Etg@pN9UJI_XAv zmj3jgKHYEe`3Ur)@-nwN31Zvv%s`$WdCyKGioQ<0IH|UPZ{hS=n#b*i^2gKcLoPKx zdD6cc^u?qfwGa2BPT&)FU>w|mF>oV-J2(z5>l_3=NJYOJskcaQPmP0nYK(dZE;nf& z8V8s44rQo!zu+p@*t}9xGV>}XxSsKFQLhL1&i0lIu6G<_TO%k5O;C;8u)- z%X%v^)LSLE;c;-oW7HcE+{$rqE62d?d$-x%s&R0u#=zYxxQoWYT{H%6i{M7a!HtZ8 z8xq{wad64!THrhTkymi*$HA>1qu$;klUEJn;5Lkb+bOuwad4w!;6?s3n zw`CmMmN9S#E;ie{ava>1W8m%=+}Jp{lu-=$P8r1nxAhFTtr>931$X@!aMx$R^$YHX zGvIE>fP3^^Ca>DhfZLt{H!ipxXTa^qfLkxPooB%9%zzsd+^#d=c4fdl^-iUT}Ax0e5!>+_2#8IRoyV47hoMyY~#Zdo$oB3Qb<^I|J^%47j@m zcmEl1_h-P33hu!(;2z9?TOzpKXTa^wfU5+z=M1<#8E_B1!{pVWGvFS|fZHy(htGg} zI0J5#;P##Yw>JZBKyZ(o0ryA-+`fy<_8vV0?$Hdmdj4{Tw@F&3?g{c?MZCmyxi*Ac0yqtJmTAW^O_ufoD}>E{puFC>bcpi z)+1CP_z{lW*)UEa*v>=osD1@H(q5TMZ z-;1&lN)U!hP&Ps;6GAP*OoYL!(FTN8gbIXQgk#u4+J(@7P>e8CjPenx z5DF0J_u25r)2}uMW*FMfmNkx#U}|O`!5+c&jDzbL1NXS#ddI=_j)7Znp-HoE99-WR zxRrwI9|zYz2JQyI%^e3fcMRMf!Oa^7H*XBwq1iJGPiRx3;EE3ID}>+jW%j9pD_RZr ztky)}ime7T6#nI{MqGTxZ=g>FuQTyN4!n@ym5qT{D|odIyjsDl9|Nyb@YXx<)(hT- zG4Kux-W~_u9>Lo?2A-N@wy)QL*DH8O#=t8Uyg>)vpx~Vv1Fv52@~#{$hrBCIITT!( zSq@!-SL(nk6}-?Gc)fxbao|M+uXYSPPnpS=9{88(TekG2Cuq`n2s)BUUrGco?!b!+ z-mWq58U$~p18=3^#m2yk3tp82uS)P1je&PW@QNLH#e!Ed2A=nNlP`V;o?q~C$HG(O zqs`ZhagY5k3%+J=pf#hfIr>i1Mzy-fv8!17wN88U+Hbeudc@}&jeX6_an$bP=DN`X zpD)t#=xdIKzSc*-`!wvu49t=Jut+@l)G6$Tv?tQtbFoJeOQf^IIAfsNjXMy(_Z!$d z=-!m*4IECM#kQz=)ojN52)1y^5R`%m-SqSHZmmcW~SA zUPUR&#j%opYre344(AJ%*w^Zqj=h7aD%i?nRQYAV-3e)*<7wx_s1!o3z-JGn2S_tw^Yt#4m0#`p6vH-N*S@((UmbtUFMfB}Re z1Rp{!!l~c8RJ|)p9R=(~;2vp~il-0Vw$muaUMa_u?qxfT4e#hM+NX6GkAZ)B&lG$a zP_2gECkiIgPq|fp2kcKL@^v8}>_&PMd5wI7$oD(&KaTXgi#m*5=?-J}H#>|v?8RVj zFkQrbPXzMBuQnQafsIBkf)BxqQ0U)i1QHvKf^OsqZ#1~~h&Q0OBw22ZmXB= zW!vp-=6)-A!L~c=hJ2C>rCu+}e*)$2k$SI?dVPrRM7)z9mq@xF>FuNoczGD#c0nGj zZ@0U{C_pc{QhAtD1Utg_QXLi^=L2T zZ|R3u=*UC9WuyaXcHLNO?rnkp&JFLV*%>e_l^$u&#)E&t$jjg0BN@& z?fCnkCep4!nzLp>kVuyME#pD+1pk?-Tkx4V3&k@y?QnsW98Ononq_SU1G#i-|q(D?_6 zZ$SJ%Azt@e;O%#J7(bGS#q-m!d37SA9JrHu>hiLSN1T|7ed6|IV}*Cou+2L;2a@5%uL6sdqic)O!^1pF{l0*;oexmvbdMAFq{s$B^$S z(uX#1uDlz(s|PR3lRHQ8Fq1A8fHsSVYzyZxtcx_334IBa|4AEtGo;?*h;KuDRQNY+ zgTR9Z=zzt?X_CJW`5&;+*$f&<6W10CW{h5My-D84r`J57(OOr~4pCTs9x`Jmq7pDf0$Bp(C%URQdv#>`n75;KLbJ~n^gX=HFKES)-=f2pj zuE9d~I)w5t_OD-yKpX#=QZOW;GW9%6I`QnZMq(QH5H)WW`0^l z;>nYU!&yfBKOgIkxO?g(l@kR{bO!fCM$T#e#~bYXiFD2+)&FmxyAtK+hBl@q2Th*< z#%K6SFct-HMl=k4Ks%-&pDTEM%B|W`TCcjHLy2R@U4hq8{~c-iJ%WMjQfH}oY4~Oy zgMXv{T%7;pc>$LSC*kMKe<#mbqHO4BDk}kel;QEeU{E(){x^)v)!Z}=%i`ACqBPIa zcE5e6*7t)rYv&0fKYTESpi?0~X*-0nNLxSJ=pQ%Q7`h%M|nRuo&a6&=kzan|4w7k9Xub)wr@W{|C1knDi8cSeZe;4l$4p5 z)n**XRyoD+Pp~cQE2LqCq{rQD#ut&!IHun&I`cWk0msUpC%W3=X)~Ti+DV+RJ9#a9 zJgPNC8T&7U{(z3+S(qD1UZvWM$B~z3T4DF(jO$us{o*#`15yvxs_>7s8Jn3e&~9{{ z!?V+?Q!20qZQGP67dn~GgM8~GUyGFwd6@V8lCKr*`Gl^s-KcsS%F^e9;nTy}-}P>s z7lusUD|wfEu=Uf+!SmcmF6z2HeGz2n2~?sTmFR!DfLoG&#AV@~It$&%c|+r_HF(a~ z8_2~OWa7?CyZp1^w^TW%uC7IU;n&k`T#J6C`k9Y;&KLaLAo1wK3#aFS-b0Ab#h#r@ zMbj@s#axP=4enNBHrtFoQZI4)5m$=1MWtq6 zQqT>yfqI|MJUIVdjC9i3T8Qx_7XkL>KEb~Xd>MqE1*C53>pDrJpVBAs8$1}-W+?4b zQdwAEqfF}X0Q>{QVc&=SORj$h&Vm2d9K&({@xZT9b~|vd6j<|PATrT2Usl z(4_eQp8ghTUwxu2 zQM=<|V{ciT@q0=80n%Q(?ctOcWw2k)eBxna-@Z2E*OLBir2pwtNJrWr()I)Qgrt2P zX|3=f9NhV^)|o#(U#9Cg*xF|NLh^hGdEWQAvXnP|b1DaAH1G5n-6;RZlKy$5pL@{6 z+w+9S=-Jg~{JW$*gS3}EKZ1LFhsQVs-0w*GPNaWF>MTIoVc>R4S|`#DoC{nPN>z4w zj9%bAAT_+C@yuU2VBWrw7#K-%%*ZALNT>7!2o4|f6bE6<`$MctAQohtt-$U5}i zokr-bv`wbHr5$1aeYfPRL3!}$_s>FJS1_JF4qAB+=D7qVh|_@ieZ}_Oox}KmhJ=gj1ey+;ukk@E7^nfA|{nyaeqD?Jll1=Xk}oW#f78 z#XF6?lhM!720b5uENA=Gt8v8heZA}(VcbSr-@Ny;9{Wbzo3Y1GY~nrIaCamBR2kal*dJnipQqhOybbm`1eu^+eD?-crG_MqI3IGW zoYt!$H^`N88-m>W&jSwh1fQV+-$vh?GW9^O6NdGm9QfISADgn(Xg-&9hEq5~0sPVT zpG^GGdow=PFM6Y;qZc;#^G$!=Ceb~flP)e^2q3a6$ znfAzY)i%SIyUjRH=)`7S&iYx~G!5n0$5ejO!1==}%;(nVyl=3dp}z(vNKYB)DYMbj zKE%M^b(bpHEoEUrzv>|gZUjtjU z)i|oIOZGl_80-0egl+t=wpIQGwB-vh4s4UX?6&E&Rk@z6#&ZRW30X zoMotkehiLNtcNyh-?XiUPiV&P3Ftd^Bm3TMGH#8wHwo;!6Mx<~bOy$tGY@oq(ncrW zN#`>*IlK$ejL?oyf)K=lrtCtu3ie@D;=vg{ydOutTD(^<4oI~#+$xOtL%+g) z_}g&?5FzfunLmX6Z^L^4=jf29xd8Y;=Ka(`tZa`Xgf75YIvCn2gg9m^`w;?o<{o?% zo)5kiX9W>X=Aj&f281GnIPf~LSMLWb0PG92RRC}%;4a|o#{PZ? zK_PU)XjUO~OhNewC;ccNp$x%;&~+Zt5xfXJ=i(e8{2=9k-N?KD9Pk6M2r!Pkoj%Y3 zICS=iPlWyu@|rsEE}IT~*`;z;24{@Yfnw-DjpzV=i)cbRa1dosSEpY#cApAm&;jw>CDeU**4Xnq=KYw^^9z0c=*+w=tejyKdPaD0MCf^N3|`ctj^#oRK4Ft{ zbR2q^ccIX8aDw#g0X=(c^dy9yPmDoNJ?i+N(9;BZj*mkR^Ij?RJT^gkiWkf(>&Icq7(*a4tG(gfY1&}nH2gtHs$FonKe~ag{*yI+3vdnC`P%9J^%&Q4 zalSAY=L|V^Wd*k4I}h{HZ$JGWSK!yD`xE{6O;gNIW&)SrxS-8rKKkbac;_?o<^ew| zNZk1vm*+=&&cYl5VGqja#T=moWt7;<@XtxG%-K`Sx$KiORwcgS-`~i6T za9WbzFq!#R;I;@Zzg0p1g%9U#A$!O*oX&y{Vs@9qvuanNPR8*JZ=swqW*Yat>}f^g zr1{55%N-{zPttg{nDu1`akdI)h$(+p_uLe}Nrunx-MnE|EWvvPJnIZ!)B)}x!58;U z@bJ6%b`AET)U&SOsuXVN;0&>P+3l}LnEJ3Lu__7N#1p{1BMBe<%iNb@KAai-F88qD zqjzOQ|9Yw$guR_!}PALtAFp?}aZ z{8AuDwi&NOFSUILZ8^a`q5aTm+6UHA{#Vuk-|BE3r|;z_PWl^O@v#Q1TXyA>Y5oel|;)_1f;vO&6kU@?ZP21DmxiHg#wf&IMrK z6FfKd>N?1KUYdKQlr?paw%H^0nmT2DGl*%Fv)7ODz`x~0ALLRZ^-?a>J>GRVlkN3M zKY|{-$rk=KrK#OV(EZ z4nUs*kT?4|=PlO$))TMdtb*8p2rL)B9d+#ME;Ug)*~jd3&irqpv)M-He(Zvf&Ist- z)s6EgXdCb2kf&LJt`k|fhXWo@!+7h)SesuNXvg=$V&MBcZKG5OydJiX`X13}9^%_< zS>TD&Mp91L`%6+*S&)?qY@Uv`PlbG@8`$sR{LtdDJJ>bM$haSY;Kv`fw^G0%5d2Ga6y1|93Be8xplerc%PXx92!iF04F z=E^YdDnY-ZJv*CaWBzqN$_qh%Jg`rkFO+aE6n5$tub>|I0|&5IUm9vNUKKr~e!0;W z`<#?I7CM%t^6(?tv{NC_9JSZASLms*|<0e&5I@NTHz--@niw!mR^(<_O}^jsz=YYsZ-`W zm}m7mjIv;lp+E!IDd7P3d%_xzb^5>;*2B1LysK`!2Umml6((({59T*#63WE91#{t% z?+sdUVf0bXi(L2~1I{H(`!;wNQdr}nPTha8*0sjZAE52zDeX4S^5t+00Bw++`EAT3 z($h%ai%nL`_IER>JRQ+ zs90*Zf{!&8PZq(iN3Fvq#fzjSjxJvHp(GSdXT?o z3g;x`*T}b29{?`TMLKDn3R*jX)0qLM0XVqt*xvwsU5Pwd_+~B33)cHz9(@IX9?#flZdDMsF#04epXuXS$RO`oAg}+6 z(9MO(A3O5m+r0ghO%QZb);|C~@5eIkQi=OF#C0JbZ327?!?bM|+EOed7*Cpa%I7A( zhC0|+{{*}+bXLn1bbcA}u`u^e7bf@VJPULl`mM}73zMsX^Es4P@v^DY6(Anlg=*yi zm)>Wr1*Co#B9uZF)N|T0y`I2&#N*#=6x|CMp+24?4uW1+0RF;2x50CqT<5ZXmt!8r zHj>WEkVo5q5Z^1)ILnnoU8QdQdms1$S&ry^t6r1pZv=DSIsENxew$X?O7L0*zYU#( zY=`H7ZFrAk$B=zx^uDpB+fHAw-p`hDp{qEGZOZ5@_8s(>Um=cjZLWFSC?n8Kzgn^8 zqxo&wpObEDd_W)g1K&g6HlQn7-kX3&zfLO-Vl4WJ`7Kx4Wby;!(HFG82R5P_cp>nO zdQ=i?H;N-%Gj=9RqsWVTi(&Ih5K0m7Qwllc=`Z<>+CVt<9`X@<9^u_;t>g5ql!od5 z2&ao9tww3I)hLPJ>}ISLXYz@|@oXGBgY#UbO&aYdH+ekTPflLKe&DV?WHMZ4n?XO7 zC69sGBlq;}-*`R({`3eRe+YeL+h&7r=p+5b5wtsoc1L3@tMAi)Io)rK%~v6h7j0zw z%yV(z6?BmG+rLi$L!4u+b2H`h!SBLv3cyE{vxwubA9rdoPWlymG~nxG$jYz6FY(No zd&=qrZ9r~l71CB~|Eqocp|059aTdIv`WFwPtdQwr?0f@#PUaz=3ATZ>(Qj<0typOD zfi}o#n6?toRy-DM4qAqOJ3>nmGMETIS5AXs zUo%s_Jjqvve3pM8Q@#SpcQx`^zJg5oiX@nQMYP zV?US(&)5$p!ZXTXB0QrECer^X18c7!Q$HxQ^@A>l4B{e#AY_0w{ICpmK?d=^l?-hC zBx65t$f)SoBQokdF)eY2h87c$W$iQS~+gi$Ge)}GI%!)d*+z;{2cM5c^BrS zyHKt>*fG4W%|p4|C$N5-!oq*fhL1HzP6W7K%suPv`0zV$4fq_&cnv(TaG$o}ehawt zdC`~T^=~uSHu~HOQ4ZV1_Wd*PL1X`(!={gB!{=P82kQ*NE`%d{aNe-HU9T^)A)k{` z%yGES8Uk;zuAm>w_a-@Rc~Mpq=lQ`-+kADsUUPsvJqP7{(}Q&0;jz}3ESK?K)DPKWeLEW8 zoEwkE(fd%~Ng#l4vDofR-T``fPtfx{@r8pIn7<|iXro7whno`bGjOJY@z5pwlLP+u ztAO|d12OH>qF;yn;-2wXb75=l@nw`Tkul*j$TtyN|2XnZWUhsu4a>3imNShB0T~k> zM81iP9rq&NMCNXbk#8b%w*|<@_0m}UD;D~0M85KI@|8*k8B?g%6Lm!|7jRU$(Druva|l{Tq(=e|5b7v*R7UjZydyIo?0! zcwg#xuXeo8b-d5PyS3K(4BD0(B;V$z*~e)IK5^XicV7luz;~|Eo<2T;Qy_f`e3SL^ z8u)tfI~wpi(#J^~xsW`AEiO>{n_$`xY}Hu^{3_T-rgKf1u^h<2hqWg2(B54up0gm;s*#_O;;eRq^CT zmWTVpevBbpd%OIrwGR5>|K;!g&^Cd*96$WLtkD*~9%FHD82RcM2VY?}@}uAJ z98*5d2*LidkIhZe2kQxbQR^0cgC5Kk=!bM=O-tkZfjQZGSr_hcA)e>lFlOg?0$ z)V`qr^%VXg_$@u5)~Q_k*lD3{@!(z>+v!33F2Xy%0f4-aqlt&_6z3PfXX{ftFjv@t zvf5Ah@otUtpVjo>{0V3-u$||-27D@%vwXJ*%`aizz5~1dTY^l8jzp3?qK`y{D^&@bin7- zUnq3^0<`@E?<(*(zEc8PAP2oi1HNOvkWczZ&ojv5NBUO)pG%*9b)Y9p-_zi}aNaX6 zHTX2p`y=~;H-i0)Si9j5w;O)~ZUpng2zaS|PFS1JzvPFFamBI! z5O~a>FY5}NIrE{9(RKwWANboiKIg)A;J(~+_=R1*a2xio;)ut0JfP$H8!O?B@STgU z`_1_!zdy)%tK@tj~H{HyFUY8NDun}_dj@l546Ashj}pa5FdR-&nHOlkHE8LncsYYb)(OHhdL38 zr{Qze{G_eQ4Z@dftB++(Mp-9OpBFNi9KarxwCU^gg`zFo6JQ$Wd9+Pmk$B8i`*UB& zQl}uF`hSLxyBj`j$cASQRC_$x;=z18X3EGNK^x;cjKc5^<5tZh^V^zi8|f;;*qF=l zF}QuYw;gA;@NG|Di0|vB^A2n<%I8P0uSj1czx%m%I_HW0h|Zg$pUU(>VZI5zXX(DT zCdG9z=NW-mt5FnZ84n|Dn@%2><+P!kczR|SzFgEFLf|;fyN?wJVFc`F8s~y$;!s9= zv2X5y962_GqFaoC5c}-HH18q5lky6qY_zuuI7b6Ge`?detQhC>om&53BfiV_a4gA2 z+1Kz)8*pzXf6zAS4)w;;8R|1^FUX)=fe38_w24_9On1j1F_C-*w;WmNu7R`zWCi=H)UV? zl)3(x2}qt~g zvz9UT8?nD=${1%@Kvz7yhV6`Sj&Qr?K?iitd7g{=8tg|dZ` z&TfCr{jr^|G495*gTFqJq|Q(u_&4x@!(Yu(MHm>5pwW~|Iq=ATB<2wR9<+($lHO-+ zhYgCsHYeF9u?HH7a~^>22U3@D=YKYFEA_tW;JsV*+?4%|w!cDu*Jfc7zO9#Ivs(2z zc7A&ReK~YXTkg#_fSw5ZC^?B5u+IPv9ukKzZZ&7ijW<^ zc*A}Y3a6@2U$J7owP<@7d!>&UB~j!9ZfX143GQoF$-d^9eK&eOquV(8yWAKIU|UCj zlRNj*?6V8f{Km}Cy^k5#Q-Mub$gv=2aMfeF9kj8uwa5AG5LK1r+~ZoxD7g+YdIGj~ z0e?Rv=hUpn;CGszq#uE66mR#9snzHQZvTdaIVaoP=MJt*WT_8fEwTom{ylwwzi~qO zP>!zH`V{3m5c)xKaMfzWw`#wcQ+}qbOu5))MH|btsME%xFY7j$X`^|IVQ(&K{Yf;=!2M>E-j~@bmsPluXwi-kCt^sd8 zlsxt18sp1ocQ^FNDGT;bYb>zFKCYXxeE61^?oZ)#i1GoyLKsWQD^ECPD2zMg6~_Ja zkn3Umw#&oD;H-y@tAI-y=)Z`$wx4)t_B!+-&ebiw$L}^`TwtHJ>MKItQ%CW;zX;s> zKlWqH#Sn_S`OSLRXZSfw!tEIAu;1^;J~!q}+}}5Oi}~nq*&BEt1-xA#G8w(cezs1l zq^|~iAAN=bap;Ste50^Qq>XmQ+LO0vr5%9}C?EM@%et`68<{h3Z?O~YQhwYm18zO$ z&Yb6QoC)F{Z5;Wh%xHv-o1cDiDr}uU{t|st=YcM^fo*k9*^uCTaaRcEM!;{DLMS=*Gb^9)qc05o%F4HGSpd&I(-wYld>&AoyDlrC3SkRuJMw$;PJ11DZV!0 z?cJ!e{Y4Cl-6Q?NgMQ&f84CTvgMQ)t-?U%oejLI#UleQs^qXT+Rz%OebF!d+_PcDB zKOJMoo9?+;K5yv!|HwUzNr92Q5!#7EkO}*qo{PlMkI*)EJJ!WftcznijH1X6V=d&! zF_~)x+I_EHvpzcA*KV$fRq!FKhpS}G++&0w`$B{w1ZTesAP!@VZLPZ=xC_(47~{9g zH%HbX?)LP|DB~WHIIOK<7kR$P{%sQKdP&$^C*LgkhA~K=&!wM$_Yx_qOnVVN=qi1@ zpF+DVxn#;`?PJG~Zz6jUT*K+T7trR0FD^HNvx{MzxkcM88)Vx4(c?-)^Y?bK{iD}; zl{zi+xKNHXYtJAP{Uy@Qe?Y!c_>#urN2%nSiF^~;OW|4~I8J%iUX&mCCbH*(sWSBI z&3h4<;>`1^BV({R4;Xpp+RHvhckB1j=LNr@<3{_Zo%^c`yZiD#`_T=U!ZgZ{4b3e@ce{nouEZC}6>Z+NqDDr(N1x#x>H@5?^; z$-y7(8}Z>zB*yI|#x(PcEzaZO`>;v)NHET?#yWO^K98#+7~fC_@Ahz=j`iiUmXCw} zb@sUc;GO{czUg!KhM2dKXYgP4b#KAEXMXa0gJg134Xz#|C!@%4E58mm5q4TL*G;Zd~5s$E9HT8558ZEd!-ovsKbQ*&t>Ve zw$#mD%NK+ep9LQ$IibY9HqHoYNO$tfvjf3;^eC%{dBu zIek1M$Ns{54%~m@J|)JQe4a5S-JDyJpCwV8bA>IX@02#pv{!8g=YiVSN$B`pCGv%1 z349LlJHw_9pCevtV2|@nezTwI{yf@F&|lzOcf5i)`ZzbBZ<0?6XO>??dGHza2R@r+ z-WkAeRIyzvx8j^T*4}5eXQgXc=j<6KuxOKnH`9-Kj; zeik9#n_xef)W1LB)C(U+xvHxLgLcOG+1(5qdv_aT6df9h|cDxSRneFHr)sDMR&Zi(p z%B!97MOzhQ>Vb}U{X2|HhnSW~--~>u+Ma-q=v#KWaCWLc3wY0PF9_wVKsoe9e&-mz zr}3=0Z)e?gpnr8G{3z!AlT8VZsb2I$cX-Q*GJh}Tu8=eO6W6yM^v6rIKFv>GKt7}1 zau@C$bwiKUrbJnH5AyOX559E=S#VsL`3?AI16wc-nD0^acaDiyKz10v%sqP8CEkx> znQSNR9sP40Q?5aMUi1g76Z(#`z5XpH+W5^);Bw!DWnqq^-?=}+_g1u%>9kk-fV0mJ z`9&zdEhnryP#ckleA4sS2)^?V`m#lLiXxoPkN7!gSFc3=bNtwE15dR~AdAI9ht9Oe-i>oAXi5zMjABcN-TD{&q%mHicSBwx`(oj30{ac|F!eG&UygZiD=m8JD!=ppP_K&XWXJTu~oVSKGcKkk8VJA%H5 zzUzxVa-slzIjf!aVLRzf^Y`hBV7o);XYZrVU@k~Ml{+3!>N{h8%q@y}mv9yQN&J33 z@1ya%ZgX{Cq@TPDzhCeibzj?QtDm$QYHwW6#jN{%rmq}2YSWh@oQdID)6~Zio2=A7 zVvVQ{bEz%diwPqKV}mY!I& zU|p1tJ*)m&%o}Q_!5+k@_apcB9)hgc7xg|Nx1Nxt>RMa0ozr~eL z+1`&lq=~;P;emYhxDNYE`43{;cA*`d|CRZ_h4Oi)jBBE~$z{MR-@94=RwDVZ65lqa zjd=p`?}MGx<$$+LV;$7f#{ubY;Wx++P|spW4?b?QTc3pfu+KkkFptF#&a=vbsNW$w zGwjh0`24>&K7}I+nvqW_;)r>yo~#`n43HZK2U}{M{>TFA)Xb---*pfNCWTg zy@c|LW6&k~S7PyLA4l9S*e{-a;C_M2Pd&vNifaS;#!Tc-r(azTneI`Yx<1~K=UHja z`yS&RLyT?gcQ>(b<9;f61G)Bly7%gN*PP+LZO;8RqAW|ke*!&}%UZk}F2k}-PzueZx^?E?@?&-*S0%vaeCn6hu4?y=#=+Pz2S06&W7hr3gR5OC*ln%@ zXshr|S=EVk4)>h7-s6136+%D8e1qqPaE1qV2lv2nUX8zLg5OR`MKON!_XY8LJy;)L zu7PKa=SeqcC9gTAyI^DZJ5l_dHtHVvkl`=qxPy1D zQ916&oDgFX?Zvb-*P_;X^-4TvTCV~r<9d}o4bulOdcEpW<{Gr}W%HX_-Vpr>mFY`3 z7fo!&et1})+4F^0rLqIG6_&1Zof9_K!Fn7s*ZL}oJdt?%T3*<1_P?=aWS zT0bD`A;={jmNP5x!D`=*wqa}Zo-Xx(@>?ddXC2mDfHKMkEw!j~656BZH0U?RPjQY7 z^f8Y7J3`z@IE8UGr^J!>W#o14`{JC9u7hK}WnbxkOFW*XhM-hj_s6f>sn6Q*{E^$= zq0c7ZPDL^b-fg%Dx)tU=bcgnnKvpLfm8;5@T*wk~Jn%+e9`4fczc z9@CG+`R^Xg6*$kRMmb*S9c}H|)WN`J(6=aw`7gc+hPg#R^iO>Oc^2vUm8sXJtqn!D z8ZDTA(x1UGGjH`);{zzOA9AQdy<@c>bDHn6Y}#YC!{Wg)kzXbrp#SP~Tknu_TRcap z^W&Tq{6qPJ&;{OMv7fX0ILg}xS?hM7E}ohB`tMHn_bSr7De-02hraSSbv_(Ve+GHK z!#Fv+6-Sx79c9)deJAo+e5ViQ^Ta`4<=McW;C*tyJh!A}ggO=ad#%*@nA8dSb9e^K zjlA^Dk?-}S1M>#KNDW-#BXWxs0;2 zrKupkbEMBAu9|M1p~X5VxJBYt!vw=u6>OLH*z_>yQURP#RO{eBS&MlD=3pVykLZm6 zVh!a{*oVirj7-}zdcRuFondcB?9#}*n0AtDG@a(~yh$kV#aHl!uwsw!~d#_CFG{OpJxk6o-Bk}AM^a|rD z$5`B%nnHSg33EP&wNyU8E68zJb+5+Sfbnb4R@xw(H}d2AE&f$gm46M+lyZHCINLW} zociF$SaNDx*6=+8`qIjp&~Ko_^w}?m+)7fIm!Lk*1qq(--!`?--~-x;{Lsa|p%R;?b02_bAzk44 z)yT8Omz8)2*+h=F76YkNPEf^iBH2h|Ng=x&dJ5LpYT%W@Qn&r$PH2H zzLC#$B*!sV*oQcCAI}}RA@!EV#w5zZUcEW?oWp(%TUms%c~18z>}6JnzuUL{geP=; zBKL!h$z9j6uPngXj`$Q;u+{Cwvpa_8*cwbdaGoa;pQ3%@=vO29*k)iI2z?ywW8mIQ zRt7pk;2pkqG!=JKvi=2mK1#Zv1Fzuu(Vv*M2kU}oRV0zd_}5Rnyj9{KMm*R3g|LI% zPgB8OLnVG_a4c8^-6{tM=;z5rPzapss1Ux#ir+%w{^e^d2Rbl9d#j!=z&z_Qn)4l} z9bo;8fARxU6TI^PopHH>*G=WzAX}+R_^lzg3ws#4?{n^C-l_BJy7fFL`3CF7m_}Q~ zvml(q(JpX4Qykc86wl!phwsv1PBRy@_{5if8=ec`--jN+mSeofyauvP(m%fhI^KXRo9%i3g1ssel>4VW9>ofBS%x$ds&`n4?VtcR0dogV>bgvZ8z65Vs7; z_evJo>g7C-<+E>=qo2Cfx`Yatb{YwnC|6rT@2}f<%K4MV!F&$>rDrDxSL?Ii=pT>y z5a*Nu^PhClSGv{c!@3r7KVkVQ{nR;S&Wk6bZJ!kRu$`QDL?Iu}8z-a9^l^Mn^bfS= zw_~nkZyWg*L!8xC{9wj3=p)X_!p9p;@Lq!UU1hOO_**y^{+QOo(Psy_KKQ)uN2Bk4 zQny(a=P9K1IlRO7OW%(6d)2cn;Bua0mq!fm$A{-7^OIa7vEPr-8K1Ilm`;oXDE|rI za9&GW3VhusxFiFS63rR^x4wj`1d^1kWtL24!4@XRaAM0i4zJkIWU}`v!emjh#s6UVY^j^E_-V z`ukCIWZs|Yx)1XzycZyNR=5;@Ka1aF_G0hKlfbzzH7yNVra{NDv+#^;`P6SuV#jgn z_qpA=J!!rd;GJh!*hUxVcZKnrf~dQq#`FvF{0i;3hyFmwDHP*(bYKVQR|&RZozZH{ zLb@L~1<;dG^Xzu`Dguuhv?Z6zJe&SN%DIGmM_pOK<5|c|^KA4hJwvF-D{Fw73_^F>Ye#|<}IkNWQfezg_ke9w8(nmTeBhtvZv31Ad`^1I5 zd=K(O8h_`q|L2U8dHTp5ixFSpCy?HYe7inn-my4(uX)Gf5Fl+N_fK}s#+iDoUuYxw zyI!0pP{-&eE!#?u9976ZB)b+@tJ-8>3NhTO)v`oAr6ZkGP|GDSlTm$|dyna}hW%8P5__H)` zcd!p=-jeSYt}6iljDKV50s4wT2W8WxICgAGG_oA<{UzZ$W%3~7gzqirOD(p3#6A>2 zI@dr={%@vZnE(G0_JBO{gm5-fZOO)319L*WgO^s_#iE!020ZGBGya>14{mg1lxY}_~1Z$ky7fk;{1ioBfblVB8cd}yWd;aa{_n-lCHt$u;OTs6dQ;K|;|3JpP zYcY@Ko-xOYr>|x^;b*ADJNt?!VC{E4gg)76_;9XU_espx{XF-LIl$={TO#aSu67N&oLW4Z35p!cn;e~dmF6n(ft>qAxgW=$i;?cx2fwZ=s{ZuGo_ zdno1_X2dUl3*=z!Wt;aew-}b}4vOrQ&8~T{=JUqTSHfEi*r@z0(I0)L5OkYsoY6jN z>Wy=KL>;l)h{Mp^V?Sb>O}#yYbgOJ#AL{KD-!%50`X`|-*aM6in2!qY-bJ1v{;P;@ z5FLJ=WkQEBx646Vn*M+vFb?A;*V*OJ;c~6RvcCo$ZbbUC$VXZ%8m#tVJng>&>5)&G zYa#o3ylbg^M*@)hJ>1vv-T?nMf0Gb4rYz8FxM2s1U?Vs;qaN{h=f4R)a=x??@=08U zxfyt>_aN}yI_?pAq8LBXH~IbdeaO@OPUL~Uo8#`nz4(af@1FqNAhk1TP zw_~J#JZ$2i9XZ1|Tg^Rw;Iv?G&EvEv<=^w zQ4yZuy_JhHxo)C=(S>^gxL+~_^LO_PN5CiGQP-#g-1oT$^qTu;ohAgA&ZDsA z?jG5P`3vrTu%G%syBqt+So`OD<}4^4$_j<7F`%(K^{U0+7JbMM?uzN4?W zb-7zKZ@knWv>$6D)M-AO^D3O91g%>3h}V1sO&se-+Bc#j9>w3AAE8&v9{sl&%+>GsmM_{${=&%Q=rbKi!+DH;_Vv4|f9R*D|8n|S z+EeEHy2L@gng;R^bC3Ke);woJhkURj`1-nu=80o`K$wi@pR*j) z^{;p?MPBA>@n~O9@^^n3@k5g?FLaSUBlOkby^xd0Lq9a===UVPp!Y{kAkMzGvcB8& z|IrW0Glm8-Jr?zxrUQ3p*+jy%I|)eHZ+|4KH^Ux zKl#D)Z68HjOdn-9y-Z|7zTAUnrsK?s&dYvBeq!A-%scv*sWXEp@9=ta+}QJsd4{AI zjiZ0Tix5HJcybsM><}Q&mh8XFrT60omblc>Pn-KK4H&cNhu|2&KE<;)H<^59g5UpUhH`)%cZQ&{bA% z&Y@kgcrt=|v!a;GqfYuQ=#wB#UbW5m6L`&aX77dHOb!GNp?;n{BpvI-KTF>S#}u9e zHhoGbfWv$oo5_2wo#}@hio-)7{twQsEYyX*ulL#Q_ZqBk(J_rWU{ABYHIykW z7ydVv3;w+6&ciQ2hvkDYeV3Wf>U#sNu$#Dhg}N;|=qqA>Mt>MSmt&pjr`}pLWy)uL zlae}Z(U&P-uGH&dUCR6|4!eEG6vy?hJrDQB?C-P_|I>W`f2saVI%$2QDw9rfElNA2 z^?|m}&-K%F@SDxU-T4^wZQ{S%f_Vb=BD6nJ_br^4c4eXOOoQ#Djre=YArl|QyQ^e< z?<*6Y#lK8x)?J!RY1aLjOlj7glT2yW{gzB=)}5A2X`yj!k7ak>Mw=@6GT8vj_HYkl zBDUw<6SO@SOwji5-a!oODZO6Cc<)!7LvA+sz2X4Ap9!B~el5mXm%?5D0LCx1%5cwK zeZsH(iov9A`vkB3Qip!HfT&cbp4Mgm-;i zS?Vx?#k&Xp59VFo-&yb0W1qeO!Qx%;|6tzzz58s@V_C|FVDS#hIw5;Ee}eYz`U%=Q z+Rus1wP-)BaVe8Mw!Z&O`)Q3enetipHfcZOW7toAe;B^s{MP?2`-!=PwI=7DkbNHb zOa}Yfg7W~25G+~UH$hpkjr=W?Ok)JU8-EtsSUk}-I&6M)JJu)&7EN;}NE7v9BI70X zVj^>O>cvF#hk9YnPcrF+^$k+;tbGig%>>V|SDW8FQJ&f4JfU&bmS5|IgXejV;2aXq zVaWPyu=oG>S!>SozgwTJ>cH=PAXu_`Xo9l(@9eYTt@!>3f<;s91ZjE>ePSYg_8H`x zNS}Qa`6kk5KZ$%3vH2fIK5Jc)sc&1q`Ot`b6R`m`$TyKOgkzz#cF9z)^&1kjdDc26 zQ@)wvPoT}S)-;*&S$Fnn^Q`qvrhL|&ecC*0t&=HVNb04|@q3<`#)&f6Je(=XAN+gS zJev*FW1;Px=M(H>hqT*9jtEr(`4*&nI41$OX zF`AhX<(gP#l&g`VVXj6-rZuy}4P3Mj6)Gml@A*3C-km=zy7aBz=fi_}?7ionzwh%t z@Bil<*#zaUHg-dFt3T^LbNVD7*JylPTc@mdw+^y?*DddpO&I%O8v9%)dk;F=yPYU! z!#M4vYcIf3VlUd=2Hu1CXPwl9?vZWnZk%5@vBqt|f5h2-h1Zz-5P$dc7mlu2Bw~@<$)B`4vm+5HHe|-j?qQJeVIu z+!Qf%foA$0PH1mIYhhXd`{E8YxwR=%Zrm@RL;$0~f>}b|!f@Z`JvD z*K=mw`26FHv!mpFHt)k22m31A6~CsB9m($1q}AcKF#97E6N2xnYQ$2`)tTKLNiRJ{ zJ~7=*R~yCWQR2UeX6G1P+}d1c^L-A!Jp9%f+03UDR??TR(MA*fEsH5h%U^BJ+`J)R z{nhd*2p`^uKIvq#`7f$(hlyXn&-=t&&Tf@|eWmePPbn-FjQX_~s@#W--2@*e z{F z;oBi*F&!MpbFhu)wz)Ka5pfN&uPQcqwF}SSEMVV9v%tMj{h-cZYW*&|7eV&z1;D-h z>@hnId-j+wb8G)g6Mh2Oz3my!6Y}%HtI>+{VBcIgN9<|mH}TJJqYvW?v#^oJoMDAV zaHDECI7|7e=vlcq?+xj8cVw0`spG4v8OPATkfpgQ@`8KB+05<^Wpu7vHh(nr`*SE9 zApW7=Nda@>EagjdQuEw*Yp%dELM@oH@)$E*0nCSuFN@_t5z#HY0Kd+8Dvw=@h_US9^}0;j^JCQ{rWNC zo{by$9PfgK;2^kY+=5H*xEZq#8^P(P+;!z-lHCu;U&9zbW&AefWBi!$yOqb#O{N{q z)1TBfxNsHm3r+_y7#-&Wx2XlEV}bitU=x{yUnT*}J)9ksD*6$X4|)2Kb+2f82l8v~_h~;TWkQVq3*f-n^eK{-uVr%KR9q`HX5k6 zF}uzknbQ8YcK7qD|1fpE+p7!uVCor3ovMo%x~HGPC*D{4v5GQruME1~(;JDA-H0FE ztUuZg#jP)Ra7=Lk%X8;@cie3Uf1Bx->Yw0^ch+Ir3wiB{hr_e0>*SMV%(}No>(Hks zJ=CXo0H0TUK;>9#X>h~IFsB}zoD64hL3g^wuXmd?S5+2Q9#=n@^G{K~e2_WsUGWV& zN3C~vA{&Si!Q|x3V9h1K|N&8PwCJ0U_u848)o)?V>ORn!0SnhU`XSubeafO|%P6P#zgF*i*!%u{zF*C^JCIp*e`Nq) zjpaR(O`w7d&PJP=QM|!vlkiXWBOA1s{@8Qq zm*)oYEkm2P(dK1I>ZNbQW%QU>eJ}4cYzpeT>X}d8kMVu?7p;$4e(C*F11A1;)_Cs4 z;W^Cj-d4`| ze7EyBkGbpOy$k-RdELf$%|nB5D3L9o6ZX_5kv-`{B)!J%pskLFEFKsc6q%-Lgk;bM zpx5kuMF#ylYp5#yh=abf>$-X&XV&-T;a;0iKOJtNrk(q?^){35o1;+ceXJX#F{8}=3SoLSp&_Ld}sXmN$zM>pJ=PE zxY-Fb>< z-elyzsfDlgA&*_rhdg!(?T8)>MCSSjG?N(19&o9L{jWXj-{`4kPJCQVYpk^K3F>h= zn2%l=ak2Ip0mE`VK=ZSP^ek=U;K6msTcR=1sN}Ad?(mnXFQYl0QurzT9Z0^-#yQ!inbZq{3OqOT*Hf zTh(Uoxj=?Aa+vB-9V4kj<+sBll~yT-{ZZeM7h=%eG1M7Ieh7F?(*5aAE6%^KGEaDA zj`#9QruhS~Q{Jf8-ps?4eb6gAj56?w>RFP5X!9w`kB0Y)o`2KJ^EltGA^lG8{c7fS z81;(3m&P|H`F=V1Br}BJ`{MV$>^3lNXPjF)*7@6z}b z8#9vUIKR=%Sy22XJ)yg)jrmJm?|#7W`U?wx1{cu(3tOOXwQ0^($*@Nn+AiH9PMz^# z7B(hE4n3gj)(2$kDk#n^)(NfVHyEB(<4g!N@+`XFnBwdh>4^piDTzKIEw;|Q; z?mUBj6RT+X?}R)$b&b=JEi`m;*HTKnBU{*_JlN4}p7Dy^uGvJI|Nc|n2YI-qH6mSP zUKMsCc+lXx(mA8c!*3#~wDwce_8elbMF(!A54t}{X^R=F(xm_DeUV$6UJ9>X&E5v_ z>dA#msPk`+a0kc96}&nlUTyask>^qA{O~2>l8XC|c2Z95iC4=ebhtZxHhcU!mTW)f zv$WUfh>t2R>1@`s_;%XGP6zMeTv6tvp^xuXhBp=cnaV5L6iY*2_}i$ybY$~M>UE&k zRdM>8(ikt~?7$0$a5h4{bUVd{LQ4rzWp8+vGnO(d-HZ7qei}lDhK_ps(~*6k$BfT= zUwlj(@K%41Vm^gCVPGNJY4l|H!C=Og#0DlfiB8UTR&quv`ebPCZsfUqIOFeQw`2EX zh}$%F=%(m&0omx!i+l=O#X7)hLu~&Z5y(ejE=2yCG+@psB@~E`mvtu z5&#y^>ZeCzhZSy$PBdX>ZNg64EB}JmrSk7Ez7I3sEj`-;{Ec08kmchMzKdQ?H~cuO zJ4AbYc$eDI#1jXm&DlNd{a9;dC~vRP2bib9*nS3M`$^>5yNxV0FFJdC&w7PiNTkUWhC#JF@ab9n8F@EP@kVP^2~*W z(~Ue+zBlL;;8bZxdpGTg<_$oeS-|s)jPoge5Agdrzgg%_jj`EA4vE2kB!~QSA8RND zj!;f?Y#VxgOluJyJb?Ytqt9Jmtuq&z(7$*Gm&(_06U4>4z3Y{zj{W5$PoV;ImxFSb11Iub~Pq;7=7)6rW*E*@N65cMoAl&KG z_4&{RojoBMx{T-5u6ROmEiQ0BN#Co1ospk9vV{fk)|hlIWVi($T<@TbXRv=pj@6!H zyC22y9ALk1>%l#i?y>%$6{2bVft#hJwv6auf68R&LsRl*BM*pH$(}Boq0YX&RdWCg zM)0@vyrs)Ue`D9X{<+7{zzwau>ny(-@i*vVSZTxt>bxcNY|i)78I}_Y!+5Sd-%sZ& zETj!{1~Rl9-02B<=ljhjU9k4g_uDxZd}ICwLDOqu(0J!&H==vYg@Y+*t%su*vkv5Y z6OZ!Gf7YCc@A~r+V_s^R+a_S8`yeF;h>ph@zwD?BAC_E;ojk)`&h$fPE@+>f@be_| zcS_*_3L^;}Lps$(Skgj9c}Y#sMhwKvM^baL-d z+~Tb8S9m)xi7eOI?oNX*zF9Pa@!35p6Z5YzCoesOzs|@ooJk4&4KZfHSbVs0kJo(Y z*k7qb`<~Ba9tH0(d4>PK6Fz`nqUYitxBT;9{aNI_*VAKWdfylQ6I!P=lxlb1$M>&! z>8~&s8T6S{SD^#jy*a7aA*81)fdMRwCbRCJ+Sx2Yw)RJZZ3?W9@TvZaZK;AiPQ z6YakZFSTcWcA+Z;X`}Q!z#ZiMJ@X)3^zran`ZaxOQBSHxe`!Xq*%m0bmA0V+8U5)D zbQ_-6d??_=KNxVf@;rvTXY-pzTHBRX&YIByr)g}!iO#BW(tH?sd6mN_XCHs3^V@zI z?cs>N3>|4Ci!i~jwaMyG3I0;0(}ry~gVVX~zp$n9cQd~zzXtLeT`G~yU)Ih&dPhN1 z(#vx#MweQ%YsQ&Ymtx}8nzZYFh zYy2tQm72&FJ`=!hifZxV?Wp>geu!lEE zKe!s*OFViYYa1Tc>z|*m_QCJI?4;KR?D+!t_V1GpbE$zr`8`?-#k1*4QHJ5%S@C$% z)Q<082{5mpQ(M?a@qbdrmx&fIAM@NFn0|Qmq>|l(l*j0Feb+Y8E z)uie9d#2CjW4GfhzgNwU>+EjZ_XQp-%H>YgS(6fMBoj|86oA+E*p_@O3a`N)JOn)> z=uFLj4mn8YNDUspa#x^ZDR@`3m7DWv49@hYPn=B#9w_cZIHWdYZ~r~zhtY?o6k{jt z0PowRyBVCFkpC9_GG`j1uZEqW-D~-7&TMGIUXZ;W@|zv{;x7;GS&RNwhIbk8E{g3C zyaTTvtpN|jx6FBdSzKb!mXw^cdle>#h+cwWIfC?lOoeU}b6uG8Ako0HI~Y&+{ndf%#|-ly@E*w25@e3-sx zgbPy&e*rFo)E@7HlB8wIeU|rXUNZ1(=2(3Dg5~NzckL;ic_`j#GT*J%S|JT!5~l&~ zA4&v9SJo++)%Jrm+uINBIy7Z0ZXa64>7SFEWpF8n>=300pST#vb1DB2!&wm{{F^pKAVfgs8#_Qf8PKet%1Pje1WSFDY(g>dy7HP`rbBGL2F39@;uYk!SDtZ`+M-BBa6 zO)8A{bn_zLn(wvpOekbMCx9Gg}?!Am5l2lC1qyjV@-ixlQMO>`lh-o zb>(RuF3ZM0gK-7g&V^53Wc)zG4pZi%UYT)T{sd*^2U7jldhPAR$JSSS39oE3WsrTV z$D$*tP3g*;D6_=Uh7<6Ex+y+;FP~seO~$$Fc=hr zHbkvl_XV{Hp05HoE~1WBbY989RbF4dEpV;-50-aFxWwq-k5{XoX2HI7Hu;mBl|tJslx+!EUZHa-1hM%4Q$=dOJiwC{EhHex}?rOy5kDYP{yvQ^H?LS51kE~Na{RR$>_qZ zN$>)mQ`w=!eB)P{P}nOxi(394Nw09f{UCURu7Chg6UH|c24{s=??g@r#WHRS^;gFG zq6XV|-wx5xsRg=U(@4HhRCY|xC`FeW0RN6;@V~&XgM2sqI!nA)FTch|Zk{>2CZ_Z; z&=KN^@tggDzC5FNl?*X;QJsgRd(_6~0b|Wp(*1XIp!zW1!|=7Rb9CWczQ_0*>cAhE zxTzW%KlJU)yUu6Q{k3W@%Ds32`WO~mqPin$LjDBeUnCod_UgU~@rEen%o#VxUR&wc zm=XBYVq+eh6Pwc&jZzn~t@;$@8~|X7Zr56Pn>WtlSQdLc%#$fRxm0cuxhS>^)1Vqxg%dmiuf-^XjWSao{%ujE&6a z^^pX3Z&7{_dJ8eGH9FTty7O0fZu02eES@9Y^W{7X?y`Bve<#=rK24-o@=*gH>b5-6 zo+-6eJk;P^t2tXej7}UyHi$%ROg*t98yxT>;z;hEgRD54u@F}k!=^nX4LldP$U-$W z^uf-(iC3;)t921ec30Dn8ABzTa=tOLspcGlRDY%UUOs;@(ktihIOLn^ot9Sr6`4eG zOL5LU-Bz*;?f1@8Kk#A)w#pswCCTL5;W?tSGbNv;{Ij%k*z1tr@J0U&Sw?3x>D()| zE>Dn70k2?SQxKfbZ;p-v}236W^CJTX~J0MJ z;eDRop>e+y|7HxrkzL*xD&@^Vs*^Ip%@&o*Cc6~_CVXh?kgs~Gxpz-%)k)?G)v-Cb zq2w2@!tU3ty8lP_o+a$PT~Ty zdST&kox6hXf1$lgV-FV6(6dL$SK9V1-nh1sr++vqTo~ig?8DKUiwoz|j`m#5p#5zh zwETB0Otg}(il>rn&TA6?OhS}r!C3HZnRAh%?+Q3|{F>ixZLYQa6(5vcGFlKcr?J1I6kb>q<=Qk4?syj%3?AcMD60hPtnp)v*d(V1z+Xw8rGO{o5 zb)uR-&I+Wyv59tf9KRNRNq(*TCi9!d@7;OfOS1bjLD4Q^6QkDF6izKg2f+qv_NrJv zoUb|Co~jJh#$zwd2X%@F%mchWTe*=Vc52O&B^#o?x0iFwW$B2W1+055bcZ zGht{U_L*R8OiuTtAN^i?SNg5TW6R*Y^!wmZ{`u?eVTbeAcR+6^7FO{rA8Q!8ITl)h zM5Oyq>myNUDLjDl0P_Lo5_85N>lv2LdFKvsu1*x4T4%67iwB-Hk1KH@4+~_C|DO3ps4Tjx!(G;%0YjC-$x6A~%pl zzJV9i#1q5}w!1pxzAAOYu5X=!E{d->m|!ncVs3B%&-m4Xx;wU3HeX=e$(RN}M^xYa z-dN5LJ4}gq>&@=D;A5L?+tKyAeys2DWcO0O>l=1JV%Rh2c`Mzqf+z2)>q7djd+qc- zk!Qn0Gvc9B3S%?v?gON0%)j?x7ia$#c*Go6pM6a>h?Ba;VcZU59oq@7_GxEEa{*q$ z^CF#dUFk=v@1h+2LWiN>HC?|V#`-vZ*pU@CEn1`UTLx2~VsALRS?3_y^}~13ap@Wz z^Z35htxC4e2Z8buIYg$tk>ZkW(|3dNiLO<9W~hyzco$o7jKRg&oTHKTj?ucH?qiVs zc%OSrld;V&&q?<0YABEKKRxKwk8>2`pDc{gx-f7DXNiduYy@-JgtZ1$?<)g}YwsnV zwf3UqlPy-?H6JIlR+D|;2QpLH9FC(*l>ABjEt5Ofxzm^<@toEie}S?3lw|zl_=Qr$ z$|dMSjuY|h zV{YZI+=Bgh3o%YrQTd51#dP^J|os zO!Py^N#K&;CB1)U4A>bMTf6t1!JOCO*}aF+hSisn;28WWRs~ol6s`it2Ejk6hkHc= zq)9f+4r#^CVD0|IAqh{@$?o$8!>2Shz`a z-^6?R@LS|QG(huSzBVk+TjwsrS5*na5bGvzb++&^e6Ls2zV4CA94k0k*-qbtCl9Ny zz(n*Tm_UAD9)iq6ka-AFhv+($LL*<~6w8&%DyjZ?I1AK4n||9#7q z`$jmUfH9TtS(Q)VEoRP>-MjvIa6{?3ll*qpHN;GdwqgT%ty-~DlL{~LS2|Wb^+}I< z@6Wk+2-|{@bD?QL=EcP2f-m}>=euww1x*X2#~nRb{tNQ!TVTDwyUE!3@b zdm>|~dI@}n;46cN9c2De=F+|zY(p`7{rr(z2-{lliV|yzG!Vr z?h$Oi|1*mV(&g38O|;V&Upu6os2!&-Z}ip!%*0cFMBN(u8;#q@Y0yp0r!Q}a7amUD z5NsuLXl&i!jeN+@V#AJLD;S(0jyWqFzG2tk6wmZU^2cEE`*R-b5Y1fYzSgEW>c1aW zW6_?_822W91Q;dE{YeYBKWRZ#%z1m^Jd^fz?w(r2-BXLI(2ok^Ni%m(CA_<*687$? zH=#Rp96(QJ58J7%J>5Meo;R1dkc<)a?trTF4{xN*cNpuIW~*;!r*OXTv?^!TWZwBZ z4sI7CehR(B+`FW`sGWSf?Ly8xA@4MPqc0|wiL~a{Dkp|f;lM>z&L#pvo)0+A$YZd1 z#{$kX$Dt{)@oz>Qi6iXunq!HhB5h}qlSTM-P$owGO0RZbRV2O{Cr zlD7Fn>`gtJv=3J~`^In=1%H>($+bKu$QL?`J7f6k+YFk?yNPd$MiZMw-3-atcKB?GS z?gdy96rO91R%Lk4%n1fLuS0a<_n|{+NoC!Ff!34RZ$bY=Cnei{?!ZCtaiWPg`95;6 zV5#>FJeR^!de^b&M5<@!DBuXq5nmwg%fRrcK~DXzyDi=DU|1c#ba?eR`o?S*no8g& z{pU^8)o{viw*{IpjxnpQNEF{Z@{O-MMe+3;ddV2q`{kJvzy4{|AE*Al=Akdzl%YMr zKy4ZQg|Bsu(411;QMh^gX3JMK7nk$h!mS*i`of3l=wX7>u zPAu=o4fJD%w@>{F(JN$OYinHWCNu4BiaHE_g72bpQ*@^-b1fN0xc+I%^oOrYepy3Z zT07E96*pt$s|oo}P>0%h4LB#kO^si)S#c1Ryvpdo@LthVKjy~ADT9-YU9?v+NdL=X zSD;_MoM7z|hw3?6Z-TAtw9RqFs7@^0!g`WjQaa){d0uwfaJQPi8F?3Y`7$PDduh%& z*lD_z_St6&VBuwZ{`~OD9FAH!L4^r2fhzi%=by<^F5CFp5@K= zsTK1rd33bu=wpr)U;k$1r@bl%Uet+wS%2T457X2~>QH(qoeRN( zWs9n$6O+krcnA4q8!Ihi=A(}?ttDj`N59IbjaKq@FgC^AYHY(8TO;$86rY#R17BvW z)5gd~BnNBl?T-B<_vJd<`mWFUzQn#txDIdi%d2PRlGrrX_jQLkd5eVo@`mq*2Gp|4$ykCdIK zazFHK5xhzG`3b=odf?Ln!7q1)BUxD`QCEe#UKjXbAF5lV2!gDy8Z^#4$Z6YOHtV$li$}DHt}p^Tu&b2i2Hu=YG0;N-`_~4Pj=e* z6OM@94rVPJ#k!ZBPPDiI7%GNF^I+p&BD{Z2b4TB_CcaAFT4LDpM~UuE;12Ed zG4kCqUhJH6x*0F;+8ZDn26r$42MgmR*t40Z>|FQny4Q{R#QQs_->f6qL3(XphteD2 zj>g%SoKQ)d6sKt71elKpnGfj^$bEMunG3C3w;G!#wilf>Yx_2vzkY1SynfO3()A!* z?9Uo1U3dRcnwf@XvNk^blX9A=wGq_X@MxxFw85g6(6_PVmz;VO{s{SBg}b7agP5N; zqLq^2i*r{>D{nSuiwNds-l+2>@aJgBDBzuF4#4TPT^TP zk-wg`X0(Q$Csv?TPJ2i`$1Jfv!G6kV;%V>**`J=IFJ=yzCp(AiV`2_9f8uu`V{2Ru z&$j%|5v_Xze&^4j#_RLDI^-zXT{RZXp>W~_c%5K=i+FF=o5So8%wg7_L(A_z*xxxc z<;rbwb`JaY{rU95@JMLQk*?4GG+)&E|0w#iXkR#y&4+Yhx8>`c4fe{xp4Y&U zr~_@`c@ul)HW8a3{%G|A@t~D%mU|T?vkA`>Hx-KE2ZQG3NIw#~Dt%`%?TR-A@d=0U z2Z!(nhcel~4XkarvQhvXai{* zUbcN3L_YlU`9Y~{9{+sdtCYV-mKhgHpENgI*)B);Y-+C`Ak3Qh-i;|09RlS*F2YwLG$+$#!$x|#=7?l7UD71KP~Fm0utE@BIEd>0%fqYAddH_?W>ehmJ3^R(#7_3m@b z!M)_ySumbdzoEZXTQ4KI6RqgC|)DU{I&8vj(gU%9^05>{bfDo#h)E;VcA#LyPqfB z%nRwNBgi-TK!e~%n(r#}N%EvmxBh+`7h&-UTNAR!O7~ablj@KhuKZtte^stO;rBoM2v9_Ot+=?8Z(7Y05@u=X^* zeSNIGWml|spN6J}@u>@cucU6ppv!J1`N-19+4ut5-RmfS*=g)`IJWP#_4JR5YfEE3 zTCgMkWY5l>^z7V?C2Q-Zf3UWI+cf&o0PLQmj=7ZEcR6^;yXfGr!9&g4^YFW7>J$Ha z30X_`r&Z4DX3Fh@2J}UH_w(%qz8M=CduT(%XNum5_K7D4hRn(JMfdh_x0O%#bmp_# zjMCrz*ztY1oh-OTfm;d8IJ3_5|C{Q68r&xTuUQ)(29AC8PdN2U`ltOL+HZ_cjk!R+ z1J5e$*zcvT_^IpN86Ip?9&DeG3=00rpDjD{bPv9z^!C7I>)r1OMh@pd18-z{6H}d* zoWb)k^iQ(aWf~uF3Iiv>sD*J0My30SdvO%_-QvMXIC>$m4WgH&v~n}^Ighx7Sze#p zyguJn(r4L9@21a{JR(b<-a>3hr~(OjOBdLv78S&kogi_mCSMhbQ8VX&|>s66U+W1 z;T~nSa_)g0cR742?F3eLwDioUzlY;%nhViB@%1;#EBfqoqJu{*eU?0^Sl&OuKhmeH zche7AUfz4|?>o!w>p|vmjpx@ns&}5PZBqCq8DH^Y$$RX0hkhe_cQm{19@gqTdtW|y zpY7}Gk6m%Dg1KlOWnJlw(S*jv{GlQ4BrdC zqn(^N8)p5k)!tZ#K;uNOgd^IIW@6M0-?nqZ-P1iQp0#k92+dh@W|b2R5GQaNF$1Sp zIqV&C0{n6;-Z%62XnvfR;VgUAak|K;eFtMlan~Rl=M?j>>?OxJK!F_&@eTiUoH&si z^Qf!olq%;WzE9uJcfK`KW;4IcLC4un*^&QMPGi??lf1e4c2z7x_+E!Y$a; z>NspcbWY~SJ~R_sp;(J|^J6cc(?yvqzY};arOAo5;qLwyIYTHu-0-�AKBwl+4&4 z8Pm#3|9M|--KgPiW1B~xz>g;923NSIJs6XohX2#w_$9-QyqFj<+)V_A8@X@nkm2CS z^4vSnWd?#RbHNZda@e=kw-nWH%OMTHl5+BE3%A8g| zLmbCt)a%oF;iG6wf8g@}7oQbhNdgzi{JstlN+HvCw!7ytr%lkUN;$FPE5qH-Gta`C z)4*FNo6Sd&FSn2``X}5F5Abp0R1Y^kMj6RXEt@C8!p6>(%Yu{Ln|U;J^(|8gs1J(qFmtTFYu zQod`Uo`?CC+W+!{th@X-i5|567U#@kve@pXv%hAZy(d=);f1_FxQEV0XXJlW{9c7I% z=?tWyxsGFgPytTeD{Fg9PHUXqRQFGFRiwzM{P%Q z#7@w5EP4Uv@iTiI`koSHhGW%X`||_%&tI=bst-X-H|J?hk*}! z=4zx%j}v^14^444nja57%!`2!aES1W@~h<+Vo$B$a$H3}*3yq<#}kvu?|%a>FaOZu zj6YAa=uZxu>EQRDz}ZhQ{!*O%o!7o_b_#8eq}`C;b_LEx4l^e@3nfvqW;8!$y*SW1 z=0f~1ZR5CZiC|Wz+Ugv8}!$zmGH6rXajwCX!&flOoSJ>$so^?R{Bh46!D9}|8h zxl7O3jygDxCg7hZA^q3tWl?n9 zsMZ(NWk~E z&egX&rC*RPJw@k*h<_V-ET;2Um~Ya9%8NW!hkhO+V$I1Ii1;|Gyi_3 z{LIfJok7fdAOk*UMJItNeI68@4Nv19Oy)&AUOIrzfT*;^yoa=Co93Gs2F}M)K8ptn zdCwMxC6No#^H>wC59n`WW*+w{!ViMvRD;!rulpvd0hT2Czj1~Zeow@cXn=yaOT_u(#y{v*<;em&phLP zI8)wV%iDR^{x;&K0zYPN6P>H!FEA}%cRvn~D%_M~&p zam{qvs1n`4_N-W?dGx!9?>Y-ld(3uo9$odQML7pL5Mh1Ub7hKj-~jnHsy@c3e*H+W z06vei&qep47WXbKa&SnGG8>Y{u?eXoG2X!0QDRBe2R zdX$elb^^QyIrpQc#`|`&`8Kg|!)q0IUxM>zk;h*<6KK<{SN5wn7#QB@wq*swiwiN+ zk2j|A!n^mg?gdx+IK;{1hBgB0105FDIzvR~UX{YSit+rO?;6ug;P^$+VCLu*%4uvr z=dZ^46>qF|eU#&w?hdHrL6jLfow7b3QXM}2eVn@P;r(-}vtoYsQ^wDyJj$!SeTcrD zEImx zNy|UDI|Q1@Syb#xpO{}vTz(`9&4r%StXQ!tkX?e#?b|;WTN(*n)BI@7J5km^FE2=2 znoio@*kk4nP2HUt$*gj_cvn49&ZV$=y!OEmryqrGrYh(rG;?Gex|!l0odkF4M7al! zUmd?vdx?BIeff!xY=3P3_l1kb3cnMakLb$=;%%5UjqI}T9h`G#cr#};#pHLlap%NJ z4Pk2QEuPKkc4Cr8tn7lB71`y&{QHqz?xn0`qRRDdWvR+N);GF)?$nx+?4mPcv-z)f z@t(1L^!q2gb+WmFzs4Q-xOk)kANSY#V(?h;5<|5{#jjbrf^*|B=zQvrWDWYuQEevQ zU(~M2_r~-<^!F~txV=gA+n(ogKkLDlsRl@c7ny1n?Nsii{UKv1m8rhX zyJV_xOtfu6;rqOgHT^5fROiuWU#2>j@BgYyC3yQXm0%t&k*W0UV%Z$~Aya97e3{C? zo_?=Tzg|bCvSqwIf)OIg1T`0=@^h%dNgH ztG&gN1KW2S+8)J*1zrWRk_*?l@Wx)5W!;=()?l*x&G6m*oY_@XvR=Nx_)g$^4Rvdca~Hve0i`lT1>S29{A>?i zoLhB>+;BH(50d9PwF%GREUKP0qt?4?Xm`yJXh*zUhPXocfc^0XPs;h_+vuC-Q0+-J z^koR%gIQ08&^MiXrnwg`ou~S=?vW34e~Hc|@X!1ltTw=(A}^TZ{t4U>t~ta;eNpw$ z=Y{-Lz51&*`{L!czvZ-rGDBwpZ=aW|4xdL~N?mE*zot50hnFjl@@g!tqLms8Jczo2 zTj?wF*>i!?Nh5D?IqgY?@^Q3sJqf=%_LcMXX~$Z=Ui&-8nUS}Aea9d1xjk$7y6%{D zK7qbX%x-lO`=n#{+30R!@%u0|!Jc(_VPPcC(#LnfyT$K+VDw-3CH%Cp4W15RnK0nWm^WFe$6J3iT14wUMCO_|C?f~mCazWqo@JI8FyUPszlMTkMZ5^J2jO zx)pBI_^sWc{A}cMxFE(MM@i4I`fr^2wU;EsdER#16Y`ioYle~Tzas~7rv44gy*X3A zu!-;HoZl>G&Uf5Ujm|MN_5*YgVpdDf{Zx6Qi_`CyIR|+d@E%Ot^4}Xe-NF7@%4rXa zaO#cj(rYt!I!rB0H*o>w^g?zBJ8oYmU5HE|`dxn4K`pSa?a+MnZ;w)K2lgbz;u@To znrD5QdkB;8Nz7C|ff#euhOEkcKH%`sE5I2epJIEkckOXcX!Ui^0e7!|nj`da=57n| zpv>JdMz4y`JsO+QF`9RS58TBkSTU!hFF8i%kr-S7Pwr*>22a#B>u6U;wy+sI5MEt& z263j)4}1QGY~d>@XZ=;*_sZ$6_z3GdBDhl@CO2s1b({fb-t*^b3>_LD=a&lB(VNZO zTe)~C_$vE~=j)1=(^S@CeI4?(XmTy{E%{n!1_{@7pJ&iZA4|-h&Y{(}qVB1>iJ#KE z@lE3&2EOZ@PSqtjMf=}Oed=ornXLCr#I&&$g-FvH(VF+q_tZFRDJOeSUh4(9s#tEW zTW#92wxNjH0~UgBgfap8ptSqHk55Z=ux@nb;2)@`X#be);hN6UFWL}fM~iy6CV92e zUZb@rI^gpOBl7`U_46FyZtQS;Z)R<1o(Q90p6oO6P8J8^!hwl}-QWP{Bb%{Bz}dr& zuL3SQYkxhwMQ5!?J2XD@8E0v?r6uzXeH@mt_S6`9P-C0uIdmKy=>5O8_S^(#%f(p> z2Z$Nf8kdi1DDX1tS~`?ug$mhf0ArV}!slH+41{wL_}aj%#x6dWNx6Qo9-J;qvC*4GNsxw=Y$Yl8Q3gI}hY<#OG-9NW=KlIPP z>)Ii{)u)S3(1(5Ks{Z>j#-upGFmo7kh7`WZ_ZWXeZ7W^qb+wbu4t;7Pdr~QLI6BD@ zABIj!?+nuibFO$tHoui}rF2sFjoLcKm@}5o<_^-i@wr{PhXVQJKEYA36E$twyw1`$ z{Fe8+%qq8uGrp!t$3}0eioxqVekVQf6vnE!p-@UbYtgF3?nug4-h+LTNh{a+jx%ZH z^j7zL-ALah*Xo`G*&41dd0)bJYuokitpH!%2|lhddAL`UK5xS2UX>6pS;aaVpI=NL zFE`)Ial+1j>IcaK9%#Vv#IL?)U`u;HNI-*DE}q; zvJsjp8t@PBC)}xh^3w{)uh@oHkT04440&`nonQ(L=?UfTa^FPyCrH!Tf=pEazz{7C;E zWu9aH?%=#`?TyyjwtLdVi<9}&7^~>w2>yyE=7WZWCMPyJ(zh4q_f{pNna^JBooUoRU48^$48la7l=CG-CPmUV_!`9Q=g zJE3dk_22ByrvA~yh&0f)X!G}}+o#L(z?W|W-xd%20SGThv!hQcY<6?a)qHTT>9mHMlxE7GPm*0~b|JH@H? z%4>`1v-OQh*2*)dLxF+w8`=R5j{w88U@%l~u!Aro)Ii$^_tc7PH7k%@W^VzCw{(Aa%^9EuT8N2$dv%+^0i24kj z3=QFYE`pI;IN)zO0F_<5j=wqw3)#S&q22nXDkmPPa`ryzIIA9WoZaZxzAfDuXz!nR z{vq`3AZL92k~6vZIs6)^L$>vKzqaM%_a2E3K5_wfn;dKJEtC!(;Jy|4!X?*A{x<&b zRK{(Ha<&HW*SUk=1)js$^Cr9yJ*{oSuZM51mObgxvp)ha)g8RjiKWMH_nx)((Tlt5 z`0MM#-P9#}?*Qip^kI7+Ap8h@cvAjMbI02aZeRZ92<=Cl1@z%a^kL4iK+e_O1*Q7% z9~f7uKKxPM!|b=${lOZe_*vaCvKJx;a+j58?j`h*yD0eHTKE#*B{PIG`YwG1y$_kk zK4agHD*Y^mDnIcO>XENGWBk3wCaSSOD?(B0uY8N>K)n2XR?!73ca-}mC4W7x_K~H0 zx+PhvPZu9#=3m#6&v$tHNGorkHyRnGs%Uz?T;D}V1IPhKaMhILrmwg7sLA2+$c z9ses|MqlI}kF4DA@96seF@Ke&)2If2jeeq@OZS-NJ7uV1N|A@uFeQ$2((+}|;|DC%g>ch-^ z82T4R&R)xR$=lRDRQHjHHitSg?knHrZjoQCXC17=R|BmC7j%zEB*Xn@#2YaGdC5JJ zKhziFgJoX#P);=KjqW1>mPX$GJniG>%)^)9*%Ng45&rnqZsutA#mSFK47K{MyC18- zRoS&?F$UeG7D_TsbN=N*_ZZ4=Gi}?u5q9w|*++A0)&sn_0s8v5$&>6B4~x@AAffx* zxVMDyTu!|k^&R_15x4rbi9mVWG0@PIz{TLFB!hsHpH+LnU-IAQ<--L2lJQh_ z5cMbza?&AnOa>0)$tQlTbAMF+O5L+adD%vXIqVCh51M<)F!)1j)UV(3?Hbbctn}Yf z&jI+!0r*K3e3d^ki-*esFZJ^7(?j;On*ah}&rI9n|%h)(?H=J;-?K zWxs#^j)Qwr7%|1K_64e(u@4k^mCl=Ne9&>OW^tABEuTM$|AZcKoXA$k*+Ti2&DIty zK9u9VnS6VV9&P#1Ztq$AC+9tjC;7bSL)5p8bZeXCPGs1TIq{&f}yQ()#<_^WnyqMz$tYTdIb zn5+J)XtT@M8|*uKOG@uLEqs^nMZ4_v)vSS`_kkDLL+lN@PaB*lF8h0r{*5O#1 z3hSax&AZ=-xwHIYs(fhm)mhQHDTPJw-WoG6<+6#|I`k~>{-4i1j`)Ic)vO8dsF(k9 zN3xxlqOI-nt@OR4$p3|VKL1yohtL0Y50{Voo9M56^!_`tU74*d&39vKOJZwF-Bj(Q zvO`}5Mz>L>+}2UV{f+Q^;l6Bb1L%Y9U>DzbfpVp|UukOtPR7oGP1o@KTWPx{$zBTR zu&>8!y<-30@U)pHXd$+*zw=#mka)kED6}z#?P4E#vbDpprp-FH_l(`o_>3JcU9`j9 zh3@iDNqr-zuhMp=eanxSJjw2BX{QsJtSX@~Tie-F)O$PM7lUKM1K~qPe6_;A zsDHTd5WJyYvs^}j}t!7rZ4xL{|n?1@JMhQ!nXk5V%WU|&#`<{`UcYXBXb$N#m@ddzkjrazr6+@ ze$R)!wvo^3H)1>3W_<5O+R=0S!99uxytkyDlS=Bj3LC>NzR#20LAX<)!@#Q`AFJHI zQ_n!!tE3s=ea{kb>vR0AS6`rO!v7!hzJT<7)a~0^@TVD>$sgw*9=GGf{%UZ0lFDPd zIgvIiZ8!DmM><#7gFT=+X8D)q?jp+gaJ-+kBm)Xwf1$r-E`b&H;F_QEt!Q(ZmhUOC zxnzxvKzw#uekbWO=+EofFBUScpHtswMcb&K_n>6-6Dc>Jc6Z>+m25WS)qs;l0P28p zOb3vC*%Bm!ZTc}X8+oqYQnVvP@a6Bj+i@20o5e4|uYo$6n5QOWaOw4;yV|1!{mVz? z%NHLMPJv6}`6oVvA4~H}UhVyR2QZAoM-Fsa*;g`>cb`kQc#ZZI?RJpuIhTJYvae(q z-BILp%BSd^$s#_BPF|OsM;dl1;=QV(?a$qdEUlP?P~5h!`W~cxCzkC&9ooYj zRK^dNwlVE5+;jHVfD?WUpz}AwZ~LBrbJ_m{oHc(scu=zQ7T~<9L?({6a7F<>Vadd@ z&1hZAHdBm^V6Q^P%EaG6CX;Oj8Og*#)~0Vn-dK!GEWHz%IEk+X+~j!pnjF4cKVD&n z_bi#X%X==BiN6Y;+)VlaXASll;pzDN(I#GDQvN$8USZ8)>@zoFpHXZhdWYt~z;z6G zBAd}%_oMVz@^58q0(P!4`4{+0bH(kA)$qQdQFev!YChpiljY-i*Z$z%(7 zE|-7VH(j%jvwvc3l6hAfn2LwKS#TlUj&VZ%HY4*QSECb!ouP$m_+FHGR~wo4pWi;X zr-L$wqxUCPIgiS2DY;`{v?%lb59MUr?2pXLys|o{7T6kfh)#-60h}xMgDEfk7?L%) z(8XBMl}lu|MeeT{*MKa3KIljjym=qz8U@-`?HcG@3=h?vIT#L^vlpmiAigKo^HBe8 zo!z8~Z&k6zMgJ~l98N0PO=C43=x!b6{G?U8s$!Bc&dKQxHQk>kA6C$uYd<%rI;+|^ z)4pvE;`v2|7u842LmM#&y*Aqg?oZ9wD&@PRmzs7@&ts#;23c)H8m+{V1>NT zM1g1Jb0Ph3Ft}joyR*{$(QUvZo9wPN^YX@a#xQiLmT^jleVf_^FXVf=`Ym>?tGz%J zSt2$j$Nc7W-=Xm7*5k7Vr-IJW`H#X|yGA{o7ruT0{k&_`Q|9@LJcm26*HMS~>ig-x z&LGm6oAO@-oUefA*`eTjFc4h<|H*R9_mDiX1>AS|G`72^%zcL=@RgbS4&y=Oz6tEL zb?Rf>`w?LcHDC|aTuq_x3I5haxeFw^pi1|Ce3mqG??>Fb_akoa{gCYV7V6NwAFCOw z?)_K*+@jZfIsctY1^04VwNS8RjcA?Y6XTA6>x|t=y4GX7SK1UJ*ciV{dSyLJk<}~x z>b}imq5M4HO{vXqIr*Q|e8!XAoIO$VJo;9tY%iP0o#uNvZLxS#?yHylHkZ8bkz508 z22)=Y-n5oFr=xEw7TVGa%Ucv1p!=Uiw~VdQ=+=we@r-LG`GdLjyWYfHU?c05 zU!`m*eXm@5=#WOQo9)T*^r!v`!4rAzVPL04AZAR%3s+B4%oRVk6DQ%*oTl3AChfLdQ+o(A;826Wd3?ET{XlJ$I;&!CT=CXdfAzr?fTTVIcQg?qXT zy<{GAwwSL+X@35uJG@9=4cmT+g#lB)k9zpuli$My7ls|ZusaivR$ zuK$5_gG=CsY}g;9+||T+8=8+i`kRvP_`GXQ=X*hQk-rIC7>!Pttk4PP@%`Q88(mV* z110r5VeaNC$E)`Od%xzAt|;dE?SS z&@FXt5c5&^p>QeQXzV zc;h|6&)DsE+k2Tu-eLX6&#;MP(_Pr@zs=c4{O;hF<|qA7KIPHqg5i(hPbRKcaor)K zw-D2vmA=-_Pq4jM`z7;=>24xz888lz20b*oOI-*1t5e1O)iLOkc*n3Tbc+0OBMX<~ zm8ApaGK$r~Cl)?~Ja)D8DB?@ykC*=R4P@V$!zBA&kL)`II$D%{e+T~=s5>M}WMAUE zd+(2wE$n9DC^%D3-y5mBk$ZM+e1PKI#+AsvlS^dZ$@!`h+4mNWgE)O7`^Kdk$wt4( z-AG%9#w()hAlD4*Sm!RaCJs5wxwxgW^*x>7a7;X?Xty2s3t*dMjL6nae5(fDzTNgF=5n;>w-rt( zc3rX4n>g!r4Z4`-xH8sI^Zm4uDI}LlFI=BcUBa8LXCVq z+V@xD>-m4#lT}OqD)(glo&K9WSKoP} z`v|^6%H7L*xWnouBYEG*dqdWKZ{*#NN9P)Pqt}F^+K*;+gHuV>x$GY0eileFci}2d-1>FzKxd1mW%nrV!H}-9igX*N zG$H>^#^1XKBRaJER=&&bA^I4J-%uUOD%P{z{rN5Ufr;;pdTS%9yJ#}R&c=xKrQa8# zmxiOrMb0|c`1-Qh{9Tk$AK%E&hY1W$ba5eRaH?F#sAf!u(#DGmgiHaOay+;AS8gBa z;9QIv`sM4bVf6{SFCkNuFW0|p`Er?AYo#`=wK=)4n=-l=IK|&-#10Fm)we1~a5yXH z97b8-#g3{MaYPu1K5&j>n_e5e8EQfx8kt+ArsT7}+v zGWnv;@7-wU4x_h@9OCJ%(LlG#oxpeLt>{%XRt8;+47#`~<_s$wZPJF7-CKD)X-0qT z^z_$GtG`CjU!&B84qc$mn(Km9xu>$F`fEA-3dFM&M?$3E!mLkrzWv^yPrEr=XZ zDVJLODUYw>3=j8yV0M=J3lIMVy!fSN4l?9DPCK2SnXT-knGNp&mU8d$(!un zjJ&v0zBjcWWnIJ5W-><)^Zg#=#}6C)&gSK35na0j-E;7$1v$|)yARZ-C5v75{`F{n z1_DpX7%t`S=Wo%7dfp=y;4BeYja578Xy!3{QEjO6HJ8HWl*?lXxB6-B$ zBPkhfJ!wuhhwlwLygx>CmJ=D{-QL)UeW?jojO}K|mf`!ifRE^l@L<*>w3DSh)?Seg zFLL)&*Wc;;R&=1P#6@j2dQf=`r!P;vK%L)ZypjX(M{cMYwbbsFHM%G;pwFdpzyb0; z;K^Z(c_=(;$jzJ&r*rb2SO43v3D9;6ZMV{PYaeY3cU8x)$-jhhe|>;*z(D&gl|G*| z)_Wn2Z%*U<*k(Jc&pYUR&^BbuS*6y;H&i)~ypm{!3#kCN^CU27-zV=7bFLiX+K(e5i zZ1JUllN~}#M|Bm?q0Duz_VfBMd!KBfS@47L4FY!sQ*4Gko&439oC^HiPo0uAlvjD) zO`Z#(t@8L&ur?b^hIu=Z(6&RZBHR@q3N0cY6KizfP4`nC)j3;m~Qt6I0p{R}39Vyy_Oi-jd^IYLvT6H4B z01JcP#qW#VPxDQ-=~^=v;|ra^!S<==J_p%1t=^Em6 z9LL6ZI?nmntk&%EW6Z0FjdzT{B^^|pJpRm}fng#$q}J5SczWwy>Rzlg;BYPU_HgmO zn%mNN-$|W54_xG)1V0xY|8Mm@k?j66^mA}Rb8(S56GU>^576g|FgRR%X#Zn?*AmmR zmb0;{nFl`x=y>kPt@P7ecE9?h{eOr0X=KOuV}L5xv+Q<<+SgaRA17V0+Zu0a?DkbA zzb7l=qt>^TN&`1SfjYE4mEc(Uk$0FZY5{vB1=vyh*pIGD;PexblkM3DNo4yOj zuIF8`$Wi*d6Ta71EbhN{ z?%OJx}n|+T4oQ;nm6%wSphQE!!4mdNn2Al|!lYG|3*-XoD96!YGNaC69M)v+s z!MU~{aK8564CnhjI8XW);k@jTfRg~G&36QxIDb3&g&qz#w*mj`ZVTsqFo!KS92uNX zdG3D~&Q1SjIB)Xc{Hkc-zktsT;O=%{+I4%t*~;I^zrvsM%YZW)_&@($3+H9+M5sb* zjs%}y-u<70bARZ@)6!*=|GxOVjUJqD`4{25`JsR_1DMYEcECyTcQ3yt2=aDtI!Qpa zq31ZN_Ti{L5;#BbzYOQ}zZuTo^5A^#zX<16aQ6T(b#4nd`}w;F{NDB;G#dEVK4js% zc?tKjtVEwZ``ynu=?UF!W7fNE*ijS**?@mBm{hE=Vtw1O8*nxve{~j3IJLq(1G$BG zGoAHSpFo~WP);$?;wht%EfqH^+pm25MsJ9t4OXAVU$rUsq&*k6+WvwAkk@B zB}X93OTQh!v-SwfZYbGau|e7+*dV{u+@I~1%Yp$Bp1YQPHIm~3l#MOV&G+EHi+hKq*E~c0Iuk3tJlR^Uc5eRQ;%j=9|u_P`c9oPMXH@1nDX2%ivEB2+oe; z5Cu!=f9>woq-*}ez*=+MhMd_({!)1FVSKkz&nf)fjPpZ&^o`)>BJeW?zRr6f;Iwu^ zdr5Z|Am5?PY(ZvgMWz_dW`_g{+FIzwG=6p1eL{RoEkZsd-H>bKcMW!!6V! zf1bfZ`Mt90gU)NtVrP|~gf#Y(Efwr3r+K&ye|8;h*HKpOsBA+_ez)s)4QR{ex%szG`7_JFYa?(L%s6t$~STy?;5NBE?9(P z(u=R7k3$O6_%6LTl;Z5L^v%^yIy-a-bGqz36+SDS_Y%`y)`|ILLFZ8iyb)fRST1lX zBz)()_U4`v8}p#u*L#-P*E?oJ_K7*MIbGTZ`>QJXtfmzHNW0Q!nlqX=(Tgbs*;*!r zWn)q7v+f~~53AfR(42vupt}_9GM$mc2CDPmp-hRv_eBV!OhSsfUiTWz~`~l$_v;(@FZ+5ux6peI{2aGh zbJJu&lolA%7SB zYtq^U29NXX!+#skz3^u|8p~s(h1(Ljw|KFj>hnNj!&_+k?Ah?1rOyU-%xe)>y#0fu z`FJ86ksfdGgg(xPR{Q<@Ep6$3V!xkly!-uZV(t6=9K~~GKfguZ5bZRx&dhlR(5<)dDC2-&HVas_%Z#RS1(>6yq=JM zumldGfj%5g=UMRVg$4MhIsKJj0UVkgjXzoVjo#a|-YzO|KvqqHx~srl;jqRj92Q*6 z7=*{*kmkNscgIst5kB6%5u~ZS?j_J#<+<=IFp#ZdBlYhjmZG`So=N2J&Cq%Bif%fw z+2E^u#|wEM1CO4Nk9IDkucAwf-80o!(H3Z&509fryG;85Jb0YJyN?%_^X$XpQl87; z;o)$G^l&1y5>#&zl635_mqT{+WDc+=k|^p}tCc`n9C_>sRe) z4Xd3ONS|3(gu{B?eK?FSfx`tnOU~%U3l9!IAzd+>QSAFVTls-baDcj@eRusR=xoqg z;gL>!8^+g==I@;Ds=zX6)?DUCbmk4#HgsrU7Tf`+M2AknUKLKPc3auIumiu0l`$2E zwmesdjJcIGU&ibtW~1{h>H?y7;cABQ!h z+Nq!J#bNc;=SKK(Ac5RfN|Wff;WhMo0X|FF7e@r0o(93XO>uaw@>}%oH@O^pU~vx$ zQVwgbjkE#GyW|k@ho7vWkN6hf3VqwoxVAG6@c{9_P~x0i?MJ_yzio{8(}nqvp{MhL zm3vSY8{B}u_4-5>xGC`g_?3L{y)+d*c`i6})#f;nH-O&H0eeAfz$uM^%u|RYh zUSB+WQT{1o!$wvqw%7MrETSV5Rqy}D-rImjRbBi4XEGC#12Ifs0wF{hAef*@jEWi+ zH7Y79>L8%BfJq<$A|Z)MP*BteK~X`YqT*YPEp2_Fy=k?rRol{*wzS3jqrJA$*4qMc zDn)Fu*H+rn^8bAIJ|{C7BSPEfe}BK{G0!tOd#$tf+uCcdwf5^tnR~t5q}g|0%f+n0 znD28UXG|y3S6Nd{=`XVJ1CW)huDKVJFmsV zJM3AAvXng~*}T`D66QSz+C3#5>?!F;i#o^j%rUrQ`kaYq1!wk@>|jqxVBDcI5$DpTVXxi#lP&1-bxu;fRUf0>G7N7I-CmVPK-QOw;{m zvOgo$7wMbQhXK|H9eBQgHFUpD=#rs7r0t|rG;S>wJ$*P5-4xgNr+vCVBL}Lx_M4=B z%i=$Y|4rgvZt{xln!(wn3TSm#nlBH(BEHTxB-@H}h{MROryE((nCbI8gUB9d-O({! zJLf*kc#pXPGiFL2Be&ZjpKT>)1iF|xo72`_KWpg z#(BV4H~TiKpNOy1w|uL${(M!>mIK~b6Xl`Y$xwxc;;+kY{a;yoBTIotK`r9nY8jkq8`H3FNkuUm;YUHny`or&b`qw_j_)+FE zxI1SR^9TI4vl+o*exVcmE6gt}{R(OG zd$Y~%$$y2)&F0tk9|5QEnSfLIESY>U;H=}fn@;cw^UCY4=bOe2cKvDj7swM_lzIK_ z&oM8zk-7cP+WC&^`^_#N#hujHMqnc&U0plZiU!|J^C8yX zTp3S;R`T#L?-mo*nPmB&zJIU?9TY-dLrJ)b<|pFpq51&+B5>M+EqT+L^FZ_y^9ehd zPuMY;@NXZI>|5Q)TCi{1^$n3n!;W;De8hyEo13KnzDpn0S-@19PUJZl?b_KM)wp8z z&M*HBy@UPK8I%cQM&bKuZe{k)jo`JW>(_O2QrhgV`as%+@WR)yi8}MOTJU+?S zpZg(vcwG6D_ofG}zWB=D4nBJ=@#JT|?BSjVR|n3Y|CEiH4i93;;)~EMqMn-n6kfRJ z6|bH1*x+?W>eIw6bk@Zm^U5RMGF55Yh5FjDruI3lh+j^fWxGp~_&Nl>-kHRU8~nIt zjB4XmD&7wEMMjxB6V->zyiH}-PVF&N+dN46CqXBfdJI_hK0v9@+m z^!H}w$>6!__&?&4Cp*6&uOIS#X5}T_AiYp>iuwTKK*mi29q`!1Q?wq4UT?wAXoU~* zOLQlI_CTYOAJupCLew#NZ)o$lQSs*QDXn{Vw2@|8E_~T^?+$0j{d_C(iFiBjb+3i; z5uZet<*XtN(qWFE*jceFv}tWTJxUpNtc^R>l&_lkxi3?eSZr5CY;F2y*pD#9oYQ+S zu6Nc~APx4MF~5jEp*dRLZ@epB3vGY?2KBID`!l^ zd-SN<=Znaj_?OYeclCgal@9!sfBGzGu`{CQ66|s^&6jB30a1I-WRSyIR<(a8`%(Db zwdm4FU-IIQt)3MHY(nI>?mW$#V^g@hsv#QR=_x#Z(r|<>$^>~)n~EK*BQcnq_gi-n+|8~_UtE|+U756&5SYSB-;G^ls4a&CcUCI?>pAe_X70Y zWX&N+p0b?VxKE#RM`_M+@@unb+ceG-^^ubzAaO;1cxvx8cWD(%VWtfv|iyJ3pYhYi(o)_~f;by_97y^pa8WTXMPqUcQGs zI29k{*&^`_KD+Sj8F&_jCc4GOH?mJ(+7{iqb6eoste5HTsaSwH^Zd+i-S0B1=TAmv zegF6F_)OwUK8$Zo+;Q^B@V#!spG@_Kjon~>x#<0MH)PlNbCSh(RkrTfuFnxydR}V_ zY9s0CiPZfL@SDjm6n+?4xZSM3sEika-ws~-Oz_VrV;XrJSZC`hS+8_hkAZF?Z9Jf+ zeTT+rS>^4yS*OEK<}y_NiOgxMZ%bb%-!BvHz8$%^J-*s}sYVL36$TC z+s>SM`AU+T*7IG{HisT3i=XoOCG(6$^VP>SMiKw-^JGI~lPT1%@JFNKh54i61v}^$ zo2+b=pD`+4ejGeQ|An1VQ75}$+5PAkWGpD`@nZa(VPiwtj zu`S<%hxjG*Giw*M&h6Wm`RLH6;oUj#F5q%IY_>0b}T)z>t( z&SE`5eQIX6^^Ja;l>Y+ieI)Zd(kW_Z*-VW|>9g?g?)b5kBlRpT_ciP(Q@xQ9e8QJx zt4;;Ch4QA#(m2TydT}bUbStv78=Bo)Q}p8KzIst-JM)^Q7q9Ng(OkBf|I=K+9r5T{ zql_LgeFDAs8&7vg4~2SZeY^i5`>d&_#=6E%t9|#t%kmitaXxS zC@h&t=*F*r-vHj%jcvr2Zu|;usrpJLCQ_!Cq1ytTbffLZvzW)?ew*(0T%+gk)%@{Q zxY_E%NuC{7zfnG>9S=hvN|zsw?wo$isQC1=)gQWgW|oa24&Uvf?nl}W&Ajnpl*`wP zdzmxZOunfy^7u=ZXP;yZ`FM2aoBhx{;L%KlW{k#3=X@}oyF`ObGJo(A^Wpi0qtLU^ z*|`sVCg}zG&tCIAyjYLg=Un*f>*^Btek8nphyHsOep^RBWm%xIL}R;(C`&G~k*q_H z^7@3@cO?05I>D2#&Iipm&gX*r+5MI$zI`?R;79Pf_RJ?uAC{aMIiP=N?D%YwJRS7p z{G;aS3s}cgp2pWi56b39Ps--X#$~eJ7{vZO;+0c%DW}}Kf5aWC`TRJKu65`@J7el* zY;Dqdbf#>pS&O)hwTKvJo@8@%Mq^q}pt~z)1nC@3eXY%%Wo&LfzSPozPsW#$xAeT) zy!j0Fw@?me6Kj&R{X*WWKDHlPd%85qo~nMwNj9*h6R`t3(Ba?vi|hb*@fqE?a+lSM ztKx5BUkgb8Nc8g;_y(JFgLq}`pk`hs~*t-BBNUxN0@zc3%i^F7LuK^h_K%4*_sD@D&TwTY+Ss=R)qJfEXJ2dPgK`!Czo zltecpiSAkG{sf);cG;v1=(F$}<=d{1>gT6P2l#7W*xJO{^h4IZjLl2fvDM_8 zde_}b>g(IF{a;VWR*1aTv*t(vw7;zsd}>7 zvkU4g=aSap*wRUqQ)6GP!B~C7z1r+O@bzQ{>3o!~olF{v8$=gQLT(Nx&XlA$lMgeF z@_^^@7mypjpB+wKmJhak(*1`M$J$XFN4z+kIQuzAt~o5V%LJ{@BDWKp*Tx_CDslmD zennp$3qN0Do$)o+8KujAg{-Kr&!g?|e|A+OPwZjXrTN4kf6c~wBi8kNE;71-c)F*$ z*9K@Dh5p#hH}s?nhLN`9F9W?YUb@=&{eB-@<$brq-lzWGvBdeQ7-ijF`0CC{$iYEu zZ3Xh3JohZwK*%++i}Zw@>xkfdfvuUeeYJD|A*(zJb%pdD4wtK9K=)pjLTE{ZS~0?t>6CQ zeRE9xFk#*_w;gm)Du7m7T z8!y@Sd=kl;=3LW}|9bF;lZSMQbi&Wz)oysD=Wlt=_R`P!5Lup@lKw}@@=r;38|mu# zpFHnTyU}M~VITERz|8`;m%Yr^HcZ<&fV#+Dy?bw>e$WNK_5Q(u8|Z^sH$C}I+M>>P zE?V@$@56t6_xF!7&ea;U^oDJd+vATw_YKniGHJiUvzsTYaQyB2R{2w`)3Jt^ye^mZ zsetqJLaJcQNS`%nZ#vvhyvi@brK4T-+9KymBZ$AIUx6w|acO z_Xzpy=h1dQ@(o|3Y+}yi+0Ab+mmaKv|J%9fQR~-lT#d%5p&OOkZwlJ}c3b=yboT!Z zXI`G+n|2QUl)YFTHbLJ)2qs_xcjYVf1 z>6w>v^sOswOn+xyTD`jc55C0b(6|1YZ}OR!GpS4JnU_<+Y2EDKapt9r`svKe64Knl zCDm`B8a5!a>yX((bZqB6>=jvS_kd)vA+h5c_IS+ZTnmGe$yf0WLUi`i=#ho|HgX7H z0`D4T@SP{{8>X^f1-gB+h{x~WBH!j5mtB{tzz?YyB7KdHXFOfb`7P;fqmQu%W-P|s zM*;I3A=VG1pWjt`{4dJ)PvLX2d@u53phf=VVaoSc*B)BF7fL>mxxG3r!OHh0ZUzpZy-N3oM@u4E4ua=w|(xD%iYgL`2n^35Hn z4rjU|mvQ&TS)84zymyDbZx-ydXBLe=!v2#2e8wn0osZJF#b=rG*V(-Q&#Y$Fz+(5s zw->OVd!qGCj4y)h`g6E1{1X1O$9C!dHu)tlaQ~>aBdgex^zd#wFLek0Aa@$$ix)$; z4jLbx#~kD8BzTzCVwvOe&rji#4eUKX)%|d~)&jl_|7H@W&py5`>cu`Nn!CeOoJ&rBVcGALmD*Y`VLFEAHuzVAT! z1~PAVG4Lpp<-r+HGY@#^yXyal-Pm^G&q!-p4{M;@`S-dBUrsoaG&Gl}a^+B$Eb5XK zW^NIle%M|0%qOrv`)Azw_d5F<1Fbxe17fE zwPS^8X51^;Ow3KNcdU0`&h7DXBfEX?Ek0g*`Kup{M=4K~a%etKbyNO2GaLrzpXbmS znM}&5cPh8+-Wl|{{mcRHXD(Q{8;GxZ{Ze)>*43l$Rp`#ObYxsIN89z@gS3u$-Oa?^ zOx$3ly${{Q=e(lQusWtA{sZIF%;?EbJG9eBQtpn6n|0H^-vZcy4)*UnSH1zpt{c}# zKQLC~yG?&*J|e42ciMikhx@t*O0Q&g>rCW|T~73_xb|_{F!LhlDy`{jZ<`ZE&%sCW zSaa)UKV{hN<=yrbtA7$aC!K25Tk_L)@4eRP1|uVbn!9%LO>)M%oc~t&NK5))$_s{n z=3DU%oHYq_uX}5dmFM2?rm!~5{jpc?#LpP&e>bH7oaWRt9v9EEOr7nSl>*W!(3zEH z@tW_jG@rl2KLaS8%6wc-AbLk|5aG0L!rfXYn$`1&WQ;Lsf(I+(t5qj(LGno4Ep>Iz z3eK!7!>>r~TNfD~^wpc^N%qhQ>XYoVr|%Gs*|D#0UtWPXI&+={uVk}=JayijZ*QBu z^!MJ)-BZjl8=FO&1gX0@Z{BYAYn`k5)A#i4Z|$Y$?x=yYp;z0b#yQoajY4~_`meW_ z{&?<})!qwz^P79_d&_*E${eH2MvrLTY*oBdZJDB1M!~Gj7e_M+@jn~zaFnptn*p2V9-mm&9_RGaln za8b_GY$L5o^R0kYoT*urrh8g{XmGlx^$xx>az~ox(P$+2Kdq;`pL<$wWj>PqO+B07 z#{+3;I~r({#CJvx=bXsZJzu3guc!Pv+xCcleA9Nm$vmfj-r!B@kb2%gdyszxO@HSNeg)oryyPjI{kMf}FO?l?(dvwsKUSB5c0UfKBmz`)muJKKX_Q(2hf4h>ZwNPM&J?{^)1 zTl<`SxxTZX{uCm8zYO>*>_=CB^XIJFLX{U5|}cS+s|h{dT6kD;P@^uy!-ybGCl0Cp>!; zaRx-OW1dW$Dc)4`%}de@k&fn=<g(mK~m`J`8p;!O#eS{N9>rc$%7c+M% zo%U^yho{rtmyv#ueEo9*`#IC%pA*oxtF50kd*>g)9|NtvU$L9H&}2DUM0#iPu9~N0 zJu}7{eS6o=Z<1%`wRQ})_b%pmnOE2v=zB+6Eyi4DVH(!hvoOhX%*$`*Ov)9 zn>y^cZ7YkPlbCbpV!Re*;wtkp<|UY$*fNFj9M2Ns?IqshJYRuUbRERqd>eNwoo~;+ zZ05QC7Ut@14LI$~nRmX_ak|eXJ<>WrcsakPfeR_$a-L?aN4+YmJL3m#w>l_`v7Wwb zp}SY-Ay=}KtFW_@5%Dn6wT^GkafdkPx^%yEUiG?oK{wyKK<0`$`;dc;6CKBT@;7R| z*U_F-`yF?U<z?t%56evY-E#8Y4(=%C_jMJ9SU}YV`KoCY{)>bn4M5yQ(tKR@$TNA|G4K zd;H_xamI)21H_MfhWbpxe){#_OrO=a(irde4AA#4s&B`KO6c}1=8+E5FQ6 z%45a^E8!0^Z^C?Qk~|Xru>B5$?oN<=n>>)|27Chfqtb(t4b2(q{TcFAB=i0FH>N%N z@vCoEc^F3}_}u^ZDRyIjc3^)@Uk+0*uRo*3a+Xm)-Pu&vsYx+{R1(ARcmG~c_U27btPt~B+P9Pa zeU;_e&Vgzd^ii_yOecNmsD0>U-)`y~FGfd`PJcGD0GpZDj=jWY7Gf)lyX-e5{$H_~ zzlRTz_I2_1u$vk;+wV5QTf<-bE%~?9R-6&D`dHs$mCalq-w$3k^9*d}i^gU?jLq!( zy#k|Sy*(km>^jaP@%QdPMw4u2yS@|OnPM}e=<%){_`%YP)}Jx@5`Aub8TuRJ7|O;t zWHs@Pe-q>E0N?J)#fR>sJhYq2TaJu~?tSHJ==$D&V9V*<%j5YO(ou{#^ItP|l<#@L zlW)-0uFE5&x1IN)S6Y#i(F zslBE%o}D5eg1#RJ`|`UWk6xJw~^hvi6nh8&y9~uF3D8va_Ao+0GO@ zyMXWeR*<*!*$nLLz!O*OkRG$&bfG*+`s_!Py^b=<&T3uxQOP!IN7qtbmCd)a3srvX ztY~~Yt2@rFFny5wwXt>kjh#*OmqpaCg!ekXu0GDW9_;Mu54E$E&@J%zW$dic7v~{Y zn#Wz;YiA!*p785Z=+`rzT~EI28OKU?{V}ZM^;Xfr`!W6S{%FdkHdKC3kdEjE(&oUy zF6uJSd&ivN9<{w>X`0fL?4dKXA57l`@V{Fln=ScC$nc8zZ;%~x78D!3Sm{vaJ9sKj zJ(Z_DkK0!+YAW8i!lP3=#T@7JdHwd)<%Tf1Iy8tb6vG9pW3e2i@m^E=$V zSfBZ?|Nr)4eM@sHv47uQEPqW~-w1YMN4^)Uq7nWzv!{YZx7|G3uH(nPi!F-+PW3*! zN9e_q`3B5cN46JhF+Ba>+>2Fr7<~5kNiEkrQuzaK1uNC>w2rZYHJ+96h2R&m|4x0p zE-byu`uP#^+0R33{Y&BNx=WeU;aLo?tFH|>4*W0vv*mM)N!0dRO8RiTbW1X>YLhlZGg(>W3Zgy&pL<_Heuwn^sF1v8g@&+Ga6po6|L(#dhmH=C~c{1`DeZv>sw*!4;&gD>U)>fGxf0#08{VFks!C0=BrpU}+ zYy6#f{~Yi2O(d=9sBKT>sda1iTABNlU+>^s+}I@3zW9Lhb&~H>zH=32pY zFG~WJN9sefJpQ2X_tX*x@!zBV^&U@uu3qKKL#`#`pQ4U$@GkkDy%T6!1cRf${_66Oh?|#9Dt@s48vASz{19Qca-PAd2-PxRc|3C-ncR-)q_8sux zR?_(~<%nHk=a4JVnVT0U>{C}gd(alr-@%p8&kroH^TYc}*vnJFy-F~75_YQu;pkvM zGKKhA{IoAK^91f;I-Pwyb==p)1mA(GgR_<#7mRW;`{G~eqy z^j2l(!|d5$?7_HD<4T>aPNPjqz-3i3ZwpTg`9=AK@Xy_M@9n&OfU}47<~>YF@7cod zC;SdlKgBQU)|j?~?<1=ZUfEOLi7!vwA9Id;I(I0ip;yEk-SZ;9`UbTPye=f)??V&D z7Y{qk)8R`b=BK=SMLqw*_ZgI*%I1H+>k`)V-#c61?|STa!SaXDPmGJex%6Y6zszC{ z%blvbESMYaymOc4o{M7|cdd#?DNi(}`9aPB86Bd2b^b2t5zYNtU6DAe5sj^juOTm| zo%=)D;Z5{G+FW^FiLZ<-ntPoe#5cdPr-HEd#)QKUT7HJfGs$*1j7O{;xh*cfXkJ?7 z&^XVZgZ9f|by}hv1)?`P3w=$T0*%qdlYZi+)}a7iZ#{}SZ0hRSax`mAnjFb9$oh_wf`M=20n70g1<+;8SFVm(*$EPy`? zOEunx2VPrf-RzINv-h@6-FXq`z9(p&6CRb)_WnJs#}Q7aPop<_{5e+1hwz1zGl&cs zTY!DK={e*F+jKnl>J~ca?v%My!!L0DU03EjMGU!#t&NvbmhJ2d6Az`69qif^E{QkV*;M-~R*-GvMIH3F$RM|;$KYd<%a0YfG ztHwXOE54uoUHgAz^|F7jOE~sK@7*rW4)(H9Ug?Z9?sy55--BPr-54?HqE)ODt&JZY zviH8|J9XzEi*~(yCF=}##|yiq10FNq^45JWsq-A=&>LBXkCKt7WLffR>~})XoJ$?r zDXa3<9?N9CQbe3ccwJn5W6MU?C)-JjIx3xF@>l=2W46A!>kRP)zMHdJ<(&66W$!z# zD}v@l_GG=t9xeMVa&(#3Z&^diX{PR~uj&?vQfKbAR~a)YqpzC^ynLj89%1aRwwM@2 zPRUz#p`zW|hKh35;D|SoXC?0|dCFeMhWqw{&P7|!^mK9GvRXaXcaN6w+sM!Ay^ppX z`cAdVcewOVv%gGzSv(0--elQNZA0!e!|zP!=&QsFj|ctP#<%d#=#xEj)F%!>$7i7O zXG6yl@E+M8-NBNndSF}B_WnL6n}+Rs6R-!7>W5k1d>B1&2YT!d#sPQqS>N>AFV(ha z4~ON?zju8zL>;9AG(S~B`6bWV%Ou-*334{UTk}K*?M#zCrf!@Ad^Sei_5E1EhhrN} z|2j-s^$lCszI$M-to6O4DS8BDP+zy{e)Qg@YSzuG2Rs?qccP6w!vB2?Uo@NcmJf3p zd&eeee_ADWIc2X-f92Ho`>tF8|I9qJ+PrJ$uQg7JaSs9hn)-6`w*#f)WglK<-%h)U z$N5Ue0Na>5Pg9=g9_hz7uuXG#k38Zvu{@uP5925x}*|lXH%L_>^sbmFr4tx6;RBlM9Xgk>7M4KAPs> zZo@xiyeD6ZdinNV@}fM=J$vY@AbYgT-gV=jY3`KoJjg$z%=$)#-bKUcv>oV>9oT>! zD+rUO31d^CNz9|!vzz|67K|SjMn;LBM}70?d%d!1c;c7UJM#%HQBM3%Qzz-^7-?v| z#XEof5pngcZRz4D^f7EQC$!8y7^nSy=9*_>Z)OhtE$aii^G|*Kee{Ut>ZD)glWC1f zJ}doyVDdUh0qM#X8~qS{AQxLYgt?Af!%O+aNw^R7kCN?lIX1gowt8C6tF)oo?QfDB z@e0|J&a6NW=)J!65%R*Fg#9@K$${>_mw&S5HY*$2V<{T#Ln&u2qIeVhz?aiFLuJ;HHb9Lroea9DBq6@qVPo_*gm-V?6Q&m*-81-t4#k{o=Pz z9eg`jZu`O?XhZ3Z?&zp^s!fsn^`KvTo1%XCGd#;^S46Gej9PvD+`prg;1tC4K(S@Q*$% z-7fw$pESzwQ2C0F^0CvzM<2jSr`-(F4l87 z@xQ`7#6Kl1`TGBHEA-&mpY^Ql%X8qBzU+-?`Bnn5Jk6w~zHlzKQG1~^M|u_SmlN($ z8l?X!@_m3Z>0Xu@UOCLXdsyRvsXelx|7GstwhzD~z~roUVLzM62~F;O}^()l0t zA@yhD6eRn$~LP$6R8hliXPps`~~X8cPI7;e;jz(?s>rS(==w#y3&oN?y+4D6E=PBBXqU& zJUYRQ2lQ=k)k}W1@5{>nVtvW@aFPKZFFm^kyl_4*YVZTqc1w}{RJ+2sBX<|=oN8Az z9(jX0WWp!a=LEu%gUPB#cWf7H68MRa8DG`kE09U~t|f2HX*iubdff7rJ8p;9@|7le zzTFj+VasWw`uKL{&INPlF!!_OjnY`n%+X$8<)tS~-qQ)^!|Nz?>MLrO8PLghdik+~ zZ*S$DQ`vPPD52f!6_*Rgo=U!Gikmv<99+%w>YQ&-8rDB47Q?jM?OqRIv!@SFCemLGegztV4U+rmh zHu~3JuYUN)@Cn_`5qISH;rJS8rE^w)=gIi$G5jct;zgPnpEIr!&lJ~RgVwsE=(A$H zXZ_jiwMH)+pOi9cZCCf)JN!cBmM_!gBe4#_k{fw`^d5hIomu@`^Ilqyk80lQj&JN% z{r57?kZlUG&MrB^t^Va3;NHl2(#VKpO?4Q<+Ozh)Yyq!t^$I7OxPW$g1^5+jE%g%k zt$Jk`+tk&=URcv!S~Gr}bRYN9Rr~;H@0L7iyj4m4j6c3QzMS-yr=<5k^xIThCz<*_ zedybyq4qo8Yrlwi1N;NtX+PS@Hy?bvoV-o@;ll;P-g=)*rum7WmjoYrr&^HQ_lPx@lwnDl4#0fyLu>Nz`10X^t^a{IrtZjw_`MonO3uR zCd^o9BENFRM_HE!oPtZZ8|ux22lp~2+MCBWZ(26!m75WMRkq!H`cXOwbb!#oxV8d`kIC%pq(Wx z_0E#U)+No&O)YJ8wbA)Y8t1juH#PFA558_`b4y)ot9jGbwyarkO%8f4Y-z$aI&F1J z5n;!vs%ooiZL6wMxUFV^)7sWjSF_l0T3hCw(6DrI!wFS&4Rwp_8rxK+vSyAE@UFR` zUXfet7c|ziEm4u3*1E=8^A7TPZA~qSF!x#%&AO&&&T&P{$IQBB%$(!KEI;FnzWf1 zuV=T;Iez@|*{#T_bJMuio5!^}4i#R~K%rC^YTsPbQdia5R?|{8v7u>RO+)M1Wv!-U zDp&IRK5$*b{6o_7KAE0$YU}6KwAJ+!$^w!_Jx8<5&zcf0oCED237MhguP~TWrMT@kx&}egO<}DJgu0~2>UQMHfY)NZfv}SH= zQv;G#EdR)Ykw!=Pp5*t5onRwNVW^CL!8>&HJY#8K+|=oxmQPvNC>zD+Ti_EgoOWLr;e-J5K3YMNSz%DM$9hIh8_~C+~O)C>kS-?iMgZB2NkESz?RwG-}T2=Kya>TjKPZT~>RV})~EAdB?S5+N~vTaFoLtSsm zzP&4gA>>GDYFd_|pO%@PLOpAdAW!d5Ek6`M&Nw>;-=aq$a|F$N+M88$w2-5X#Y{7^{u9emp3)moiQ-VUt7zvGolyy z=|<0rR@pSmdU1xVZt1+b=C){G!8n5s)7om^H?-CzrBl{Yx1hciNh|KZ9ODNj6|rw^ zKctA~`z%Q+VlVCpir5?HgGKCHj`4Vm=bPq;T8>2L*PvT!CBJn3c?*5?4fSZwc?fvZ z;;852pj(RC5O&O$+E(0-8sEtZ|Fsa8$|sQT)Z3=CTW>g8(}4F=y9^6fH&2qVAn6^> zP7{hg(P|eg#R!ZmJE^?9wRn8At!5D_y^&tlvS5kSSZlO++>K;Ze|=r!_*A;Or8V=~ z8kR*>L_b0w`txdPqxdZi(fJKE3yi6#s){XJT6O-i3q7x|>U>_8MK8Nx`sAuBrc65b z%8RDiMvOKzH7=-YiS{~*qp9Nu%ZYxyp{b>|H~Ut6$hpS$FRr6I)J9E|X;iJTuC5l- z)YwZ(dK2d@^Sf4b+>B^VTXbAAYe>C)sl4i>)2mKC)tR;s3soESnp6#C)1^wbPt=&! z>+RzoPQS3GHQKhYE_y=?)r+>`EtjYpMO*5u{ZVU4pCbMkRQ^ZjEv$hNXoWW8jzmj| zPp+O^AuX_F~~@nnuI`aD$S&Xw#8t#Vl1Rt$%ejf;zM?{oyE58JK^khKh7>_q($YxN zQsv%co90K)!^673Pu+T23dO zAxhOFj0o4!`5lN(DR1pfR-H$>$@efksj>2G06%BUF&5DH!j~B{7cEM5r;Fe#y1>(u zbL;BJ-Z-RnwPn#O>q_ez>)Yz_id&5^`-%3dBDq`6xZ1LD%E0p*+v*q7khm~v=y9!4 z80&RWDsdv(wJ2KKWOOS%!kB=TC5Q_Uh-? z)AIetSWsUzzs1v87b?(CqR_yXMx#IpFRQO>sGZ-^WX1uuucIT?xvb+&UUQd4iws#* zbVVhJ-b?&>O|^AN^8t;u#q|2|(bBW6X)XftWVg3sB?E0o#ndcqi<*?l#oBHZgXxsf zK5n!G$@HOOY|5+>NN1I_&7CvH=Ov=f+LgoB`n3rJ% z@nc%&H8pF7rez5=Jn@t&wU5TGhetoby51?{!Nbq*WN}|363u>i^oeFaJo*!R z%jQq59bUYu)EQr=-#HwqUw@vezXs~Xd6PmuoXjX6Cyk>v?S&Z^CBuFNQcLF9QQ!Bk zYHF#n!v!KU2w;}S&b1L<+(fX~FSX;Nab*?EQ!p%QZfeC*U5RP!}X- zw)%gknJ(WKPVuPZC&53>8>ycC$L|lH;JVbcKMy&-rB2>wOT8R494MR=rc3LXjhiR? zScj{Qqsk=wf<_GnF$_^&p`&F-jq+oD%?<*cUWd*zwv17j=5Jt*(0YF#ENj2BVZI7= zisVR7XQum0uDFOylN@XgU7>S%hTU+j;f zb2MhB2O@-RjDk&1@?eJiAUyb2u{PgsOrL zN2{C=zkGg~z--|&@Spy1uqlto>A+iAtLA<}XCg2`=d1i1#FK4*PLQ8d9dy`2=rjXF zc(N7HVf&vmoAo+{-y3F*QaKBWFcg?Qyv{!k9&CC6{6U_I%Qan1E7(lRe&MD!Rp`U~ z3sYwQZ#(t-`1k)F5B&D~zxlavu9Y+7)% z#7BH=;<@|5MA#3#vCa=AJuB5qIiJX;)`EvDUVY8~TX%ENY2df-rbK^mJUX`M{!@R+ z-7v}pAd|gRHh<}#O3p+Ic=hPMK9NS$3pRY6^O%&snqN4%9tqMT4sGRf;t8vQ&SowG zIN6U)#Wt=CIxm15+>7Jeb>N-`C*5ZL0({>9+~eTfBwRPRHQ=(7a9!Zq!AZ}WKjLlx z*OroAIb~@EC!J^MIFrgJh#J84@|!>jbPK`twkEh@aJ4CM3&B;V;G*DWr^GD)Hyxbx zxu0(yxL8Wut(0X-9~|drp_>fON+7W*OBmdw6kHc^EBnO7?m#y&g)S4^1aQe^34tq5 ziR*wXNx@C(2s*_nxar^u!6oym7F;w1*9NX2CGG@pc`3L9;KJY%<>OnNwB`PZX$~gJ z{?Wesq1y(IyXAUu%fW2{myv{%kTF;;@s%?F1)VYyP0y2W~ky z*-al;a4T|^LYDT5yT7@SP3HGCPHCKV_K=Zb(wx4d5n$OUP-!X(w(a zxCEc+GtgClOXk%MaOL2V>#-MH9ymS@NH3fccPY3`aLM)P0C(WbzI`wT?mckH zbi1kVK5z*+<@`9fH^C+Ieh0Yi;FA0KMAF*^F1gIxDD&gsCM1>l6>zJ;CE5eu1>90_ z@~zAtb$b(BEw}_v@sG%(8eB5}-k>Zq!6oOr9o*zT>2cpXxC(IcxojSMw}tddz$NRZ zZO}zia9hFUflF?qNyLqSOXk%U=(1AiBH;FOQB$HG-2X}3z2K7b-3;BE;F9aH9=h!* zbO+$eR&dF@k3zQ@Typs~k=~0bajT*02A7=2Qs_2JgVE)ie#n2U`&~1S3Kt*4={m|_Pmn`=i;qyLl$-L?! z?(RM~bRu+Xz;%^gF1dXxz}13FZnww918~W5^&)vx zf=iZzTH;oKOD=O3xC!8r<*%Leioqq9Wj(kkxa6{|A#NVHBXLEdcilxMckjrp!-+OO`)ByW}TX_x`QE zEX|qZL9yTWqK`aKX-m9s=aENEjuD=hT)N~p9}Fi`#;Awy%f0f>2Wbx*e2Bp z)Mee=*+E%8!+e9uQ_^Wg+u zJ$CQ-aFWA$^LR}%mk%8yneqkd;mcL#zo8y`cRJ2Ce*f%W^q;Ip2lepfYWD7bHh1EA z?Q!5=l&cNZ$y`2kd6FroQ;(=e9)0W3@ecXctH;6}hot(*myv(69(mNmALqXr|Hy1U zoWSoNzrptY`oqaS>dl&}WG)|?I+=3!rHS@<`prYfJLFrh9?kzk9hCloYm!TM$QRF8(9Ui6U%yn5{W7wggRPu62K_3-<7`+Y}V{N5N|Jq~=K7xPaA_HiHB;r=C4 z&P=Mu8}}Y=3jNS|^=SKIKktqJwdUEwCr++Magtm;eb3>i@c~M&9;58wCC`Zv_0!$14qyvlbK_mFd;F%tN>o0n}Cafo&O2+jz9B&qx%wY z2zbYz67YNY%q8DQz&kV+*pvjrtHL4+FP+Qyiuc?2(5yec-45IlO2AuzyAF73Wi-ep zVCRnsIJq7C_F76F{@-fGVf%0NQwPh0l;RX$>X`YtNwa-Q#>T7xwlTLp;TG~CtiSC% zE5NNmu6BF4OfE@$dZmpQ(S?a0@>jw;%~NPh=a;hroW_pD9&R%5QV&;=L`U!gf9=o} zyl&S3R}=2KAkBH>+cxbtfnygl&w~7E^f!}m>fai0-K?X$po8k(-}-)VUErFbYhU40 zS>B}L#GCeI@aVP#-A3XrO-f&HUQ~MUE1X2PxgXp%aMdYscl3kX3vNOR-GP2^naIKZ z8xv(yDAEru3T_>A)7ulY<^A9)!IeX|{?-It3|ujFdjpv{)L%7pYIo@gJ38;5x&gZN z@YI)=R4UCGYwk^R(V7p`pN~6SSn++@?Nig7>F;pYjF*w-6E%;bzvQs!Hgh?oPbYZx zOMT(@UhE66`C4DN@T+~{SMKi%XQ5a8^i%WRF(fgEnEWm|tTJu*{fDPf&LygT`c4uL zE;|4GGor;;*0eUyt!E!}McK(^<)x<{-_l%v;&=-==a#^a8ur@PJAp9-(@%8<49E<) zfq`j5LXkjjV0bVuFd~qjRuC8ycq|(5+Bg*0i36DRKTA*^=ZU2#ojj%n1KWp>CmalA zjG?VV3a5vHfy^PK9Xd^K(lWk!nISkDf?!}kgg0sJv`gB!;g%r%Pq;8?S;z3NsNj6! z3<#xj+S5r3w165vOo^tAIFo;6B@Zdd%=EvlBzc9?E*1WSGC5+w%#1wpNSlX;ns)9u z^ZKemgdZC5s$PfEoerWYoYoWL-@_xnqVS4y`1h@mHxSMUy)Vi@=17%a;moJz(@%mY zX5N+NIPR}0Uhw1$kvi^$^pxPKuEwk(_g8fQrx_sAePSv=g#ohM?@tFf-2h?tyyF4R zFhImz!P;%`OatV(PuBuWG(drS{FMM_86fIDdkR3M0Set=%Jf_V6uVWE0nRf(iMzW2 zVA8P9P|k99XB6PV$TI*F+~+7^aIz_Ng>TZM$pi{?b8;4{Rc5Z!lZQ|5b2i<)c`ts@I1nIW@iT#Q8JMI?!{p4GMMbP ziwNIs!#{0Da`Uq!8(Hr{cs@}EJ0ZTW<76Wo&VZ5mLS_F%bjKLFY}(uzFv{Y`UQZUK z*%GJh_eeLR%!I?^X@kJzK%VIaBN6w^kwfo-C}$fgz#Ww~_*qjn#mo7rP@^p>`-PG4 zs?a8Q(@Mf8*-RHtBYc_-*Iz>TOcPF%5+0N{6s9_9+4ROiBO)}8lNO{K4$6-pcuv}7 zX1Dl^JeJW0ryeeQ(fDm?wbK{ngK$vdj z?y}W+oumgpm7^}6eY!@22{YYWT> zH-uFe$JJeD;l(31Gv^<2h7KIePOI=I17X3D4mcH_6-fUpfD;)4Klx&Fj^rpS@(7(M zJSSjM2}jO!4Rnmsj6}xaP=#v(;R>F4k-_x6@Z7-QtAGk3#}S)3>zoxp(a6-%K(&FK zuL2cD-X?aqE|B|cN>LnHbsNxvK=vPaR}$F*ufvN1!`|dwdF1*_ff@pNdw?cHVszW^ z;=u5IKoyZ_J;uG`7#ULl)Dp;Sl~>Le5V@dX3L40kqa7uZVL>#cOdE@@}qG; z9f6}(l3#V?a+Vgts{=X5kV99spVzIa-wK0wZ<dMJvg0_QhXR8Kkb6hu zoi?C{14C*_b9E$k577F+kn4cfM7}x}=n-3%&d4!}_h=yd7T&FkjJyKqvB2Q30j-a` zb3V}HfursQdOY%u6hWJ zhJVe=ytzx}JK?VlI)!wdJdQs);TMe%hVmM?Z!P?F%X{~1Xu~fVAj^He8sHV962tD9 zD&sc{5OJ?pQ+#ufRAZjovk>50Im)KMy-MP~$pBIJLdog34N&O5dkesKObLo9yXus7 zpG5w<_!NYDQ262R4L(3PBa}AKtJz2bmI)>#zVP}@MR-bj>-*tSC^AAP^MAzoeTbd3 z!uz0jd+-&8Vg~;Wv+8@Ptk|UILbZ4B5<_*9PbF<(Gd4U+yJ8kp?+kv-P(9^Sz0^x( zQZ=Nxo#B1%m$DG+nNs9`3QI&Cx9CoQKN}$Ac3>33?;9Y~eFa}Eyx#y>?txB#zZf9w z<_`e)tI>@S_ZR9$e;b@bYI*MbI)DQPC~!C44DfdYMBVY@0sdk1TcKNq{}DcD-V{fQ zqzs&ZNxLMH124k?3zbKHu0EG$p$U<5lvU6|6_HES+93-~jC^k`Pz8z?Yg_L2RmPPvU}b(8YsUed;Fqy+3{ZJssMJv=#;XJH#6WN^@krt1fcp!j zFl;gC36@Vz41MX4Ssz|IH^cjK3KJsxQ z%}asK4CIZbP9f?l8#gf!{4H_9&&d%uClD?oT1Kdp|0Cqd3`Z1svEV}fRR+Qrn75be ztvnm66vI9E*Wn8TgXfvI_53$FLEet-?eeyV8#NQYy$;&Rf!uoy?SrC~#*jB+X{G<1 z@XxCGcX1$Bb|?I@T%Ah-gTHIy{7`X}n0%H*9Iq^Is4|xZ21}WTe{?GUrUY_j-oiI4 z=gR`QE>fEj8qEJ;Wi+I`6ff=owaVpz+~WPoLTtKoZing={m128?1yWV8>DL*s0AH(H{CUT_Jr$IX-kh|H? z{>Z2ObuXe^hi2JC^K>`p(4(?m zK9<7eaWSGZG&^f2K&DA&=wR!byPI&8hlY*HRHBcNPI!&HlIH_KIZT6|3s9Al?*#L^ zK>qJ}oij(>c#j7>bvwY@9&lX&z&$}rc8-{TuLqo^p1M9bOdeFu`EAsdB&k}IoETM}37_pVG<9<5|aL@pu$fI`yH~}-z%5+9fZ6tc+ zz+h1pESTp+0)dQH!bgv}2fDOC*0~g%Ix5xh4=)233 z=AMy0YzR5l(IIlr94e7#lzA<{L<5AJ+;HwW=@roAEh=|%D~IHWByZ7)PVTuToay97 zawnzFRw`eo+_@JFSJ+GCLX%3^$vO>G19&s08>~2!(>r_PTKuM6aTE=3bPcf<~{!Bg(xrL)qDknY)|fkv{k2O-462HEf_NYk(^8=iaz;iGK$#8HH^ zZTL$1)Ud%e{O3yuhi$k7y*n(&hX0CD8aBj+zfV&Q8*0PT+X)-jz{$Rlf(*;G`0nw9 zhuQGB<%EaZ@aG!{=h^VLaTA7*F@l&qkVYFm)`ZP$$7`6;!BmURJ-lMb4}r2ThA(*~ zmV7B4Ft5~v(=K0(#%>;xPRpi^Quw+de?cdweHNCCXvukpaDHgSkU;wKh~tdjwHoZm zfSITZr5)pp-iuc_;xrEt9O;andIgAy9wLzMjDCz1MpXKU5zgqf2=Ryud<2RiH*duE z+^r;UM%W_;2hz3{9ess>xq%@!0#L#*iDZOA=Kp?5pI`4HV|wF%=tV468G?EOu=yJ+Oqpt2uDn)82_C)1hz%=LtS zZo+BpO6`<9l{a*^lGMMA{7fPcKS|du7-(hrrF#hviK>9vQz?GIkP{WgybN}A5X}_y z=&%(jx0GS`(K$vSBCThSB*Rv%Z1}89j2aUSv60s{Lw$Uft5hP?*u9 zgVRA}S0L)63vC|1o=SL}3Fk(}40r$APj^gSQo3XE!+MeB9*wpdQ)If1jGl5ydk`Bi zrZ~7!Np}Q#h2)exIY*s6x?|2ma$nW0I0pwe;14vGE^>zErIJKVjVeru{V zHqT@222APLk)Bn56r(+MRJQB|!zwB~cJy#X$#bun2~ccGSwO)?flPak>C3U>gU1uj zKKcy8C)tACiuxUUvJF3vq8U5Eh9AYN9D9llw_QW{R2%NNp73cl9Q`EW3LCzd!WRy< z;j0u5+wibE3Fp}G7fG|wYv=dTkA+@44@O4Dd2RdXbi#uy{Vk~IV=u76`vZE+v6oqV z#yG;4+wkLbgk!I;;Vc>?C)Uze z_hDhq!XbK*>An#Is2?KX$#T1+0M{BI?7pfREHXfZax2HQ6W4%i2);`=d;aBIA?|T4 zighk3HZ{+jjMznrjt@WWXIxYgv~yBFp=d>=gTG)h{>Lc*W!b8BmU{zSFFN5Ul_Knn z(<39K_-RV4s604dQ69X2e?=3+Z<&PG^5QJxQ#$TWA{3o%+`kZg0J@@cg5Oe{(fpfG zbV>Mn#Lw+Pa~EA2c^;hOepC5R87v<-;y!Q!z-0!=bMsIjMVFhB6}UfW2e=|EW<}js zZvu!FD6vBK`$$>Q)UakXirwevxh2>O41xZsuilztuhevKj zajttN9mX_E@i4Dh(($&7hnp#+Om{BbqBze0S?+gmIf_RZAnfuX52rZa01@|PdPea` z1LV2Cxd))Y00r*YMF2+|AnIN)1>hJ16uM8<0E{v~u^SW+H9(2GD+ge-0m|Kl$YAjp z159wzCQzl~@xj&9JbMGGv)I!sD<=`2W5quYTT^_E3Fk(}XSvV#RUChmSH<620&pTNf|8yZoREO*t_0Fj|r zpC&c=QU^e;sb<7|iR8+L86eNS5wymI&GlK~1%SDD~e%mFyg02S_H_*Qnj0VcXb z={990CV@)#jQIei;W?CgQqj}2Ls^-zW)lKV?&{K`-9b?*Jp=ZZ9%G_A?zDPiF>x**s7Jg^X3AS7_tfOTm|KS$D?QDS zO?L-H08Tdv%yj8YPU#uu&20AyG-v5qCV^^q{8a#F8=%(Rej~tnCeA|ldBvGz;xxFk zkdM*}3|X@o&6QqgfHt>PmAl9QOWkT0V6p+0yR!sbY=Cz6yOQlGCg~1jSZ;LM>eInp z7L)|%7ME7L&rm5X~rc!|Z0UJ34kxb!Bk1S8Za z%WVnVSLmmuHyfbX-73!AVt^8NnxyA8!<}+BtrDPP;Hwm7f}5>E-Z|s zIP3yYan=~1(w(&wV66crxlc&4?=h)Ob`eFV^j-r@aW6;*xNm4qR7>%f2)O?kHP7~< z`#%A&&bCjWsN+1KhfQ*!K+!i(1zK;Q%s|o744_BzM^mJ%K+(A?fF8H*VxXuQ#a;SD z_8fQ@2^8I^G`mc^aC*`2M*%%$ph$XA<7}W$8z?WmXsbHrXR|aFSdd<{`yQarnRn6j zqK5l`o;Ds~aXK>g70Nrls;$-ODt#@iR&qCkDSh3vnAeuuZS%R8=kewjBmNFmrdx9% zz^^<7dcrb*H%xuQ?g2^ce;Xwgaldvhz;6tY>rUwa*lEb}+&RSnzcoOC`w0PW86fJ0 zE(Q4AkY(gk=nlt7mhLe?v3s-H?`>0;68EZU0DBEk?!LYd;133v;QlfbV4ndh+*`$s zcMUMn{Q+r~{(0EDJSyE2)XaY!9vo-d5Bpnsz>rOMA4Z#&{=*b!X5<_Jj$H?w9hr=O zQ5vvouGNw6V<1a|0Yh0E$+{INWGNR$u9K=dI*_Fa+lI&qwLr(%$?N9Gb6DBZsEyYa z`6Hf5=@=VtY2*)r#@ctwBjYaz8fV|NNB*WFA8VnG$TtT86AATDO_m|@StA=@w``_aJtNHQ}L+%Q3|J7p!WV-wRKdP<+yo#cWK1d)5 zkWlhSqlK2XdC3beA-z1(Xd=CLDIy?95dp=9jiO?&SU^P)R1~`c7MducfC4tGi2b(! z*8kkHlO4Ygzd3i#+_`h-&fVGBeVbVT``c3!I;l!>6MhBjs1BQI;)u+hC|u%-KjGY<#G*8o#Nl&j&ybj*fW_o&-3B z*=P}Spo{@;xnssV2KZx2&oUq>W-ZJ>8=|$3c>~S^ARngs8h?Tq40Vb4m_~;Q^M&*_ zc0BGcLd9a?nLLzBq`VJlB~&Km`w<pNd3zn3Pv6KzTTq8~=>t6(8Mp z7X}y=`8NK~J2N^7mI#6=@b@o>f%uq~KQQZ8VlASvrn@W}g*?+}Oh?Y~tt059I4Y73 zgyXtmvf}$m*RwIR@%^QIcMi&W=hwIe%6jKF9owpSz4I&Yh4Mh*_ea0+gQYwk0Tw?) z%8x9^RYJGTeq8kP^>+Lh z)6M~}SHw>EG47sWDBmvk#CIYri|&x}kBEt)yQKVKJj(Y-xg*K%mGV$5fugli&cuWk z-6!QYFzH1PNO|?;C_gCWP6(KybyEHfvs1KQ$}`}-qKBmXYipDrmhuM7cF`kJ#zxgw z^r)2gj6->&l=qYTaVh_ci*(T@DPM6V%A2Kp02i5}C#3uU+4-cDw__C*JtgH=$;D4g zd3pfltx~?}DwLm_N1uw`lJXDNp}bGZ*Q`MKZ7KH{iSj#AZnhHT{ZhUZ zE28LKDYu%A@&PHIUWM{|Qf`EcV$u6jo`*eN(LpI+JsagCQcfg)9+mP*vhy=3ckGSw zaVeLR{?DcSb`r{8NO=~;(w9FggTx()}K>93g#~>-@k0t=^8MKdCimX`bo&lVO!%E#V zfWiv^+%tdynA%eJ3}AgGKxbb0!I)090D1-xvjo|qG=pC~DT+CXrBIs5w6d5BiU6`0 zRK>(0C`%m%H8JCY00BOj=^gWT0zeMe^pE)xaZ}oZYX;)wP?pYun_VxKHmb9i*sz_g4IpU_`;!ahd zMMbv2|Kk>*kBZCKzUaw`xV%(c8-0z@a-C{vhMZHeB4rgSB4f_W0$9nj677o|%(~!B zUtA;nzhX_dwJaeeareWQl~EEq^QNM#m;I*)p)8mE7I3QXLy&o^^`9?tH#O{wL{b%- zN^(B#KjR^MON914KuGCK^0*8{dR03vwGF#W+GWf`>*NaBQ$_&TKI>I1d5Aj|1X-f^8bD#qY$Ci{?Ujo)YTDcgV$A% zX8{LxKu=C*1Y3A_1fMZFEs>eSdlXE?1unc-K>>yqeoMi8#6)92*%u!VEVq zQisciwiIf#FTU-$a9cPfGTN8tdZwLA4K0Dz_K{~%RkZ&M7Gt=BG;HBtg|G{E6ohAG z=L2;T9)NXSR~9;F|b&e-Ne8W zVP^Q^pTXj25w4Al-e*j!b4_EX*NYlB{Tl3zg5klD(F?JxB^-yiRCfB%$iY;lP9G)> z)#<|psnbUYQm2m;q)s1YIeoO{^fAIzr;oLqKCZ#(=Z-@hf|V5T5-`Yb`}^x1;c>E~NcpQBFq#lMe*ofKXY866I}{#ojFSb8D4xY+IR z5Oz-COWY3G&CA>lH&A-GR6F#=H%3B84X=od-eQ!lbd|ExS49q@Dh-|0u2PQe>s_V1 zUT;vP5;`|pqgdmPA}W&H6@M8ni>cvzBBL{rJ!G!$wYptvb$g%H?fq7_4_MtkXmz{J z?KYmCQUt@BBctCl9X?@o_@vw6BueK`xgGLMZgD&0Q9tc=$fJHnkOtRQ=^jgjGSRcr zy{_ozgsH*xyfAe|zaY$PU;I09Wat}_(X`bO&%9|Fy3;k3SN1MZs;gkPAYBD}1nDZ+ zD@YA}%QAGIW$4?&R72mf4Bc-Gy^!PoDB|B3ddxEPBiB&&;m4v>XzOqSc zY-I78R!;Mne&EL3itSzwo<~CHi*ew?oLB~tF_qY`=EO0;YXzIJP0MK+k%Bf+k+hF* zLCtA9!kdS9U*nk*!N`rEXGL)zP+NJhoiZ{!yJ^faH1~hM3>KW= z1KBIQSWv!y7q+?KB~5t;j=ccw#FjSY;g$IV)ceIv`7FE2Pp|KVFOj+$|4ml|EfX!h z{Xz2LrGonVzqtbFvZk$Rw=vL9j}ya}OWjaks|?&Ng|BEDK__ia93|E(nSlX_{N67^ET7_}|{ZSEjfEn+{o~%Wd5&SArMZ9>b?)4)vwSMJ}aticQB$N9sHk9mugUu z(0&G-p`9%PaD|im~j^RxT>cRk<74)ZE_Jn}ekCFSHisCmlv;V;a zZi#B*j2#2v)+o6FIXVE~Sq0Z1Fv8C%C{6@;UcsSr0A5hAh2sB30WJQ;I-Uy`a0+PZ zi=2qEbLCPnUW$sR3TE8oGVp8MD~Pe07%xY~Qw1}gaT&PlT2G8n6&SBX#Z!e-LEu%P zJEz+KY>R43ZJquL0JbZ*mS{T!u-0aX5w;9pj{B47?+*gwwWzjK;j9}A@VbH_a{=B^ z@E@wfZ>rW0aM%#usWmtC0@$TBUs8X&75qW8JwoHouW>t%^hGYB{^E$fH>xdFI1@?H zTOM1Vb?Fhl$cKqBix~T&+ERsc5rMZAl-2^gqoAI^e%0EhH^94UQCC_^2NdKIcuz+$ z_FRDX6|5Zva8PNFHU~JQsy9+(9ac~q3Gjh}Ievf-quSC8J0H?oKcY3aF9kTNVEK6f z$JDm>>H$7d@BuPn_+tgr76E*sV8w8NPX(|a_haesB;p)l8_Ld0l=(i3YD*Q)Ub6AH zf}dz*ey)msquBmJK_O*?FBJ?X8^6*vS6>V8wbm>e0q~8Ci#zXMp`ADJMV6uLT(Jg> z6H#rc!f8b#|5m|MlrT;zSWIi_I|b7&0r+0QdszTK2;eTBaJv}gi@cAt-b7jC$EbL! zaH6nm!#_pEbAO#K2l!b*2J%<<7X>Y`1rPsE!As)+eigu7v_WjL3!C{O8>8$zN8$8a zR6JEUv9wqCJu064d4C^(KUC3i>f)3vWanxMw9^VYQ5Rof#HvirwV5_U9H;+VEP1?jyG%1CPwoM!AOXXrwV6@4Z9Zwa` zi=zQLDoCSicP9l8QWvQLSWy5gfff1j8*r4JeMIjZ9Zwa`EA0Wg2w?hHm)_PF*`F9s zl54w0$5RC}mbr{1U*!43*fJB0Zqe~n!HoM|MuIQ$Mq=E39T?rCyPhcEI%V*Jzy zj6ifeRWO5I-DW$w`XcWj#%N04InnV{!Hm5wBjk&Gkr+$q8j>3wPZdsg%6UOgmuFmh z7hmMJ#5hV>Dla;oDx7_D0D45r#-|Y_`jCR%ivjW#Or-=^pr92cz@7@~X_^WZ+)X*C zNJ0D!0L2Qv!8I{lqM+&mfKml*DOSo9hpVgmgX zyu1RSzk(D}aF&8Tv~C6{*mya>*$Qq=02ruXbt1qZ1$j*X1}iu*3}A?Yo@WCLRd9qZ z3&RvVumE7Vf)WBF6ddmaFj7HR(l$y#Avtlhf&^+aM!|P9p0NrpqBt0*;4aG5;}vYA zK$@UnIi;zI3jU?kI!Qs~RDj6}k{Sb?qu{5p08923W_@d%vJF2On?g%Y@y5c zJOvZTiSrfYMguHR5WNs!p@J^tw+j`NT>`L3K?+^LE>bXrF1?EtEFwdfC`cX%uv9@7 zfr}NCkq<6Wu$B`3G6jQZM|Y`$p|s2{Q*Z@2{&EG&vjDD8aFBB9l?qPK%q>?irX|2t z3ex8TT&>{68v(9SF!54=YZaVo3viu+E?oguD2SwmzEZ)oRRF6LtV;q|t>7KnN?fmC zYkz0Cy|+X*R$;3g~l0;d>Rdq&906Y+3Pqf~Mqy4;ADN1vsMM4eIBpf)fOeDVR+G`;mf9 z7Xf^%U>((bqTm$@mroT;piKUmf;8H&9aqqkz~>5Xr11Yj!BtfArGf`&1%IWWDP@k0g-U=M-c6dWP&yMmT9C4VS5zYV}C1p{cLrxn~x?meU6DAE2@ za4*H^UkWl40sdAnn7}^@-Xhw+3XT!@Pr=p;0emsC+o+&GYNTKafyN51A`qeAb^?(K z$|=N}C|E;Rz@`e;5r|T-lR&hB!odJB3U&}^rr;$Cm*xr{r7K1Yw}wEhf;}{+aSA@B znwAQFBG5`fKT6)M6^tGQ(8g^;88%+QX>y2PLETD#whBfK0_Ym!r(f7O3%UYa+(JNA z9KcQmb!7n6aZ=ML5@5B0JX)tewUnCW699@@3D}hh@VJ6RKfoUfA}I5H+D2%L`vPRf z3&?K;FvTxm54G8>pdaOsb#0|)>BRtdCI~2{E%Dw&0slJ(AU#>YcnYx&DGc~`t7|Zo zywOd<{ShsPZ#%_a4w;ie`-PL8q*=xcfa>l7(kYG1OA}C#4RA}kfbS?~2WBv6@e{Pr zKh_?Flic!LsC~Zzl-`*`KBYdI(N(HXCLaPi8|nIWZ)RJ1`>zE(pw344Xk#Y}ZNpz> z4sH*bbJJXaueI6FRRFEBq}e&BrhleSdR*?Dpv*fmtKSf6{COB)RF?F4-D-d}+W3A{ z(?8R=DU5LPXq#{(tKW^(cyBGhQEfbxtdDb~XL`8%aYJM0!;z>Q?u>YwnpMzdXM`ht zE~fdoT$}j^;^-RxOrP|q*@>p$+~f3%M2%B@7QkL@d@Ti9<80}35US~)X}lChI45Wp z`)2nGQ{xZOeYjt?^!!aUz*22Y4@R$VXzW}~7opd)hcBaM!xjU)q0L^r0N@{O_9m+7 zpXrkx=sG)UK&cJ%+e(cGH36s#NT0dn;R^#|aN|LED-{1sU@lkp7v*^!U~JaR?}dIsJ1{<20`WD9VwZD`-W`&5@ojMm7C2jpo2Gmj`+a{GVHjk^Opt&Kl}OTwqLF+DH~Ay;Z+C#4>hmBGoJHXe5!z%gx1dG8UoF_^PP zp|We9|8~e)(2xDza4Q?*#7TP_YE=2Dj#;d5%2pmI&UesW7oV+KD( z2!GU@ADafdg69mSUDY?e+fXBi-c1Xi=$%0Cb@}p~D`;QUwoe3Up{HTDC*W22L>lLH zy;I;Q-#OG1G+x)cgnL?5iMkcNqp8jpXq*ewxi^Q%WyD-SFrSK0MpG16Pa*YJJyU)q z3m&);g1_sVF?hHKz(4i;%rAEa75RNVXI7Bqe(J^swK$dCr4* zKy&NkY1qLDRL{=3w4PlH!pIRIEElMrR7AD}Zld<%>UkHm7R^Jfa9n+eeI01j2Gv2S z9)t~sR0r#esX8=l7T2D|Z>^=%j;@C|$(c^KqM>?z*63Uo!yuX3$%uNpqA-bg4E;o;V^CzGV?ccjTZ~^WEkp;c>pLZ5;PfwNI=*}sZd2cl zK!_iSwyCe8N1`Em9}+bKc`*EVv`zg)2J{h`aC|*KUk%Nst5|$}I@i>;Wl%~W_%2!Z z2ZelsYw#CF)WsG3VMN_rQ4DO6hG{Cw6PTe8fk_W^1JCC}d5nzaP8tAx(I(uiz8yWJ zmeDk;FKQS~v-;i*qiI$@vSBpMy`yRF9ZmCk9!)MgszrT!auj}$(+eH_Ue|~;yhlB6 z2(X|B`;p$+M{WNCP#yYdRQOaK&o+KJG#}`AU86;)>Iv6L!{c=Y-0(Qmp|+L{V=c$) zCX$xi1+(#z=NFo3*@IH@3mJU6yf&EaMcBagR+yAFqgUEpXis2fU(vu-aGZ z`ZXB0O^quE(|Q_P7kjm7G`7wmTb$Pr3*m9Xb5>GJjH_$UH5brjb6i~(0hz(^bv%R4 z=BrUNp{@zND3F&sZz^7!U0cVALjAd}PLc$E-tqkua4YL#H=CX->v9`ZR*6ddF!6fu z0(G1xzaH%lEl`);z|9eE@Gq!xo}F!C&hA}}TyMv=u( z1jdzyQEV|3f$@-GlvoT!VC*uCQj4L8vJj87%&JvHA#wBh@I$)zZRi*`DW%tyaoBw; zwf*Shf;p4sO(*I|ijQC(xK3&|8fVlsp#|j&))-Nyit>b!rO+2R)D{go*YTzCHPA!! zD?kVa(J%i(+*{|mX$`$~uA9%j-DgyHaeLchL|yIPx|!aJE`svpI=+PX$GS0*T-SqQ zB1Av?L2WM%kOhme#8V`Ub1$4U3(t=fEWkdYy{>~mi+N~std=znK#rCLbgY&yN;$0L zSS{}xrmik?K)ou5~Tkb*uF)>-5@(UwU>x7n{U$zVWW- zHr4W6$jCR#$em7fg!6<9-C0BX(kJAzBJ7hVr9#I2R4s3Pg6|jupR46A)c{2p!f`XI z=Y@gHGkZP)`qf%~w_O`-(@Lz21Z=;;kBPI z$GTdzifCke7oy{)((%8hP6?^NU%oUgTr-fH*QG6-`2F-1TB*FzO5NfS1vB#?H0o5S7^y>R--4m6S%pi zxM3%;xuy?~;6XZB+gvl0(vJ+_i5k8vJI~NH`pFtUjmF_D{Zvf~+smWg;GIQhaKBlNWq_taowyS zQUvqcphp>CcZ;D2jPAtXD?>;pHdtgtya~8Vv^maQsO6j;R?(HO{tysA(pS za`z7Xq)tl@Wj(C4iS(d) zni{j`L_*K{YM%BRrn+XYujXxTi0=~CS6A>DxQF%CXHyI~!NzF!P&Frx+y&UbJW?G` zH($=n6H&22E09DUt>!PhJF7-O{#Z4C9LJ%bKm+i{0i5bp02`}$ocUK^PZ|Ebx>2w# zj1eF2t=64Dh7ldAmbD%1OCnCZhef0VRD`J;XBr);mJLC0t`QwqQJ!<4J^DRe?Y$BB zQ!C-^c?qapSj}6<-DsV|8=r;M_3W4*yL0Vu21x>D67U5k_e9kUY51FIIHQ^aAw=Ix zK9jl9}=qsqC zd*!@vY&rZBYF)%2n~qaLOZ^N=C`E_OBxw8!faF6L7gK7t8_`Q>!yLOQj` z5BurbAeWYcuv}VhsYFdr`SHAi6-t0Fn$CY+7^IR%dQP4+1uu1k8wH=A?nYa$FbAMU zn<7NpQNyUV7>dC7+c0V@h9WRJV$>4TL&M%=ugIkGVOFgo3?lFVUG7d*CD4bgzBVpA zU6tJ6!qZjh4K6%W#T)n#yYNg^T7wJ!tP&T-(H#6$#j9Q1kp*|`GKOYYrYJIoI##VB z7+SEY3Tk&$#ZH-l+2o%P?5N6OyZF}yJF2Q_2)T3T;3oaGDs#~IT2&m89R9h$>s9=7 zf#6W+ki(KgRf*J0=jMYdS@ppC=uYNXRV+1zn-b{A@M&?=y~cv4tMXVmTkwpGUo6-v z7We{3=c3`-D$bezP(wCkZB;M&-9m_e;IOvpY|$|-N7 zU8sLY2A2{D=AfZ-@r97|uH+bXo+WOd%0%Q~J^k-n$!S%d3-qf@pyvWe{K&)$EByyi z&P9H{u(DMc*8|wqtQ8b&ui!`u&UWqEUQxiqWxKXl)DRH6wpWa8uxoq8xfE8R7iigR zui$NQ{ve8%?v*jYW>81{zFT4XJx~!xt?41gfeQXRKe@AJf%1Mu`+G?~YZi< z0MHIrv?CzHIb6ZRk;fb#RHVpb4(cPPVQjfFHrXi!EB!jqbrkyJD>&ZhR7rMU<16@p zCGcs*o#EaSFiA0)k-!DcT8O?MsSkZ``+_lEI4dqp2gY5M;l=I^nHf}@t z1gh`_##f--Jn85y({5h5Tsqi{dF6c?l*}t1#ehaQul!sp(=ovO@+4|4=Q<0@`Ogo? zB3)R{dr%GWRpp!=ofHH|cvX2fHUi$JA58|%&^kG{oS&Qg1Z_x)gmZaD0$u4EFihN^ zf#WQ3|FCktd6Km}tXyW5pY#kX=dkbvUZ0MJRpmU1qvlc65v<@~;1k`da?km3Rk@rW zUw|&;bhuZ!o*yqaqH0%kyAjp6qQ{J=))l>CM0Kv{T_dV@MPC?EZ&&n(5%qCJF&Kf^ z)z=lZH==&7DA$Pkt0>ROuZAB6lye@V?f2Q`oU8NPQ_d!15t%2; z@_6y{e(hu#@40+|C`!#cg?WuTtes^gOyx(9JIe+azyWfx-c=?Smp~{L?Vc^;*#F0E z_pG+#Bd%x5Q+g8SF1k=N_@R~rK1w}LolUk$K4PtEp z_JceL8_J3stldyHsKMGtU2BKYF7ytu_71n*9omkqy`xN$C|i3++2jUm?-V6!+Iq`0 zMP%BJG<2~-OncYuVntbDgJ~v?XPp zhu=#r)2_BmQ$(g68j3EaNEb`oE~bWo2U zJsYTl$_CKX;A6o!B?*_ypk}(%aUhV z_j@Pb@16VvYY^S6K`5d@Y)e2FabnpRw~IJ$T*gUU`T`SELH)Co*Yv9{_0Lk7V0P)B zr5>05S?YP!;qOvT47y61S=J~bYu?2TTll+DPE6mrU3{lqaDabT$}xmDjl!UQD%SL0 zqQ3dGvE z%G2fxJb68+50>(01%3rp-m7`Aw1m#(oG1#$b<(M`cO}63Qa<#Ro1NE68|6>z1L?NX zM!|z#+j`katDaS25ssMVvo+ z0E|)E(p&~|O#Ns-25EFDlL6m^alQ;|CA-hlaR&Dr(R^3*xe+aJMZc4XK0O>>TH1~t z1Nnl97@AxfR$5L{1V*u8tg;x2z!+l~t1X5iFfK8S+bo76Fzz#q+bxD7bMJVERjY{R zYaivp-lZu>gT7NxCiB(1^emb$Ifw3D$~P%;QqxEL?F;OrP%V{-F2)Iu9D$dX@>7iv z-_Vto@->|{xn-s12)wM6kHCEeB^1G(OWU==9hY?5xwNVwOgfhi=B)^aN$1kZ1UO7O zm(HiM%zqc}{C6q!%zu|so`0FRZl(Ou=-_@>D)SbyJfa95{lzfyErufF(E_Vh5u8}C zw;hJnrnKG7W>{@XD;tK@rgU&a^tUNJ$3%ad(uExT9B6*EcP^Aj%yy9e@H&tYbySh= zwmK<9rb>eek)@3&R<{{5B1?m0hB&0Dbl?k2>jv)W65dAs0j}J_oh}KnzxkN$bcwwD zf=kGm5)@Sm6dS-EK!5#!R3+?IR~RJ?E-L^IO8aqmP#+O=07QE z6g&>ooYE3hU0=et^ugCia+0$CO(kt9>XGeu2YPP_pWf&mZ$pXP;v*t{qZYfUuNOs! zFW3V{%JYf+B}wd5PC4&NyE`*x{TcjB7w9{h9`4PP0pe{U z{FJtsgB^49vDPl})L!h?;@v0w$fdYF{dx4fT$~avFK$m=URBqX${F4k=x`>?K9Zrkw36lgMviuttZ05r%;I7P*r)C5@ycH%C1L#JIaXRTlswPd3@7fUJ$_9qdq z{VpQXt`(W((ABC{L_RNgF9O}g6}P(vnnIjpIg5p_y_O zbn(&h<|59>a=^K{i1UjtP}&9D_0sPg!(A`^3U_@G-{neI4@p;&jvp4FF4|b+PVA_& zq4Y*E;5DQ4#v;Dfh|(L2hHxI^Tbnhil$YO{q6Drf9s(sd74i8f4ku^_J5N+jyBcHS zHw@;9%1|fr-n=3?3h5?bI&0y}#(b~-`J!L;)+>q{1%ps0lVm_@H@0k-Wmf zUYMvRkGT;#CKd6Y?Z$e>?k|kLSxRk=UE^wOQdB|$IahB|)Q_$(p;F`wP{;BDUy4Zp zm`$|YbC9W;7Ri%nK0}JqzHTf8D_Q~H$;2plu?98G6|Bdjs&K4;+?iBNp&oPb zUr5QN=dUe`bUO)3D=A9|wU(wb0mCr?FJmO~OxP*n{LXJY6eaV@&7|xf3nc?KEro~ zl19oip!)kl84}Xv4~0A;8O4u<-lXPpgCH=J?#>Ssb|zPU2zx?TEnLpm0pX z6dfp>MHV@{M&B#+JR5kwP@WC&5;-W{IsEA7P$8eZ_zFrXp*&j{OV6!C{N=>w3i&;{ z&`0Px{Jii&(`Ep?Al8REW3Iw4DtKoez)L!=hid^|QSkaSfLBEu{_qT4RtFYxsxDlC z&KBPQ!5}dzG?vba1{b#Cn!m~chG@+sy37wPY{}!T8xJr{d%lWp28WCOT;9Tt)FJX- za%3Sth?B4wr8aR+99`I&`f(=ELCY8cvYC9Uuu*>AAV?oT;f_`)tViMF1t@GNY!pmF ztK4(wq2jVacURdPvhb?H4x}+pDz7h0#*EQ_QITYJ!TaZd)2lFcDmdcgYIX9L zX8Qtt&jHGpNL)i)HaEYJAI3@06u8_?mw}sJ$SHacxUw}*FO*F)_QF)l8Is=y%P8c7 z0bfB@d(`ac8C$a&`Z+Lm^yDB8HdzUu@Uw%RJtHXibg3vpQcE|CT^2(T7<~+5x5ZEd z#!SQ5V=)wgvDz^9S`0;CJYg7bSqw#B959TxErud6J_jQg3w?i2x$*^nRl)nNAQGq9 z#Q4A!v{k_|SCFQHPhCNw3chd!y;bmyD;TAM?_9xoD)`A2ELFj;u3(i4PPqd5%U5LB zU#?)Y3jT8i+f)#t(Gq-D1yQcxxC)xPf(XQe%zj*Qum~Sx@fpNqz7FY~LVEknm3oV8s zFgjfCdgellp$Lph!&qc76oE0xFfOtfiom$iFcw=3MPNK+7)vaMA~1Ft#!`!+2#jwH z<6?`U2#n@P%QBCbSPVsA1Po)D#ZUys*@khc#ZUys1%`2%#ZUys&4zKg#ZUysR>Qc$ zVkiRR1H-t|VkiRRjA1Od7>dAXhwYR2<0^}x2#j*WxY}YU0%L+d3D=mg1Fk;rYqg`b&6oKIw#%hb92#m7~<9dss2#h&~ zaf8KB1jZV}xY1%L0^@1JSYt61fpN$%Zn7APz&K?XH(LxvU?k%nRc8Mdi=haNQp32_ zVkiP*oMGH%F%*GusbSo1F%*IEfMMKWF%*IEx?$XDF%*IEm0{dvF%*Fjb+bF#yDf$y zFft9}9*dy}jDCi3uf zXfYIlk$8*ik98J95g5gWvEE`R0%MF}JY+ExfpLjpJZv!(fpMQX1k6H{xU^Kba9qnTlLlGG1hOyCNC<3F8VLWaz6oE0*Fg95XMPRHpjLjB95g1Px z#uFAp5f}#y<4KF52#jA1<0*@w2#mJarpVggVlfoaeuv*P-rBP(y=P3foX_@bPCI{x zUpaoZC%+Y~yXcpC^6$n_8|XR~`=IyoI}-KBJFyL)JAnm!gXi!cp*ft-r%4X~F@O&g z@ZaV6Fh7dB;J?0eB%lB8w)~Nvqf(RKt`gct_l(Hjk4JvtsXZft@6t%<&$ouN3Us&o z1&R1DqF(`T_k6*K+aU_kInmI92s#FG_M{4+n*m=if$F)*NViF*5sh(0Wkxj46`gHF z=eeTEMs%SoT4+R9xT0%~=z3Rlw-MdtiZ&b3!>(wD5p8ir$4SJad&N6C02$qHrpb0! zA{Y}Dc`=?f2EHnTwvCcB{xK$P%;z)m5O=&We=zkG zx-yEX)A`pWXZL5Yj6pV?EN{$Txd?jYefr1May~NLl+UL^YQmO$_pH2W9GcxCeP`Z{ zrX5E@a9e)j8t8MXIsx3C-->{*@bAGuH{|mPY!4r0y1Ds$=+k2)9U-2pU=w+2qJY4Q zID87f7h>9dq@Oe0!H_4@9SV6e-C?PbOgAP!!q;O{D`?m&8hSjk5a2Zh+ou4$C?JqQ zM^YO?oOzFpHD>9Ua3mF$8Ggq9;)`??lHVyzRWZc zRrCyJe{c*x|HT+R1DIynponbP zp8+jnM9Ui0GA78cHj~4~1Q)sv8xvgSI&5r%!^TNBzJk6bP&6$T#JUcuR}J9-7Lb=}b`xXyJ)wd;;Y^U(URdFz)d=gxHp@yl{f|LBGy?t~K+5 zknwgH#x9GY2#hZbW4Fan1V$4WAieCd7>dA1H;la&LlGE#4C5_}p$LqbhOy6LC<0@( zVZ3cI6qz`G$EsCC6MIWCJi0ZPS0B=-hhx{+zGix4BT%H#hc}D(TxWvHgS-ya-j|^0TbL zD1tNYGK>KhLlGD+8^+ldLy>XUK&w`f5AHhmT-aGA?n-_@+*Q`#uCfMql{L7l+;vw4 zx$B60iElEs#yU8XW7ffu9J3CNxiV>$Kotv_GEYWq2W1YCXcZ19O2q&0=Dse_XYcPu7j55RMZ!r{sG2SrF zvKWfMxXdsHSPVsAJZKnaTMR|UWx#{v0u4zm5n0sTx773a9w{*!=-@=pVG^es(a!ALx12=5QX{;W#& zixP_RcZCyNjVf{ZdjW5hD}pngFpT#th9WQy7{)=1p~$%FkX5UQ-1XNI*tsLX5t{Rm zxNApXyqiOJ1QxqFbVuM8H;29!&UkE#Ui@U~=t%$DP4esjQ;I7^c?&{;ZYgQ~;|0Z8>jd?^y`djuSb}Ito_iX;l zn8AmQm49S=149wUvD+|CSqw#BoHUHn7DJI4=^3k55sh?N9c=wvY#pq&ex5C_mtiG* zo_&G4@A*7?iMtZM$TlnCOBsx>;JbcMbTB*iPgQbIl+a2zqyxSkRWdCfSmr3ga9%Ks z4=siwFpe3<5sRV74EU&3tB3~tc0TOfnawMqXoF1c&g>cPO4ymb++7Jfv+r|P!meyx z35Uj`^$c;><_;+T{j9k9YF)rWd7?5<~j4+v@p-1FEaCu@cf2} zTOi%|3JMxS(R3$vqbiv$N@(KFwM;qBGDQ)YGM{2-l(^$t(gJska?W!X>?r3dcfpQw z?spgLXxAO9=)!kKz8c=+adF3)EE9oevP=Y?$ubf6XO@Y;zq0D+yX3xt)SgguGAs6P zRdQ04&_KQuPH+*bB))#g@f(8Uc7 zUDDvtrCD|Km3aKHoXnV!6+36MD4EgV(DQ^7+ztKW&{@`C6u}uM4P&;&Py|K`s23gQ zTMR{Dri=haNfrc^HVkj~$zrdNG zE6UKinYjE{Y7Lh+%i?zfDg2se@!yo!CEdcZK@r*T%}Qu#BwEUz5G{?eCi3FJl5UhW z+g;L)vMzL&bmNAJi;!-71vgEFqCYZYm#LCJGFb_kaw^kn%9%{>Do{kGEDb@!iA;{b zmq`oUaUyf7yQEKKUgj?86Pb6rOZwYPjlhehqxD?*69i43l!466Ksm}D^&fsue=%2*~_3`JlR8OAvlLlGFG z4P%PMPz1)shB4J*C<0@xVNA0aion=z7}G6=BD3DkwQ3bnfHezZX8TEib=V>S)-Q9K z8({r1FLwj1U*ed z=VBS$$u;~Zx;JJ#L%`Wh0snXg2e1>)1lXj29}hmEfFBP&>4I*cJ*D99X#iU?IEJ03 zv;dygn$=MN&uC31)ofM3r|!=x;OC3aWq3~ApO+drGcU>1=Zj$!{=F1hoXjS{x~E|~ zKV*9?!}ACcfJWsDE~0vV?|M&0YZBoTY4kefzKkeF`ZP@tHP}E69-~C`UPeoDt^2E+ z41RW^C*TJKQG+9oOwpoS{Qe8kdnsc02sO@pw0OmecLqG znwk_r^%TP>wHS)PxY{tvEQTVpD9f!{MX)}QI0sXHtAy9xFSy}#Yr4D>&WrHYbUvDw zMR;raT#hIXyxTM&coE*NfCKLiZ>Zeq4VAmRp>ns@aD3h)ZDidYOxJaH7zJK;N7LPP zcYk^!nJVk+Yd+UU$04UQL%Z=Poj8rKyNh(@QRHjAyhCys|xw z7v20o(uA83U~#+p@3K5n=YUg zxKjbIz+Gvc6}Ve#_=3Dg0bh{!DhScl`7H&!Q1__oXV%OoJ^d|Y! zmqW``6!x`7VFU{MN1-s23Usr3WqL&LzZWqDyi`9-^DI>Wa)mD#dw4gO~}P(%$Lq6WNFqtaQYFZjF>#ke_U z-^*a}2M61x^9Kim-xG;fYPWQ+@rs~1j@mFIUo`7lRs=@SFbXV&A}|IUMo){O2#f`W zQD`v~fpME*oNZaE2#iOG!9Exy3_K1rqQNRs>xU@x1%EVpFR?PWBIs>}Wg;F}W-%0j z(ZetRK?nyJ*Eb#5Q81uKAT>`n!o$L{Lx$zykG z4d=0Yy7S-7ayXCO+r4E6nh{Q2YqbrhuKT)sQrG=bBdKd7oXTlwLRv)dwryz5Y3Z@< zp0orYX=xYLb6R?;yEiR8)7`tW6;aYSO$|6Lz1UqRhZp+G-Mwi^5jDu%?lySMYVd~D zKoK=4qXxVr4+{l9hcKcKUBf3E(MeadkVO2u@kcn7DEvj-xJ0Fqg5jkAM-qR{8RyFz|T@8&wWW5 z@VElbfS)Viqm?hT4QIeF6>tXpN&)ZWzScJMXUf9gXie9q04Ef@K^wDg6_iuWNo~`c zz;~&VTzP)K*BZ{JKcsr{>5oz)`Lr8mGNlTQ$8?U$zrH;RXF4~@U(*(aK$j-@ztHA* z015-oLt!Wi5m%#7g#u?`2hAU$OHxADCi%N@3K~8egK;a|`Ib`7% z-D2_w_Cw(`B*W<#xl#9s;C*kpDJiP6UI=zTBq=Grvp16~!kRs38V&EPr!U_a(Fj-c zrxA^EMX@{G-j;Tj7h;2{MzqWog^cJjS5#+2n_XR_jOck+G|Pxyaz&RK(aWyrCL`MB zik^W;hP+)wnot#C$X`(-z8W0s%&SnZ2A_21pCTw<5z zE7y*I5uI>FRYvqbS2Vi%e8G>5A*rtDU!ydqi#K=_p;0Os!rkUt3`Jn{GK`?bP-HF% zc~-3=vg>kEz;;jW;@Ro|h~2kPJ$rttD|*H>ncJmF!%zXF$u84mfh#&qA`XegU3inB zA#rgR?*>5;nU%7~9r-Wbt@PYk@+X60q^(rbn))@-m(Uxh#DmCbsHS88oX~cP(%%~se!Br zcNCRI^o?uyU?V!|ioSje4LP{~(BQtBNE~Htx_aYK5jxvo81WWE5g2<7!*4MZf$_az zBw7qbV8oGSY)6vCPy|NMFp@2XA}|IUMvBEy1jdzM$nwwcs!N&sG>Dz5h&=s}QQ6aN zz!XJb>@ti(i=oIY!Xm3y5p_Wy+m|^R-Bl7!<~~R`;?D2t&7l``_2y7Tq@o`+;DIc( zdQk+%cw(^S7YPIJKbl6%EpI78qX!M+DvO~Aj5iG9YKx%=jIRyjI*XwQjA$A^8^6M0 zC;}tPFjiU&MPT$dj8zsx5lsRQ{t+F#FSu+!dgYaHq-zv?!7O+^>EJwYqH9b;W&@Bs z@Br1bmLFZwGe-22EBcB=Ja@l$d#lKzK%0VPM!`IC_ z*@~z^y=l<2o3}x<)j$z77)=e>@D!oo=dec9zMBs3G9&8fiXJ2p8>wRHw-Wpc4UweJ z%~m5tXmrS^ea&*SA}~%F#_JYC5g5tjcsA_~i=haNQp4C~F%*F@&M~wZ^)lY!b0c z5=5j*6~UANhSA+(C<0@yVWe3MMPS@y80i*65e?WdGAxE7Fb*3=w#85c#%aR{SPVsA zq~JbXMw??X6oFA@7`YZh5g6kQBWN)cfpM8(DVlRRZ5Wx#zsr+XFGlGNIiC-V zR>0>2V_ZPz17j8N`M@~6Rp;}8@u_kS%I5|fmA)W91oG?rj4n(k>!pIVx@}6mJ5v9r=)=|xZH@Ib9;K2 zM6Bo)%VI^)v)eFUwHS)PIB6K$EQTVABkp0lRjUZ52D;9}6!eg=T1R2U@A~ve9n}y# zA#d>HYgF(I_w>$ip?8LhbcXrI`)6T3Z-#F9Tfudy{5PO=dg|3d?lx+m7z)eoZwt%5 z>%_-vmwez__FbnzWSP8z@m;6s4ETA;cb)h-r^Dxn-*=J|H9mOzK>^$RV<$NS<8!8; zI(g2Se%2a3MEgbB$T?y=L?*vz(E$ZMN9>&Ho+JL=DUqy`2flxFYDwQq)Caz&J9*9# z&vfE*MEIOvqgahL{Dc=zbnm(pBYn0VkF?}-ccjm@lRut#{UWZN$0Ox)z-Qa7XqcVn z+VQU`oF}tDd%m3vn;uhyUr@l$NM2O%bPLqHq~N6q052=JWdy)03QjEtcvZo%I)H5o zGW!B-SHP~?p@8$r>k2rZyx{`MCvPg?e6q8h=ZVWM1)NWIE8u*xM**KV?o|bR-uRZ* z@Ok4tt>N>=w-xYt<2wrYym7w*j)Qkq0ms3CcAhwRPiiD7?d%khe>S=4`Sua{*R(|8 z+4fEHzeq-5HVQv9MPWS(oVeZrc^o~1Ue+NZ|GbVU{EfmodLzBAW0U+BC!;X0V?_Q& z(zCi#ll+gVc~z(8`JGo%6$+1yL}3aFXJ3HA%1%+ikB%U^I1|RS_nvXIXzxAaP(<11 zUuwXszEykgeYYYoS|0_2lUBSie8CVzlH>eVBSmObXBu^O8;vreN>?!1D_HFTa$z>A7k02$ZR*pNiB3tH997%j$uZ} z6ibI9qhp%UaS^rPFk7Uu;7TJ}><(|O5iNB^+f7#wSY0WCd7lx3-T0c@I50s~|;3mDOAS5#$0 zce|n?Mzo=$-sMj-qOBd}+d#p^Mzqfrtumq?U0wGX(O<5vQ=h^v-qR*`YR*R}Zx~Xx zT$ynfZA7`Q=nRQ?g33C1&o~re#O+8kGs-Q7A~4Dgqrze+0%L+T&W0+<{HLsi=haNn+#)*#ZUysGlsF(VkiRRuwlGqF%*Gu+A#K83`Jn19Csb? zuEkIUMwww8uo#NK7;hNwSqw#BTxJ;WTMR{DJZKmPErud6-Y|?q7DEvjUmM0@i=haN zXly1W*gvosionP+j1Mh_A`?PKq!!z9-v13u;mvB7Z?IYA`_O?YGaBwg2d3QKa34A_ z<%x#P>fjXqN{HNt4oQ*CD(@SID&T$NuoQVP%+INZr^wwV?;A%bjqgK8D&T$NCH=ZLk`FvM9 zJ0&8&at^j|J=-;xo#Z|3BJzKuUz4tChmGH26vnoT%D;U$3Rj@8ly=;gpfD>Ng*hnj zmU3OYh~V}wFpYdmdTWZ_lKujb>|gFn(S^)O%^+UFihP*pE?+_iU;UmG9eRrQbc%Nu zsfZfXPy^QaoZAEIR0PHdVo0hGhA((6L}J#hJ+e3Md4@NRmW(+&f`;(C6BWorz+sgJ1yChd8bQ_WZnysBl5c} z$KZ}8M@i;wgj~$YGzu<`{T6}2$@I=-O{NtP$--Zk>`kTyafmCTg+GUMa58;HbZ9bt zF4>!s6j6gU)PUpdCASCGsR)eq#9-O0!ocUijcA7}+G|8_xT24Z=+|Ujga46;duuFl zqH9nQdh3h{7e<7|Py|M`VMJOCMPN)dj3yRCky&BUR;?mhVQuL+BqR~&eCLL4DA}{Z zLdl*LmhTO^0u2+6j6!c@6nP_~SR;d1*r4QyU^{dqE39v_cZKy+f4VDds5%pWv#=k` z%n&oD7&9}xW@f0FyuvcYGGBnt(Edr}6&C%IyTblS^sKOd59p$niV}w$wu^~E6O&a|G7h~G@`$gG{a0H5gX84)`?~q zMKIt>!)ReK6oK)OVZ>StMPTeQj5v#-2#jwHqou`AWO7g&t5y*_8Td2}(Rf(a=o7R? z`6_=nk^lUAh_CX86K6GC_&)G1%MTM}S#l0KnkXxT7sate&!YH9YGeugmWY5yN0Nhn zNc85Q9}_v&%}v*-ME5HH zHwW!YnBH)e-F}T6;4|2QStP(V>ggN%UqKMbuz5HQ=?9 z>-NAp6@hU-F<90^BOv&+5tX{4og`x82PbN#IR%jzKQ_^uX$)eeipZ8`2m$HoHdk#2 zBf4M1Em%n+w)hDV>FQPlJ(CRMNsFNfj4KV}DT|>9jE4+ki^Wi6*6voTRuQe;Sv@f0 z4@qp#{MB8%4<&fk?n4QlwfnF)oFCBu^?5p zSayFYfMxdy0W7-*rz*qXNdc?_e>GK!>r*Dhi0kuH#X`U2L=o3(Ai!*)zZWFF<3-Ep zQ%@8rJ%~q!(N8mU7AbXz8C?)D`lLUj4wlkJQ-?@t%ZXY_1yO-!D!@G7YTv+h3PO&R zl!KqWQO3IAa`)&>_EE+?T4Eo)+daw&Q#5>@9`W1WWgdxy3BudH?{d65l0y)3{MzN% z8p$CDIYxtN%v-LF~`)+-5ns-7=(G!pi7y^^qB3t$QR zO}&z^-_|P$dq%Rcg#AtcOW3mlSi=6N-bfhFj?W2TqCPKx#qIa?O5FZnQjEC0R4?MT zajJ;h2OxkfZXX7{PdyAS;d$lssUmJ`@W_bUIfm#WZVs^+2qNj(N_DWfooDJ0aa%G~ zi<=-S@C7Qs0TL%(g+HV=&JL~@}(|)V|VzR%C z<@v4p-q0BPwr00`gh7}MzN6XTyP6H|6Ejm&~$e99ofM@AGpQZbJwjSWs=p9S-T8#8aG|ce$5;K+}1%klAuXj1t zL~;m1jtg9lb&(u`9FMP$qzWP)=T2Teh4riVcTkGgiY}j$3cZiZr`!;FAD2)0O33hU zpTbv#8vVLqiqfy|5WxENiYZFJ`cssC-6+{uza|8*e(e;%`ZYO4>DQD1rh6cO^=sD@ zrC+;EiqWrEO%eV2t0|&iYwSoMmBuNVo|ub-SE`t=SxGWzw4Q&{jszdFQvPY|ig zgH#9W*FB~V(XZc_qV=mFDsbH2?C^ivzJco$gd9^T2S59c$pH%ok4&@fvxQhiJH*)q z(OWKeb-X;qD2#@8x)+a)aD^Zg`i#plE|NnKa(vh2sEypqX)@un#lIBF!Y{Y9@K3FbQkljwvG> zZp4d>_HCP@weMSG0Br1Woe}1oko{_d^Cr?(JB~PAQ;GS{&PoAtcOP(^BZ+|_9Rq=Gw%5$El80BjPaQjacz^ZtL z0M<6ATflRG0A87Xoe+Sv%}fDIwAX8*y+IT0Op{_FLqC{2vZZG_n(_twU_Jih$s-$n zF=B*B{+lQ3&0ptF*2{~6NG6X^0T$bplUXK3@e4wZiN_%ai*lRE;Waekk&*njL<$K) zq2;d7rMA$e?$LmKbftUrxyi<&XxKrIxIN#9R4oWq-|lk!Fp@(May;yEJP^qt2s!@f za_o)d5QH4{;1$!3eUTi3kYj<%@lYg(Amq5r<@k?C4nd@Ln65uDsn9dbTW3vTIeg;@ z;8vai&zhvx0M459iEsuyYm!<6IA;>y{%mHz*^|@^I7a~U~k~^1fh_lJ|us#ms<9CrSM6(Md7`j<7sD8a%vp6iClA zV0x0wfM3NU!*In(dIofe=_rWU`d3s3&w%eUb;u03eUhF51yO-f$J_DVVc)=Y3PO(8 zP!4|fPbLSp!?;Jg?4$GO5jXyhNfLI;;*n|mHz(<^n?qcwAZp9CuG-((YInLvf0`sy z=fBY-mXzZn+$9M0>~}dvMsf&3j{kExMn!T6LXPR+Li3j6BRK@QsdG#uRS-He=e9RO zM;&Ka`d7r#Jary7NqGdvO;SODk(!G~3EweyouIjEwC1ic!d*Od&X|PbAb63PI!~IU zr_Pgwo>uZ+C&cvTe1c~9ztpkhoif@s^DlKOWd4`BKAz`T=O38&z61C8E$1(08fy4-Oa0XHw(I(MU!GCyBpCVp5s1Uhkzg2Vp#IJ zIz43x0@MD~<=7R;A;>Z9O_5YV#Iz4ygRU<(UGJ!|U0+^z1&<@I^DM6`ac{YUD`XhB zjaLxSSui^y^$Vi<&mwzkk*WVWSO20qb6ADzUsTr})_<<4-<$Jn9SRvH@ul0%SV&L<+Nf{1yzllM+w9@sbmlwu>{-U*$dn|$wt>q8^q-U+ub zC-Fr>-<`l0^cy4Lz6r`m_;&$pBz$jzG7`Q&K^Y16OExwVejtF2gdYlEBjEw5fQ^K` zQUTNbM-vpUJvc$}+K)|&F%tfBf*1+i6U9i_X-DEy7>R$b#Ypfx`_~C#B>WtY%se}K zqBas7;(1mO2-z@tJnCR0VcJBlLyUw|CTb%=5EVF!3b16KX5YYd3PO&>l!Kq0VRGR9 zGxz8m`>2y1apTXQC`Q7^@W?d2eWErJ9O6m^QCq&`s@-C%{ib{Le#1N1|45Ix#UGEb zlOWXdSC``xksN}M<23M?spG~-4nfGV)aBR}$sx$G^rs`Kf{3Mm(GI!&q+#jN6Rq%n za)Q#gpPXPc8FTTcG#7tb_>Q^jGn%_TtGVlQ!d+}6?3pmK;V)>lF%oW@ppAsvCm3JE z8VTQ+U@R_g&I_cYK4O}=#5MCH6O`Ki$ONUf|H-t>oAcEY3NAMVPp-55TRuUl?d8&0 zR@=*^v#hpPOi*fjr2y{i1-i4VbZ6Tng>~RtOf!s;P=Z{sf4vDm*hsi~f;AFWPf%)m z%>=Es-#S65?X?q}+J5G3=-IR5SsA4!*`7T+-q=mt{%6Ot#bb{ro9r|H%%!%X>gd9ySM`I+1Ammu@ax_J92qKYSiEcKjkOA)ZOSMeNh4ogg zzf_wH)%r`d9}U&|OSNAPDfx0Oe{q zg>vvS-{kNb-ryef*hh=#5jXzb<3+7siASdK*NxX|-65`25VhqRSM4`#wb#2x-ybi& z-`D67tMy0BBjF}NsOM3a<7bf^f{^2XU5-a1IRqicG;pDL%YR042y$wDetrxeg}TATK{^jRqG$9Rcd{Etyb$FtW|3LL$yw=Pay~B!!@joYEQMw=)*N@LuK^g znysNS`f!c8ou7yCpKADvF@{*z*C=K5Q30%sZm2P1%Exv-CMg^o-6?>T(Z>a_GWvu7 zRz^2U1+0vA)fmmhn^8YmV>AD;4n_R(s3#BHq`t7Gm{#)`)0?1HF{JQd)!zQ)uc+FKBEyw|mCilI_Vq!NqhTC9 z;dehIxf)J&kN#60Nj>{rJwCFS?muB#BHO$;sS!Gz!zO3-Y|~U zE6)GYBW9|%jnn(U1)X$atK0>n(4NV4UrszkmDSe!;j<;gd7*S92+A!1R+Px z0c_@P}V;bB?rU4suT{V}n(X+UPQ?m^C zI-RbX>)7aF)1X_M20b#b@>F`Io=SW5RGN{glpXhNH6t7D#9NJpcTJ79@ZKd#+)DNb zYOIBKI~i&-O`E@bnr-vU8nwPXvqr6N&#W=)+uWPiOEbAQZ_sT%Q@44RZu41^!iL(} zri?MvE`u$={`cGPgAKJSYOJ9)w?-Li^J=uA)>NYmwdNW&)Z}Y0%WI6YL4)%&o$vdv z6HeX?@ITbinpS>rE)BuleoA`_{hZg118*lxp)B(bFjqhw0l zYwBs9Ve7f~gjQS6y(e(&g6jE>uIIZ_&zzUKQNw6cLqFAUH!W6=K4A&hPzxydLO`k=&iRY5I9CwX*q<%lP>!Zn8IG(umhjm@;nUgi|Ke zq4CF^=#89k?zlIOTQsf>6W7R@-nemZLaOJDdV@z#j-QApo_B&IfE=Ug2_=o0GGgR} zapO$s5qMBDURBnLQe(r~J#X9;q%MY+Q#)cr+Z4(_{&c)z9`a3SQ3c<85@nirI{H*6 z<&QV5nh+VRo6>XI4d<}>XZ?>sV7byapp;;6|Xs-tC)roV=N`8 z#7UHe>N;79O4X;l#=Z+gqx9)glHcWduhp;iyi;Ejc`^K_@HL({Loy5fPuFF~jT=9% zb{sY345>p}@VZfG!JEd>D4@aeaONz~a5^%-eyT@Z^E`OnAj%|ebb zI>%Z3Kn>~H(p>HvHRT*V2A(&&#k*h%H34!k7q2tzv80`Qyy+~Lh9IFVkyv2ExDiCY zM#T8Nrn!a#kYpO)jG|H-^`&L3gZR3peiK!(0I5>3=PjJ;z4;_t)>PK23s805uOS(u zyeIJA5hF(Y?;pq0KWGNF^LQhQh2*?Ue_zI%S1uOjrL)OQITb{}yhNdIP9~i#_s{9h zmV-oRx~FSiXS!58wp{Z{1Nq<>@)ieTneqdro?Nzh?!rFvqD;DTUUxECu{o`-7U1EnBQC?p1SQF>U^577H$E*0oUnOwFzj?w=@ke3E^=5iUGp(~S1l=OpS4$TYt z^`k-}+Z}ledYCIj+Eyx~kS;^xr*SHsjNn}SL69x?=>kOzrzUnTRgS))tDH^h9LY?g z7$HwrI$9tF#WzR4xQw$G`upXz^7Ey1E?e|`r58NEoGllFRFivQKefg$<$8lG>Mh`T2O4rg zP--g$eQntierAJ0I_deu6xp0-y5|=mWyv0&O5+vW`u4^~pM=EkOylK#DwhpBj72fg z9e60p4U>N6{i5$T&$q2GaDl*-ew@ytd+C&)F9hIw@EJO~qCe?h#8h6LE3M3xv#Av{ zq8`1$@7)Y-nkZ+W?#;{coBbA=F#N_QJpz8?Le!a06oRmBzp;ohO4{MbqLtKG6ser412s_Kfig|IFc>iHG4J1`>X1=h+Si%xF6YWcU)ste$y|%Zp4KT+sTVvH``Ag`&r^D(>Ef|Ao_XbQdg^&?er5V+hEFvfn$j(tqV%aX=X8!<@+?p zwfZGt>!RN|05MAi{a&J&Os6faNk{vBOS5{j-`wPtI(?|lQrgRPf(Bhl?j*_2+C;h- ztPXaxy9eG8?&K6GOUsx(=uK*<&ye|8M4=O!`N8EW+UxqQ(B-J#13 z?K=j}PZWbSJQdjPQsX)XRb7>)w&j%@{k!d8x4i-is-S787iqrYb01aoR*pu$E zJVYa!OeA{(9#^tkV7z3z(%sULu0jwn&mD7bT5WGs!%-y^4$K{&R3>#G4S7WCS^nr9 zG*ut-D;gW^J0KKY=|Zst8ik4Dn}fpRISk_Kn`ti5hXhR6(&eK_P9^o;Ao`uAZ)i4} zK3TuQSygx&X$omL zthU*9!oa`AVzRs@yx%dfx}3?hvDq5PJV=%$3=gZ@@o4@^txqCF`mvO-^GYw-U>>;$U>rc0fX1OlA=Z7h$7z3=HDzS0ODh zZQbblYe1Ghh{ehbH=MLRbPtU6M5i6#>e;Q?zQD9@NGq;_)(wp~Yw))>+Ieb|UoMc9 zMUCtjAQjl}FDj)9frnj0O=7BXpE86~KVWCrYa%+uLI zXEZy3lBza24bd^sj_AQ!a`s70m^WiuC38K;Q%RT6gfQZuGhjdX{fJyaNc>V?Ub+u+ zCP@xpwi~u43ld&P;)EuPrSDnShP)iOBhrwgOoBs@$P8kBfTuvw5BUuI5eN?2O$OTe zh?y*x^^q7gO<{`2%P?Wqc*ggoZV3JIw zH>DBWGw*C~S|~y<_JkFkh~C9?375`!8!X;W{via^ORnh*S`KvqR)Nb7 zMTtmN55-}j14xPaY^1FXV2#pL-i~<@d<0cyX_5D{!4UBw)5b^urEy5%CH=v=#`sN! zm{IN62ZtlD;j3jdV|Bpdf*oNfoeg7luS^psFQHB0ra!AmmRU0SE8#3GBdg7l9gXyo zKACQw-?qlzTmav|a!+BD)^lWc9j2}!JVoabf$W8V+@O^6Qjao<73=~#UvEkm#rm`w zUAs@@?HDs%n%_RZ#fn%b__EhVB#oPfF<)OO2kUs<1SO1CHJsuz5tv;}Xu<^;z(DCz zDbZEhf2_SXE0fzx0tZRFVr)us?|7(XXxxXj`Rqtn*q#KGsC)9 zu#w~_0;cmXNN)P{AeVnhQ0T;b!FDSw9r%tOmNqa$_sh75I%&0Sv}Q;fiN94?L|U5>>IMG& z)z}uW8Iv|#JYIj0+6-p_l&)4TK0P `H>M=cNRlr$tGRO0RhGJ=Lk?dT(s!C#7S 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 weu(dwElementTree does this for +# you, if needed. +## + +from __future__ import absolute_import + +import re + +xpath_tokenizer_re = re.compile( + "(" + "'[^']*'|\"[^\"]*\"|" + "::|" + "//?|" + r"\.\.|" + r"\(\)|" + r"[/.*:\[\]\(\)@=])|" + r"((?:\{[^}]+\})?[^/\[\]\(\)@=\s]+)|" + r"\s+" + ) + +def xpath_tokenizer(pattern, namespaces=None): + # ElementTree uses '', lxml used None originally. + default_namespace = (namespaces.get(None) or namespaces.get('')) if namespaces else None + parsing_attribute = False + for token in xpath_tokenizer_re.findall(pattern): + ttype, tag = token + if tag and tag[0] != "{": + if ":" in tag: + prefix, uri = tag.split(":", 1) + try: + if not namespaces: + raise KeyError + yield ttype, "{%s}%s" % (namespaces[prefix], uri) + except KeyError: + raise SyntaxError("prefix %r not found in prefix map" % prefix) + elif default_namespace and not parsing_attribute: + yield ttype, "{%s}%s" % (default_namespace, tag) + else: + yield token + parsing_attribute = False + else: + yield token + parsing_attribute = ttype == '@' + + +def prepare_child(next, token): + tag = token[1] + def select(result): + for elem in result: + for e in elem.iterchildren(tag): + yield e + return select + +def prepare_star(next, token): + def select(result): + for elem in result: + for e in elem.iterchildren('*'): + yield e + return select + +def prepare_self(next, token): + def select(result): + return result + return select + +def prepare_descendant(next, token): + token = next() + if token[0] == "*": + tag = "*" + elif not token[0]: + tag = token[1] + else: + raise SyntaxError("invalid descendant") + def select(result): + for elem in result: + for e in elem.iterdescendants(tag): + yield e + return select + +def prepare_parent(next, token): + def select(result): + for elem in result: + parent = elem.getparent() + if parent is not None: + yield parent + return select + +def prepare_predicate(next, token): + # FIXME: replace with real parser!!! refs: + # http://effbot.org/zone/simple-iterator-parser.htm + # http://javascript.crockford.com/tdop/tdop.html + signature = '' + predicate = [] + while 1: + token = next() + if token[0] == "]": + break + if token == ('', ''): + # ignore whitespace + continue + if token[0] and token[0][:1] in "'\"": + token = "'", token[0][1:-1] + signature += token[0] or "-" + predicate.append(token[1]) + + # use signature to determine predicate type + if signature == "@-": + # [@attribute] predicate + key = predicate[1] + def select(result): + for elem in result: + if elem.get(key) is not None: + yield elem + return select + if signature == "@-='": + # [@attribute='value'] + key = predicate[1] + value = predicate[-1] + def select(result): + for elem in result: + if elem.get(key) == value: + yield elem + return select + if signature == "-" and not re.match(r"-?\d+$", predicate[0]): + # [tag] + tag = predicate[0] + def select(result): + for elem in result: + for _ in elem.iterchildren(tag): + yield elem + break + return select + if signature == ".='" or (signature == "-='" and not re.match(r"-?\d+$", predicate[0])): + # [.='value'] or [tag='value'] + tag = predicate[0] + value = predicate[-1] + if tag: + def select(result): + for elem in result: + for e in elem.iterchildren(tag): + if "".join(e.itertext()) == value: + yield elem + break + else: + def select(result): + for elem in result: + if "".join(elem.itertext()) == value: + yield elem + return select + if signature == "-" or signature == "-()" or signature == "-()-": + # [index] or [last()] or [last()-index] + if signature == "-": + # [index] + index = int(predicate[0]) - 1 + if index < 0: + if index == -1: + raise SyntaxError( + "indices in path predicates are 1-based, not 0-based") + else: + raise SyntaxError("path index >= 1 expected") + else: + if predicate[0] != "last": + raise SyntaxError("unsupported function") + if signature == "-()-": + try: + index = int(predicate[2]) - 1 + except ValueError: + raise SyntaxError("unsupported expression") + else: + index = -1 + def select(result): + for elem in result: + parent = elem.getparent() + if parent is None: + continue + try: + # FIXME: what if the selector is "*" ? + elems = list(parent.iterchildren(elem.tag)) + if elems[index] is elem: + yield elem + except IndexError: + pass + return select + raise SyntaxError("invalid predicate") + +ops = { + "": prepare_child, + "*": prepare_star, + ".": prepare_self, + "..": prepare_parent, + "//": prepare_descendant, + "[": prepare_predicate, +} + + +# -------------------------------------------------------------------- + +_cache = {} + + +def _build_path_iterator(path, namespaces): + """compile selector pattern""" + if path[-1:] == "/": + path += "*" # implicit all (FIXME: keep this?) + + cache_key = (path,) + if namespaces: + # lxml originally used None for the default namespace but ElementTree uses the + # more convenient (all-strings-dict) empty string, so we support both here, + # preferring the more convenient '', as long as they aren't ambiguous. + if None in namespaces: + if '' in namespaces and namespaces[None] != namespaces['']: + raise ValueError("Ambiguous default namespace provided: %r versus %r" % ( + namespaces[None], namespaces[''])) + cache_key += (namespaces[None],) + tuple(sorted( + item for item in namespaces.items() if item[0] is not None)) + else: + cache_key += tuple(sorted(namespaces.items())) + + try: + return _cache[cache_key] + except KeyError: + pass + if len(_cache) > 100: + _cache.clear() + + if path[:1] == "/": + raise SyntaxError("cannot use absolute path on element") + stream = iter(xpath_tokenizer(path, namespaces)) + try: + _next = stream.next + except AttributeError: + # Python 3 + _next = stream.__next__ + try: + token = _next() + except StopIteration: + raise SyntaxError("empty path expression") + selector = [] + while 1: + try: + selector.append(ops[token[0]](_next, token)) + except StopIteration: + raise SyntaxError("invalid path") + try: + token = _next() + if token[0] == "/": + token = _next() + except StopIteration: + break + _cache[cache_key] = selector + return selector + + +## +# Iterate over the matching nodes + +def iterfind(elem, path, namespaces=None): + selector = _build_path_iterator(path, namespaces) + result = iter((elem,)) + for select in selector: + result = select(result) + return result + + +## +# Find first matching object. + +def find(elem, path, namespaces=None): + it = iterfind(elem, path, namespaces) + try: + return next(it) + except StopIteration: + return None + + +## +# Find all matching objects. + +def findall(elem, path, namespaces=None): + return list(iterfind(elem, path, namespaces)) + + +## +# Find text for first matching object. + +def findtext(elem, path, default=None, namespaces=None): + el = find(elem, path, namespaces) + if el is None: + return default + else: + return el.text or '' diff --git a/.venv/lib/python3.7/site-packages/lxml/apihelpers.pxi b/.venv/lib/python3.7/site-packages/lxml/apihelpers.pxi new file mode 100644 index 0000000..9fae9fb --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/apihelpers.pxi @@ -0,0 +1,1819 @@ +# Private/public helper functions for API functions + +from lxml.includes cimport uri + + +cdef void displayNode(xmlNode* c_node, indent): + # to help with debugging + cdef xmlNode* c_child + try: + print indent * u' ', c_node + c_child = c_node.children + while c_child is not NULL: + displayNode(c_child, indent + 1) + c_child = c_child.next + finally: + return # swallow any exceptions + +cdef inline int _assertValidNode(_Element element) except -1: + assert element._c_node is not NULL, u"invalid Element proxy at %s" % id(element) + +cdef inline int _assertValidDoc(_Document doc) except -1: + assert doc._c_doc is not NULL, u"invalid Document proxy at %s" % id(doc) + +cdef _Document _documentOrRaise(object input): + u"""Call this to get the document of a _Document, _ElementTree or _Element + object, or to raise an exception if it can't be determined. + + Should be used in all API functions for consistency. + """ + cdef _Document doc + if isinstance(input, _ElementTree): + if (<_ElementTree>input)._context_node is not None: + doc = (<_ElementTree>input)._context_node._doc + else: + doc = None + elif isinstance(input, _Element): + doc = (<_Element>input)._doc + elif isinstance(input, _Document): + doc = <_Document>input + else: + raise TypeError, f"Invalid input object: {python._fqtypename(input).decode('utf8')}" + if doc is None: + raise ValueError, f"Input object has no document: {python._fqtypename(input).decode('utf8')}" + _assertValidDoc(doc) + return doc + +cdef _Element _rootNodeOrRaise(object input): + u"""Call this to get the root node of a _Document, _ElementTree or + _Element object, or to raise an exception if it can't be determined. + + Should be used in all API functions for consistency. + """ + cdef _Element node + if isinstance(input, _ElementTree): + node = (<_ElementTree>input)._context_node + elif isinstance(input, _Element): + node = <_Element>input + elif isinstance(input, _Document): + node = (<_Document>input).getroot() + else: + raise TypeError, f"Invalid input object: {python._fqtypename(input).decode('utf8')}" + if (node is None or not node._c_node or + node._c_node.type != tree.XML_ELEMENT_NODE): + raise ValueError, f"Input object is not an XML element: {python._fqtypename(input).decode('utf8')}" + _assertValidNode(node) + return node + +cdef bint _isAncestorOrSame(xmlNode* c_ancestor, xmlNode* c_node): + while c_node: + if c_node is c_ancestor: + return True + c_node = c_node.parent + return False + +cdef _Element _makeElement(tag, xmlDoc* c_doc, _Document doc, + _BaseParser parser, text, tail, attrib, nsmap, + dict extra_attrs): + u"""Create a new element and initialize text content, namespaces and + attributes. + + This helper function will reuse as much of the existing document as + possible: + + If 'parser' is None, the parser will be inherited from 'doc' or the + default parser will be used. + + If 'doc' is None, 'c_doc' is used to create a new _Document and the new + element is made its root node. + + If 'c_doc' is also NULL, a new xmlDoc will be created. + """ + cdef xmlNode* c_node + if doc is not None: + c_doc = doc._c_doc + ns_utf, name_utf = _getNsTag(tag) + if parser is not None and parser._for_html: + _htmlTagValidOrRaise(name_utf) + if c_doc is NULL: + c_doc = _newHTMLDoc() + else: + _tagValidOrRaise(name_utf) + if c_doc is NULL: + c_doc = _newXMLDoc() + c_node = _createElement(c_doc, name_utf) + if c_node is NULL: + if doc is None and c_doc is not NULL: + tree.xmlFreeDoc(c_doc) + raise MemoryError() + try: + if doc is None: + tree.xmlDocSetRootElement(c_doc, c_node) + doc = _documentFactory(c_doc, parser) + if text is not None: + _setNodeText(c_node, text) + if tail is not None: + _setTailText(c_node, tail) + # add namespaces to node if necessary + _setNodeNamespaces(c_node, doc, ns_utf, nsmap) + _initNodeAttributes(c_node, doc, attrib, extra_attrs) + return _elementFactory(doc, c_node) + except: + # free allocated c_node/c_doc unless Python does it for us + if c_node.doc is not c_doc: + # node not yet in document => will not be freed by document + if tail is not None: + _removeText(c_node.next) # tail + tree.xmlFreeNode(c_node) + if doc is None: + # c_doc will not be freed by doc + tree.xmlFreeDoc(c_doc) + raise + +cdef int _initNewElement(_Element element, bint is_html, name_utf, ns_utf, + _BaseParser parser, attrib, nsmap, dict extra_attrs) except -1: + u"""Initialise a new Element object. + + This is used when users instantiate a Python Element subclass + directly, without it being mapped to an existing XML node. + """ + cdef xmlDoc* c_doc + cdef xmlNode* c_node + cdef _Document doc + if is_html: + _htmlTagValidOrRaise(name_utf) + c_doc = _newHTMLDoc() + else: + _tagValidOrRaise(name_utf) + c_doc = _newXMLDoc() + c_node = _createElement(c_doc, name_utf) + if c_node is NULL: + if c_doc is not NULL: + tree.xmlFreeDoc(c_doc) + raise MemoryError() + tree.xmlDocSetRootElement(c_doc, c_node) + doc = _documentFactory(c_doc, parser) + # add namespaces to node if necessary + _setNodeNamespaces(c_node, doc, ns_utf, nsmap) + _initNodeAttributes(c_node, doc, attrib, extra_attrs) + _registerProxy(element, doc, c_node) + element._init() + return 0 + +cdef _Element _makeSubElement(_Element parent, tag, text, tail, + attrib, nsmap, dict extra_attrs): + u"""Create a new child element and initialize text content, namespaces and + attributes. + """ + cdef xmlNode* c_node + cdef xmlDoc* c_doc + if parent is None or parent._doc is None: + return None + _assertValidNode(parent) + ns_utf, name_utf = _getNsTag(tag) + c_doc = parent._doc._c_doc + + if parent._doc._parser is not None and parent._doc._parser._for_html: + _htmlTagValidOrRaise(name_utf) + else: + _tagValidOrRaise(name_utf) + + c_node = _createElement(c_doc, name_utf) + if c_node is NULL: + raise MemoryError() + tree.xmlAddChild(parent._c_node, c_node) + + try: + if text is not None: + _setNodeText(c_node, text) + if tail is not None: + _setTailText(c_node, tail) + + # add namespaces to node if necessary + _setNodeNamespaces(c_node, parent._doc, ns_utf, nsmap) + _initNodeAttributes(c_node, parent._doc, attrib, extra_attrs) + return _elementFactory(parent._doc, c_node) + except: + # make sure we clean up in case of an error + _removeNode(parent._doc, c_node) + raise + + +cdef int _setNodeNamespaces(xmlNode* c_node, _Document doc, + object node_ns_utf, object nsmap) except -1: + u"""Lookup current namespace prefixes, then set namespace structure for + node (if 'node_ns_utf' was provided) and register new ns-prefix mappings. + + 'node_ns_utf' should only be passed for a newly created node. + """ + cdef xmlNs* c_ns + cdef list nsdefs + + if nsmap: + for prefix, href in _iter_nsmap(nsmap): + href_utf = _utf8(href) + _uriValidOrRaise(href_utf) + c_href = _xcstr(href_utf) + if prefix is not None: + prefix_utf = _utf8(prefix) + _prefixValidOrRaise(prefix_utf) + c_prefix = _xcstr(prefix_utf) + else: + c_prefix = NULL + # add namespace with prefix if it is not already known + c_ns = tree.xmlSearchNs(doc._c_doc, c_node, c_prefix) + if c_ns is NULL or \ + c_ns.href is NULL or \ + tree.xmlStrcmp(c_ns.href, c_href) != 0: + c_ns = tree.xmlNewNs(c_node, c_href, c_prefix) + if href_utf == node_ns_utf: + tree.xmlSetNs(c_node, c_ns) + node_ns_utf = None + + if node_ns_utf is not None: + _uriValidOrRaise(node_ns_utf) + doc._setNodeNs(c_node, _xcstr(node_ns_utf)) + return 0 + + +cdef dict _build_nsmap(xmlNode* c_node): + """ + Namespace prefix->URI mapping known in the context of this Element. + This includes all namespace declarations of the parents. + """ + cdef xmlNs* c_ns + nsmap = {} + while c_node is not NULL and c_node.type == tree.XML_ELEMENT_NODE: + c_ns = c_node.nsDef + while c_ns is not NULL: + if c_ns.prefix or c_ns.href: + prefix = funicodeOrNone(c_ns.prefix) + if prefix not in nsmap: + nsmap[prefix] = funicodeOrNone(c_ns.href) + c_ns = c_ns.next + c_node = c_node.parent + return nsmap + + +cdef _iter_nsmap(nsmap): + """ + Create a reproducibly ordered iterable from an nsmap mapping. + Tries to preserve an existing order and sorts if it assumes no order. + + The difference to _iter_attrib() is that None doesn't sort with strings + in Py3.x. + """ + if python.PY_VERSION_HEX >= 0x03060000: + # dicts are insertion-ordered in Py3.6+ => keep the user provided order. + if isinstance(nsmap, dict): + return nsmap.items() + if len(nsmap) <= 1: + return nsmap.items() + # nsmap will usually be a plain unordered dict => avoid type checking overhead + if type(nsmap) is not dict and isinstance(nsmap, OrderedDict): + return nsmap.items() # keep existing order + if None not in nsmap: + return sorted(nsmap.items()) + + # Move the default namespace to the end. This makes sure libxml2 + # prefers a prefix if the ns is defined redundantly on the same + # element. That way, users can work around a problem themselves + # where default namespace attributes on non-default namespaced + # elements serialise without prefix (i.e. into the non-default + # namespace). + default_ns = nsmap[None] + nsdefs = [(k, v) for k, v in nsmap.items() if k is not None] + nsdefs.sort() + nsdefs.append((None, default_ns)) + return nsdefs + + +cdef _iter_attrib(attrib): + """ + Create a reproducibly ordered iterable from an attrib mapping. + Tries to preserve an existing order and sorts if it assumes no order. + """ + # dicts are insertion-ordered in Py3.6+ => keep the user provided order. + if python.PY_VERSION_HEX >= 0x03060000 and isinstance(attrib, dict) or ( + isinstance(attrib, (_Attrib, OrderedDict))): + return attrib.items() + # assume it's an unordered mapping of some kind + return sorted(attrib.items()) + + +cdef _initNodeAttributes(xmlNode* c_node, _Document doc, attrib, dict extra): + u"""Initialise the attributes of an element node. + """ + cdef bint is_html + cdef xmlNs* c_ns + if attrib is not None and not hasattr(attrib, u'items'): + raise TypeError, f"Invalid attribute dictionary: {python._fqtypename(attrib).decode('utf8')}" + if not attrib and not extra: + return # nothing to do + is_html = doc._parser._for_html + seen = set() + if extra: + if python.PY_VERSION_HEX >= 0x03060000: + for name, value in extra.items(): + _addAttributeToNode(c_node, doc, is_html, name, value, seen) + else: + for name, value in sorted(extra.items()): + _addAttributeToNode(c_node, doc, is_html, name, value, seen) + if attrib: + for name, value in _iter_attrib(attrib): + _addAttributeToNode(c_node, doc, is_html, name, value, seen) + + +cdef int _addAttributeToNode(xmlNode* c_node, _Document doc, bint is_html, + name, value, set seen_tags) except -1: + ns_utf, name_utf = tag = _getNsTag(name) + if tag in seen_tags: + return 0 + seen_tags.add(tag) + if not is_html: + _attributeValidOrRaise(name_utf) + value_utf = _utf8(value) + if ns_utf is None: + tree.xmlNewProp(c_node, _xcstr(name_utf), _xcstr(value_utf)) + else: + _uriValidOrRaise(ns_utf) + c_ns = doc._findOrBuildNodeNs(c_node, _xcstr(ns_utf), NULL, 1) + tree.xmlNewNsProp(c_node, c_ns, + _xcstr(name_utf), _xcstr(value_utf)) + return 0 + + +ctypedef struct _ns_node_ref: + xmlNs* ns + xmlNode* node + + +cdef int _collectNsDefs(xmlNode* c_element, _ns_node_ref **_c_ns_list, + size_t *_c_ns_list_len, size_t *_c_ns_list_size) except -1: + c_ns_list = _c_ns_list[0] + cdef size_t c_ns_list_len = _c_ns_list_len[0] + cdef size_t c_ns_list_size = _c_ns_list_size[0] + + c_nsdef = c_element.nsDef + while c_nsdef is not NULL: + if c_ns_list_len >= c_ns_list_size: + if c_ns_list is NULL: + c_ns_list_size = 20 + else: + c_ns_list_size *= 2 + c_nsref_ptr = <_ns_node_ref*> python.lxml_realloc( + c_ns_list, c_ns_list_size, sizeof(_ns_node_ref)) + if c_nsref_ptr is NULL: + if c_ns_list is not NULL: + python.lxml_free(c_ns_list) + _c_ns_list[0] = NULL + raise MemoryError() + c_ns_list = c_nsref_ptr + + c_ns_list[c_ns_list_len] = _ns_node_ref(c_nsdef, c_element) + c_ns_list_len += 1 + c_nsdef = c_nsdef.next + + _c_ns_list_size[0] = c_ns_list_size + _c_ns_list_len[0] = c_ns_list_len + _c_ns_list[0] = c_ns_list + + +cdef int _removeUnusedNamespaceDeclarations(xmlNode* c_element, set prefixes_to_keep) except -1: + u"""Remove any namespace declarations from a subtree that are not used by + any of its elements (or attributes). + + If a 'prefixes_to_keep' is provided, it must be a set of prefixes. + Any corresponding namespace mappings will not be removed as part of the cleanup. + """ + cdef xmlNode* c_node + cdef _ns_node_ref* c_ns_list = NULL + cdef size_t c_ns_list_size = 0 + cdef size_t c_ns_list_len = 0 + cdef size_t i + + if c_element.parent and c_element.parent.type == tree.XML_DOCUMENT_NODE: + # include declarations on the document node + _collectNsDefs(c_element.parent, &c_ns_list, &c_ns_list_len, &c_ns_list_size) + + tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_element, c_element, 1) + # collect all new namespace declarations into the ns list + if c_element.nsDef: + _collectNsDefs(c_element, &c_ns_list, &c_ns_list_len, &c_ns_list_size) + + # remove all namespace declarations from the list that are referenced + if c_ns_list_len and c_element.type == tree.XML_ELEMENT_NODE: + c_node = c_element + while c_node and c_ns_list_len: + if c_node.ns: + for i in range(c_ns_list_len): + if c_node.ns is c_ns_list[i].ns: + c_ns_list_len -= 1 + c_ns_list[i] = c_ns_list[c_ns_list_len] + #c_ns_list[c_ns_list_len] = _ns_node_ref(NULL, NULL) + break + if c_node is c_element: + # continue with attributes + c_node = c_element.properties + else: + c_node = c_node.next + tree.END_FOR_EACH_ELEMENT_FROM(c_element) + + if c_ns_list is NULL: + return 0 + + # free all namespace declarations that remained in the list, + # except for those we should keep explicitly + cdef xmlNs* c_nsdef + for i in range(c_ns_list_len): + if prefixes_to_keep is not None: + if c_ns_list[i].ns.prefix and c_ns_list[i].ns.prefix in prefixes_to_keep: + continue + c_node = c_ns_list[i].node + c_nsdef = c_node.nsDef + if c_nsdef is c_ns_list[i].ns: + c_node.nsDef = c_node.nsDef.next + else: + while c_nsdef.next is not c_ns_list[i].ns: + c_nsdef = c_nsdef.next + c_nsdef.next = c_nsdef.next.next + tree.xmlFreeNs(c_ns_list[i].ns) + + if c_ns_list is not NULL: + python.lxml_free(c_ns_list) + return 0 + +cdef xmlNs* _searchNsByHref(xmlNode* c_node, const_xmlChar* c_href, bint is_attribute): + u"""Search a namespace declaration that covers a node (element or + attribute). + + For attributes, try to find a prefixed namespace declaration + instead of the default namespaces. This helps in supporting + round-trips for attributes on elements with a different namespace. + """ + cdef xmlNs* c_ns + cdef xmlNs* c_default_ns = NULL + cdef xmlNode* c_element + if c_href is NULL or c_node is NULL or c_node.type == tree.XML_ENTITY_REF_NODE: + return NULL + if tree.xmlStrcmp(c_href, tree.XML_XML_NAMESPACE) == 0: + # no special cases here, let libxml2 handle this + return tree.xmlSearchNsByHref(c_node.doc, c_node, c_href) + if c_node.type == tree.XML_ATTRIBUTE_NODE: + is_attribute = 1 + while c_node is not NULL and c_node.type != tree.XML_ELEMENT_NODE: + c_node = c_node.parent + c_element = c_node + while c_node is not NULL: + if c_node.type == tree.XML_ELEMENT_NODE: + c_ns = c_node.nsDef + while c_ns is not NULL: + if c_ns.href is not NULL and tree.xmlStrcmp(c_href, c_ns.href) == 0: + if c_ns.prefix is NULL and is_attribute: + # for attributes, continue searching a named + # prefix, but keep the first default namespace + # declaration that we found + if c_default_ns is NULL: + c_default_ns = c_ns + elif tree.xmlSearchNs( + c_element.doc, c_element, c_ns.prefix) is c_ns: + # start node is in namespace scope => found! + return c_ns + c_ns = c_ns.next + if c_node is not c_element and c_node.ns is not NULL: + # optimise: the node may have the namespace itself + c_ns = c_node.ns + if c_ns.href is not NULL and tree.xmlStrcmp(c_href, c_ns.href) == 0: + if c_ns.prefix is NULL and is_attribute: + # for attributes, continue searching a named + # prefix, but keep the first default namespace + # declaration that we found + if c_default_ns is NULL: + c_default_ns = c_ns + elif tree.xmlSearchNs( + c_element.doc, c_element, c_ns.prefix) is c_ns: + # start node is in namespace scope => found! + return c_ns + c_node = c_node.parent + # nothing found => use a matching default namespace or fail + if c_default_ns is not NULL: + if tree.xmlSearchNs(c_element.doc, c_element, NULL) is c_default_ns: + return c_default_ns + return NULL + +cdef int _replaceNodeByChildren(_Document doc, xmlNode* c_node) except -1: + # NOTE: this does not deallocate the node, just unlink it! + cdef xmlNode* c_parent + cdef xmlNode* c_child + if c_node.children is NULL: + tree.xmlUnlinkNode(c_node) + return 0 + + c_parent = c_node.parent + # fix parent links of children + c_child = c_node.children + while c_child is not NULL: + c_child.parent = c_parent + c_child = c_child.next + + # fix namespace references of children if their parent's namespace + # declarations get lost + if c_node.nsDef is not NULL: + c_child = c_node.children + while c_child is not NULL: + moveNodeToDocument(doc, doc._c_doc, c_child) + c_child = c_child.next + + # fix sibling links to/from child slice + if c_node.prev is NULL: + c_parent.children = c_node.children + else: + c_node.prev.next = c_node.children + c_node.children.prev = c_node.prev + if c_node.next is NULL: + c_parent.last = c_node.last + else: + c_node.next.prev = c_node.last + c_node.last.next = c_node.next + + # unlink c_node + c_node.children = c_node.last = NULL + c_node.parent = c_node.next = c_node.prev = NULL + return 0 + +cdef object _attributeValue(xmlNode* c_element, xmlAttr* c_attrib_node): + c_href = _getNs(c_attrib_node) + value = tree.xmlGetNsProp(c_element, c_attrib_node.name, c_href) + try: + result = funicode(value) + finally: + tree.xmlFree(value) + return result + +cdef object _attributeValueFromNsName(xmlNode* c_element, + const_xmlChar* c_href, const_xmlChar* c_name): + c_result = tree.xmlGetNsProp(c_element, c_name, c_href) + if c_result is NULL: + return None + try: + result = funicode(c_result) + finally: + tree.xmlFree(c_result) + return result + +cdef object _getNodeAttributeValue(xmlNode* c_node, key, default): + ns, tag = _getNsTag(key) + c_href = NULL if ns is None else _xcstr(ns) + c_result = tree.xmlGetNsProp(c_node, _xcstr(tag), c_href) + if c_result is NULL: + # XXX free namespace that is not in use..? + return default + try: + result = funicode(c_result) + finally: + tree.xmlFree(c_result) + return result + +cdef inline object _getAttributeValue(_Element element, key, default): + return _getNodeAttributeValue(element._c_node, key, default) + +cdef int _setAttributeValue(_Element element, key, value) except -1: + cdef const_xmlChar* c_value + cdef xmlNs* c_ns + ns, tag = _getNsTag(key) + is_html = element._doc._parser._for_html + if not is_html: + _attributeValidOrRaise(tag) + c_tag = _xcstr(tag) + if value is None and is_html: + c_value = NULL + else: + if isinstance(value, QName): + value = _resolveQNameText(element, value) + else: + value = _utf8(value) + c_value = _xcstr(value) + if ns is None: + c_ns = NULL + else: + c_ns = element._doc._findOrBuildNodeNs(element._c_node, _xcstr(ns), NULL, 1) + tree.xmlSetNsProp(element._c_node, c_ns, c_tag, c_value) + return 0 + +cdef int _delAttribute(_Element element, key) except -1: + ns, tag = _getNsTag(key) + c_href = NULL if ns is None else _xcstr(ns) + if _delAttributeFromNsName(element._c_node, c_href, _xcstr(tag)): + raise KeyError, key + return 0 + +cdef int _delAttributeFromNsName(xmlNode* c_node, const_xmlChar* c_href, const_xmlChar* c_name): + c_attr = tree.xmlHasNsProp(c_node, c_name, c_href) + if c_attr is NULL: + # XXX free namespace that is not in use..? + return -1 + tree.xmlRemoveProp(c_attr) + return 0 + +cdef list _collectAttributes(xmlNode* c_node, int collecttype): + u"""Collect all attributes of a node in a list. Depending on collecttype, + it collects either the name (1), the value (2) or the name-value tuples. + """ + cdef Py_ssize_t count + c_attr = c_node.properties + count = 0 + while c_attr is not NULL: + if c_attr.type == tree.XML_ATTRIBUTE_NODE: + count += 1 + c_attr = c_attr.next + + if not count: + return [] + + attributes = [None] * count + c_attr = c_node.properties + count = 0 + while c_attr is not NULL: + if c_attr.type == tree.XML_ATTRIBUTE_NODE: + if collecttype == 1: + item = _namespacedName(c_attr) + elif collecttype == 2: + item = _attributeValue(c_node, c_attr) + else: + item = (_namespacedName(c_attr), + _attributeValue(c_node, c_attr)) + attributes[count] = item + count += 1 + c_attr = c_attr.next + return attributes + +cdef object __RE_XML_ENCODING = re.compile( + ur'^(<\?xml[^>]+)\s+encoding\s*=\s*["\'][^"\']*["\'](\s*\?>|)', re.U) + +cdef object __REPLACE_XML_ENCODING = __RE_XML_ENCODING.sub +cdef object __HAS_XML_ENCODING = __RE_XML_ENCODING.match + +cdef object _stripEncodingDeclaration(object xml_string): + # this is a hack to remove the XML encoding declaration from unicode + return __REPLACE_XML_ENCODING(ur'\g<1>\g<2>', xml_string) + +cdef bint _hasEncodingDeclaration(object xml_string) except -1: + # check if a (unicode) string has an XML encoding declaration + return __HAS_XML_ENCODING(xml_string) is not None + +cdef inline bint _hasText(xmlNode* c_node): + return c_node is not NULL and _textNodeOrSkip(c_node.children) is not NULL + +cdef inline bint _hasTail(xmlNode* c_node): + return c_node is not NULL and _textNodeOrSkip(c_node.next) is not NULL + +cdef inline bint _hasNonWhitespaceTail(xmlNode* c_node): + return _hasNonWhitespaceText(c_node, tail=True) + +cdef bint _hasNonWhitespaceText(xmlNode* c_node, bint tail=False): + c_text_node = c_node and _textNodeOrSkip(c_node.next if tail else c_node.children) + if c_text_node is NULL: + return False + while c_text_node is not NULL: + if c_text_node.content[0] != c'\0' and not _collectText(c_text_node).isspace(): + return True + c_text_node = _textNodeOrSkip(c_text_node.next) + return False + +cdef _collectText(xmlNode* c_node): + u"""Collect all text nodes and return them as a unicode string. + + Start collecting at c_node. + + If there was no text to collect, return None + """ + cdef Py_ssize_t scount + cdef xmlChar* c_text + cdef xmlNode* c_node_cur + # check for multiple text nodes + scount = 0 + c_text = NULL + c_node_cur = c_node = _textNodeOrSkip(c_node) + while c_node_cur is not NULL: + if c_node_cur.content[0] != c'\0': + c_text = c_node_cur.content + scount += 1 + c_node_cur = _textNodeOrSkip(c_node_cur.next) + + # handle two most common cases first + if c_text is NULL: + return '' if scount > 0 else None + if scount == 1: + return funicode(c_text) + + # the rest is not performance critical anymore + result = b'' + while c_node is not NULL: + result += c_node.content + c_node = _textNodeOrSkip(c_node.next) + return funicode(result) + +cdef void _removeText(xmlNode* c_node): + u"""Remove all text nodes. + + Start removing at c_node. + """ + cdef xmlNode* c_next + c_node = _textNodeOrSkip(c_node) + while c_node is not NULL: + c_next = _textNodeOrSkip(c_node.next) + tree.xmlUnlinkNode(c_node) + tree.xmlFreeNode(c_node) + c_node = c_next + +cdef xmlNode* _createTextNode(xmlDoc* doc, value) except NULL: + cdef xmlNode* c_text_node + if isinstance(value, CDATA): + c_text_node = tree.xmlNewCDataBlock( + doc, _xcstr((value)._utf8_data), + python.PyBytes_GET_SIZE((value)._utf8_data)) + else: + text = _utf8(value) + c_text_node = tree.xmlNewDocText(doc, _xcstr(text)) + if not c_text_node: + raise MemoryError() + return c_text_node + +cdef int _setNodeText(xmlNode* c_node, value) except -1: + # remove all text nodes at the start first + _removeText(c_node.children) + if value is None: + return 0 + # now add new text node with value at start + c_text_node = _createTextNode(c_node.doc, value) + if c_node.children is NULL: + tree.xmlAddChild(c_node, c_text_node) + else: + tree.xmlAddPrevSibling(c_node.children, c_text_node) + return 0 + +cdef int _setTailText(xmlNode* c_node, value) except -1: + # remove all text nodes at the start first + _removeText(c_node.next) + if value is None: + return 0 + # now append new text node with value + c_text_node = _createTextNode(c_node.doc, value) + tree.xmlAddNextSibling(c_node, c_text_node) + return 0 + +cdef bytes _resolveQNameText(_Element element, value): + cdef xmlNs* c_ns + ns, tag = _getNsTag(value) + if ns is None: + return tag + else: + c_ns = element._doc._findOrBuildNodeNs( + element._c_node, _xcstr(ns), NULL, 0) + return python.PyBytes_FromFormat('%s:%s', c_ns.prefix, _cstr(tag)) + +cdef inline bint _hasChild(xmlNode* c_node): + return c_node is not NULL and _findChildForwards(c_node, 0) is not NULL + +cdef inline Py_ssize_t _countElements(xmlNode* c_node): + u"Counts the elements within the following siblings and the node itself." + cdef Py_ssize_t count + count = 0 + while c_node is not NULL: + if _isElement(c_node): + count += 1 + c_node = c_node.next + return count + +cdef int _findChildSlice( + slice sliceobject, xmlNode* c_parent, + xmlNode** c_start_node, Py_ssize_t* c_step, Py_ssize_t* c_length) except -1: + u"""Resolve a children slice. + + Returns the start node, step size and the slice length in the + pointer arguments. + """ + cdef Py_ssize_t start = 0, stop = 0, childcount + childcount = _countElements(c_parent.children) + if childcount == 0: + c_start_node[0] = NULL + c_length[0] = 0 + if sliceobject.step is None: + c_step[0] = 1 + else: + python._PyEval_SliceIndex(sliceobject.step, c_step) + return 0 + python.PySlice_GetIndicesEx( + sliceobject, childcount, &start, &stop, c_step, c_length) + if start > childcount / 2: + c_start_node[0] = _findChildBackwards(c_parent, childcount - start - 1) + else: + c_start_node[0] = _findChild(c_parent, start) + return 0 + +cdef bint _isFullSlice(slice sliceobject) except -1: + u"""Conservative guess if this slice is a full slice as in ``s[:]``. + """ + cdef Py_ssize_t step = 0 + if sliceobject is None: + return 0 + if sliceobject.start is None and \ + sliceobject.stop is None: + if sliceobject.step is None: + return 1 + python._PyEval_SliceIndex(sliceobject.step, &step) + if step == 1: + return 1 + return 0 + return 0 + +cdef _collectChildren(_Element element): + cdef xmlNode* c_node + cdef list result = [] + c_node = element._c_node.children + if c_node is not NULL: + if not _isElement(c_node): + c_node = _nextElement(c_node) + while c_node is not NULL: + result.append(_elementFactory(element._doc, c_node)) + c_node = _nextElement(c_node) + return result + +cdef inline xmlNode* _findChild(xmlNode* c_node, Py_ssize_t index): + if index < 0: + return _findChildBackwards(c_node, -index - 1) + else: + return _findChildForwards(c_node, index) + +cdef inline xmlNode* _findChildForwards(xmlNode* c_node, Py_ssize_t index): + u"""Return child element of c_node with index, or return NULL if not found. + """ + cdef xmlNode* c_child + cdef Py_ssize_t c + c_child = c_node.children + c = 0 + while c_child is not NULL: + if _isElement(c_child): + if c == index: + return c_child + c += 1 + c_child = c_child.next + return NULL + +cdef inline xmlNode* _findChildBackwards(xmlNode* c_node, Py_ssize_t index): + u"""Return child element of c_node with index, or return NULL if not found. + Search from the end. + """ + cdef xmlNode* c_child + cdef Py_ssize_t c + c_child = c_node.last + c = 0 + while c_child is not NULL: + if _isElement(c_child): + if c == index: + return c_child + c += 1 + c_child = c_child.prev + return NULL + +cdef inline xmlNode* _textNodeOrSkip(xmlNode* c_node) nogil: + u"""Return the node if it's a text node. Skip over ignorable nodes in a + series of text nodes. Return NULL if a non-ignorable node is found. + + This is used to skip over XInclude nodes when collecting adjacent text + nodes. + """ + while c_node is not NULL: + if c_node.type == tree.XML_TEXT_NODE or \ + c_node.type == tree.XML_CDATA_SECTION_NODE: + return c_node + elif c_node.type == tree.XML_XINCLUDE_START or \ + c_node.type == tree.XML_XINCLUDE_END: + c_node = c_node.next + else: + return NULL + return NULL + +cdef inline xmlNode* _nextElement(xmlNode* c_node): + u"""Given a node, find the next sibling that is an element. + """ + if c_node is NULL: + return NULL + c_node = c_node.next + while c_node is not NULL: + if _isElement(c_node): + return c_node + c_node = c_node.next + return NULL + +cdef inline xmlNode* _previousElement(xmlNode* c_node): + u"""Given a node, find the next sibling that is an element. + """ + if c_node is NULL: + return NULL + c_node = c_node.prev + while c_node is not NULL: + if _isElement(c_node): + return c_node + c_node = c_node.prev + return NULL + +cdef inline xmlNode* _parentElement(xmlNode* c_node): + u"Given a node, find the parent element." + if c_node is NULL or not _isElement(c_node): + return NULL + c_node = c_node.parent + if c_node is NULL or not _isElement(c_node): + return NULL + return c_node + +cdef inline bint _tagMatches(xmlNode* c_node, const_xmlChar* c_href, const_xmlChar* c_name): + u"""Tests if the node matches namespace URI and tag name. + + A node matches if it matches both c_href and c_name. + + A node matches c_href if any of the following is true: + * c_href is NULL + * its namespace is NULL and c_href is the empty string + * its namespace string equals the c_href string + + A node matches c_name if any of the following is true: + * c_name is NULL + * its name string equals the c_name string + """ + if c_node is NULL: + return 0 + if c_node.type != tree.XML_ELEMENT_NODE: + # not an element, only succeed if we match everything + return c_name is NULL and c_href is NULL + if c_name is NULL: + if c_href is NULL: + # always match + return 1 + else: + c_node_href = _getNs(c_node) + if c_node_href is NULL: + return c_href[0] == c'\0' + else: + return tree.xmlStrcmp(c_node_href, c_href) == 0 + elif c_href is NULL: + if _getNs(c_node) is not NULL: + return 0 + return c_node.name == c_name or tree.xmlStrcmp(c_node.name, c_name) == 0 + elif c_node.name == c_name or tree.xmlStrcmp(c_node.name, c_name) == 0: + c_node_href = _getNs(c_node) + if c_node_href is NULL: + return c_href[0] == c'\0' + else: + return tree.xmlStrcmp(c_node_href, c_href) == 0 + else: + return 0 + +cdef inline bint _tagMatchesExactly(xmlNode* c_node, qname* c_qname): + u"""Tests if the node matches namespace URI and tag name. + + This differs from _tagMatches() in that it does not consider a + NULL value in qname.href a wildcard, and that it expects the c_name + to be taken from the doc dict, i.e. it only compares the names by + address. + + A node matches if it matches both href and c_name of the qname. + + A node matches c_href if any of the following is true: + * its namespace is NULL and c_href is the empty string + * its namespace string equals the c_href string + + A node matches c_name if any of the following is true: + * c_name is NULL + * its name string points to the same address (!) as c_name + """ + return _nsTagMatchesExactly(_getNs(c_node), c_node.name, c_qname) + +cdef inline bint _nsTagMatchesExactly(const_xmlChar* c_node_href, + const_xmlChar* c_node_name, + qname* c_qname): + u"""Tests if name and namespace URI match those of c_qname. + + This differs from _tagMatches() in that it does not consider a + NULL value in qname.href a wildcard, and that it expects the c_name + to be taken from the doc dict, i.e. it only compares the names by + address. + + A node matches if it matches both href and c_name of the qname. + + A node matches c_href if any of the following is true: + * its namespace is NULL and c_href is the empty string + * its namespace string equals the c_href string + + A node matches c_name if any of the following is true: + * c_name is NULL + * its name string points to the same address (!) as c_name + """ + cdef char* c_href + if c_qname.c_name is not NULL and c_qname.c_name is not c_node_name: + return 0 + if c_qname.href is NULL: + return 1 + c_href = python.__cstr(c_qname.href) + if c_href[0] == '\0': + return c_node_href is NULL or c_node_href[0] == '\0' + elif c_node_href is NULL: + return 0 + else: + return tree.xmlStrcmp(c_href, c_node_href) == 0 + +cdef Py_ssize_t _mapTagsToQnameMatchArray(xmlDoc* c_doc, list ns_tags, + qname* c_ns_tags, bint force_into_dict) except -1: + u"""Map a sequence of (name, namespace) pairs to a qname array for efficient + matching with _tagMatchesExactly() above. + + Note that each qname struct in the array owns its href byte string object + if it is not NULL. + """ + cdef Py_ssize_t count = 0, i + cdef bytes ns, tag + for ns, tag in ns_tags: + if tag is None: + c_tag = NULL + elif force_into_dict: + c_tag = tree.xmlDictLookup(c_doc.dict, _xcstr(tag), len(tag)) + if c_tag is NULL: + # clean up before raising the error + for i in xrange(count): + cpython.ref.Py_XDECREF(c_ns_tags[i].href) + raise MemoryError() + else: + c_tag = tree.xmlDictExists(c_doc.dict, _xcstr(tag), len(tag)) + if c_tag is NULL: + # not in the dict => not in the document + continue + c_ns_tags[count].c_name = c_tag + if ns is None: + c_ns_tags[count].href = NULL + else: + cpython.ref.Py_INCREF(ns) # keep an owned reference! + c_ns_tags[count].href = ns + count += 1 + return count + +cdef int _removeNode(_Document doc, xmlNode* c_node) except -1: + u"""Unlink and free a node and subnodes if possible. Otherwise, make sure + it's self-contained. + """ + cdef xmlNode* c_next + c_next = c_node.next + tree.xmlUnlinkNode(c_node) + _moveTail(c_next, c_node) + if not attemptDeallocation(c_node): + # make namespaces absolute + moveNodeToDocument(doc, c_node.doc, c_node) + return 0 + +cdef int _removeSiblings(xmlNode* c_element, tree.xmlElementType node_type, bint with_tail) except -1: + cdef xmlNode* c_node + cdef xmlNode* c_next + c_node = c_element.next + while c_node is not NULL: + c_next = _nextElement(c_node) + if c_node.type == node_type: + if with_tail: + _removeText(c_node.next) + tree.xmlUnlinkNode(c_node) + attemptDeallocation(c_node) + c_node = c_next + c_node = c_element.prev + while c_node is not NULL: + c_next = _previousElement(c_node) + if c_node.type == node_type: + if with_tail: + _removeText(c_node.next) + tree.xmlUnlinkNode(c_node) + attemptDeallocation(c_node) + c_node = c_next + return 0 + +cdef void _moveTail(xmlNode* c_tail, xmlNode* c_target): + cdef xmlNode* c_next + # tail support: look for any text nodes trailing this node and + # move them too + c_tail = _textNodeOrSkip(c_tail) + while c_tail is not NULL: + c_next = _textNodeOrSkip(c_tail.next) + c_target = tree.xmlAddNextSibling(c_target, c_tail) + c_tail = c_next + +cdef int _copyTail(xmlNode* c_tail, xmlNode* c_target) except -1: + cdef xmlNode* c_new_tail + # tail copying support: look for any text nodes trailing this node and + # copy it to the target node + c_tail = _textNodeOrSkip(c_tail) + while c_tail is not NULL: + if c_target.doc is not c_tail.doc: + c_new_tail = tree.xmlDocCopyNode(c_tail, c_target.doc, 0) + else: + c_new_tail = tree.xmlCopyNode(c_tail, 0) + if c_new_tail is NULL: + raise MemoryError() + c_target = tree.xmlAddNextSibling(c_target, c_new_tail) + c_tail = _textNodeOrSkip(c_tail.next) + return 0 + +cdef int _copyNonElementSiblings(xmlNode* c_node, xmlNode* c_target) except -1: + cdef xmlNode* c_copy + cdef xmlNode* c_sibling = c_node + while c_sibling.prev != NULL and \ + (c_sibling.prev.type == tree.XML_PI_NODE or + c_sibling.prev.type == tree.XML_COMMENT_NODE or + c_sibling.prev.type == tree.XML_DTD_NODE): + c_sibling = c_sibling.prev + while c_sibling != c_node: + if c_sibling.type == tree.XML_DTD_NODE: + c_copy = _copyDtd(c_sibling) + if c_sibling == c_node.doc.intSubset: + c_target.doc.intSubset = c_copy + else: # c_sibling == c_node.doc.extSubset + c_target.doc.extSubset = c_copy + else: + c_copy = tree.xmlDocCopyNode(c_sibling, c_target.doc, 1) + if c_copy is NULL: + raise MemoryError() + tree.xmlAddPrevSibling(c_target, c_copy) + c_sibling = c_sibling.next + while c_sibling.next != NULL and \ + (c_sibling.next.type == tree.XML_PI_NODE or + c_sibling.next.type == tree.XML_COMMENT_NODE): + c_sibling = c_sibling.next + c_copy = tree.xmlDocCopyNode(c_sibling, c_target.doc, 1) + if c_copy is NULL: + raise MemoryError() + tree.xmlAddNextSibling(c_target, c_copy) + +cdef int _deleteSlice(_Document doc, xmlNode* c_node, + Py_ssize_t count, Py_ssize_t step) except -1: + u"""Delete slice, ``count`` items starting with ``c_node`` with a step + width of ``step``. + """ + cdef xmlNode* c_next + cdef Py_ssize_t c, i + cdef _node_to_node_function next_element + if c_node is NULL: + return 0 + if step > 0: + next_element = _nextElement + else: + step = -step + next_element = _previousElement + # now start deleting nodes + c = 0 + c_next = c_node + while c_node is not NULL and c < count: + for i in range(step): + c_next = next_element(c_next) + if c_next is NULL: + break + _removeNode(doc, c_node) + c += 1 + c_node = c_next + return 0 + +cdef int _replaceSlice(_Element parent, xmlNode* c_node, + Py_ssize_t slicelength, Py_ssize_t step, + bint left_to_right, elements) except -1: + u"""Replace the slice of ``count`` elements starting at ``c_node`` with + positive step width ``step`` by the Elements in ``elements``. The + direction is given by the boolean argument ``left_to_right``. + + ``c_node`` may be NULL to indicate the end of the children list. + """ + cdef xmlNode* c_orig_neighbour + cdef xmlNode* c_next + cdef xmlDoc* c_source_doc + cdef _Element element + cdef Py_ssize_t seqlength, i, c + cdef _node_to_node_function next_element + assert step > 0 + if left_to_right: + next_element = _nextElement + else: + next_element = _previousElement + + if not isinstance(elements, (list, tuple)): + elements = list(elements) + + if step != 1 or not left_to_right: + # *replacing* children stepwise with list => check size! + seqlength = len(elements) + if seqlength != slicelength: + raise ValueError, f"attempt to assign sequence of size {seqlength} " \ + f"to extended slice of size {slicelength}" + + if c_node is NULL: + # no children yet => add all elements straight away + if left_to_right: + for element in elements: + assert element is not None, u"Node must not be None" + _appendChild(parent, element) + else: + for element in elements: + assert element is not None, u"Node must not be None" + _prependChild(parent, element) + return 0 + + # remove the elements first as some might be re-added + if left_to_right: + # L->R, remember left neighbour + c_orig_neighbour = _previousElement(c_node) + else: + # R->L, remember right neighbour + c_orig_neighbour = _nextElement(c_node) + + # We remove the original slice elements one by one. Since we hold + # a Python reference to all elements that we will insert, it is + # safe to let _removeNode() try (and fail) to free them even if + # the element itself or one of its descendents will be reinserted. + c = 0 + c_next = c_node + while c_node is not NULL and c < slicelength: + for i in range(step): + c_next = next_element(c_next) + if c_next is NULL: + break + _removeNode(parent._doc, c_node) + c += 1 + c_node = c_next + + # make sure each element is inserted only once + elements = iter(elements) + + # find the first node right of the new insertion point + if left_to_right: + if c_orig_neighbour is not NULL: + c_node = next_element(c_orig_neighbour) + else: + # before the first element + c_node = _findChildForwards(parent._c_node, 0) + elif c_orig_neighbour is NULL: + # at the end, but reversed stepping + # append one element and go to the next insertion point + for element in elements: + assert element is not None, u"Node must not be None" + _appendChild(parent, element) + c_node = element._c_node + if slicelength > 0: + slicelength -= 1 + for i in range(1, step): + c_node = next_element(c_node) + if c_node is NULL: + break + break + else: + c_node = c_orig_neighbour + + if left_to_right: + # adjust step size after removing slice as we are not stepping + # over the newly inserted elements + step -= 1 + + # now insert elements where we removed them + if c_node is not NULL: + for element in elements: + assert element is not None, u"Node must not be None" + _assertValidNode(element) + # move element and tail over + c_source_doc = element._c_node.doc + c_next = element._c_node.next + tree.xmlAddPrevSibling(c_node, element._c_node) + _moveTail(c_next, element._c_node) + + # integrate element into new document + moveNodeToDocument(parent._doc, c_source_doc, element._c_node) + + # stop at the end of the slice + if slicelength > 0: + slicelength -= 1 + for i in range(step): + c_node = next_element(c_node) + if c_node is NULL: + break + if c_node is NULL: + break + else: + # everything inserted + return 0 + + # append the remaining elements at the respective end + if left_to_right: + for element in elements: + assert element is not None, u"Node must not be None" + _assertValidNode(element) + _appendChild(parent, element) + else: + for element in elements: + assert element is not None, u"Node must not be None" + _assertValidNode(element) + _prependChild(parent, element) + + return 0 + + +cdef int _linkChild(xmlNode* c_parent, xmlNode* c_node) except -1: + """Adaptation of 'xmlAddChild()' that deep-fix the document links iteratively. + """ + assert _isElement(c_node) + c_node.parent = c_parent + if c_parent.children is NULL: + c_parent.children = c_parent.last = c_node + else: + c_node.prev = c_parent.last + c_parent.last.next = c_node + c_parent.last = c_node + + _setTreeDoc(c_node, c_parent.doc) + return 0 + + +cdef int _appendChild(_Element parent, _Element child) except -1: + u"""Append a new child to a parent element. + """ + c_node = child._c_node + c_source_doc = c_node.doc + # prevent cycles + if _isAncestorOrSame(c_node, parent._c_node): + raise ValueError("cannot append parent to itself") + # store possible text node + c_next = c_node.next + # move node itself + tree.xmlUnlinkNode(c_node) + # do not call xmlAddChild() here since it would deep-traverse the tree + _linkChild(parent._c_node, c_node) + _moveTail(c_next, c_node) + # uh oh, elements may be pointing to different doc when + # parent element has moved; change them too.. + moveNodeToDocument(parent._doc, c_source_doc, c_node) + return 0 + +cdef int _prependChild(_Element parent, _Element child) except -1: + u"""Prepend a new child to a parent element. + """ + c_node = child._c_node + c_source_doc = c_node.doc + # prevent cycles + if _isAncestorOrSame(c_node, parent._c_node): + raise ValueError("cannot append parent to itself") + # store possible text node + c_next = c_node.next + # move node itself + c_child = _findChildForwards(parent._c_node, 0) + if c_child is NULL: + tree.xmlUnlinkNode(c_node) + # do not call xmlAddChild() here since it would deep-traverse the tree + _linkChild(parent._c_node, c_node) + else: + tree.xmlAddPrevSibling(c_child, c_node) + _moveTail(c_next, c_node) + # uh oh, elements may be pointing to different doc when + # parent element has moved; change them too.. + moveNodeToDocument(parent._doc, c_source_doc, c_node) + return 0 + +cdef int _appendSibling(_Element element, _Element sibling) except -1: + u"""Add a new sibling behind an element. + """ + return _addSibling(element, sibling, as_next=True) + +cdef int _prependSibling(_Element element, _Element sibling) except -1: + u"""Add a new sibling before an element. + """ + return _addSibling(element, sibling, as_next=False) + +cdef int _addSibling(_Element element, _Element sibling, bint as_next) except -1: + c_node = sibling._c_node + c_source_doc = c_node.doc + # prevent cycles + if _isAncestorOrSame(c_node, element._c_node): + if element._c_node is c_node: + return 0 # nothing to do + raise ValueError("cannot add ancestor as sibling, please break cycle first") + # store possible text node + c_next = c_node.next + # move node itself + if as_next: + tree.xmlAddNextSibling(element._c_node, c_node) + else: + tree.xmlAddPrevSibling(element._c_node, c_node) + _moveTail(c_next, c_node) + # uh oh, elements may be pointing to different doc when + # parent element has moved; change them too.. + moveNodeToDocument(element._doc, c_source_doc, c_node) + return 0 + +cdef inline bint isutf8(const_xmlChar* s): + cdef xmlChar c = s[0] + while c != c'\0': + if c & 0x80: + return True + s += 1 + c = s[0] + return False + +cdef bint isutf8l(const_xmlChar* s, size_t length): + """ + Search for non-ASCII characters in the string, knowing its length in advance. + """ + cdef unsigned int i + cdef unsigned long non_ascii_mask + cdef const unsigned long *lptr = s + + cdef const unsigned long *end = lptr + length // sizeof(unsigned long) + if length >= sizeof(non_ascii_mask): + # Build constant 0x80808080... mask (and let the C compiler fold it). + non_ascii_mask = 0 + for i in range(sizeof(non_ascii_mask) // 2): + non_ascii_mask = (non_ascii_mask << 16) | 0x8080 + + # Advance to long-aligned character before we start reading longs. + while (s) % sizeof(unsigned long) and s < end: + if s[0] & 0x80: + return True + s += 1 + + # Read one long at a time + lptr = s + while lptr < end: + if lptr[0] & non_ascii_mask: + return True + lptr += 1 + s = lptr + + while s < (end + length % sizeof(unsigned long)): + if s[0] & 0x80: + return True + s += 1 + + return False + +cdef int _is_valid_xml_ascii(bytes pystring): + """Check if a string is XML ascii content.""" + cdef signed char ch + # When ch is a *signed* char, non-ascii characters are negative integers + # and xmlIsChar_ch does not accept them. + for ch in pystring: + if not tree.xmlIsChar_ch(ch): + return 0 + return 1 + +cdef bint _is_valid_xml_utf8(bytes pystring): + u"""Check if a string is like valid UTF-8 XML content.""" + cdef const_xmlChar* s = _xcstr(pystring) + cdef const_xmlChar* c_end = s + len(pystring) + cdef unsigned long next3 = 0 + if s < c_end - 2: + next3 = (s[0] << 8) | (s[1]) + + while s < c_end - 2: + next3 = 0x00ffffff & ((next3 << 8) | s[2]) + if s[0] & 0x80: + # 0xefbfbe and 0xefbfbf are utf-8 encodings of + # forbidden characters \ufffe and \uffff + if next3 == 0x00efbfbe or next3 == 0x00efbfbf: + return 0 + # 0xeda080 and 0xedbfbf are utf-8 encodings of + # \ud800 and \udfff. Anything between them (inclusive) + # is forbidden, because they are surrogate blocks in utf-16. + if 0x00eda080 <= next3 <= 0x00edbfbf: + return 0 + elif not tree.xmlIsChar_ch(s[0]): + return 0 # invalid ascii char + s += 1 + + while s < c_end: + if not s[0] & 0x80 and not tree.xmlIsChar_ch(s[0]): + return 0 # invalid ascii char + s += 1 + + return 1 + +cdef inline object funicodeOrNone(const_xmlChar* s): + return funicode(s) if s is not NULL else None + +cdef inline object funicodeOrEmpty(const_xmlChar* s): + return funicode(s) if s is not NULL else '' + +cdef object funicode(const_xmlChar* s): + cdef Py_ssize_t slen + cdef const_xmlChar* spos + cdef bint is_non_ascii + if python.LXML_UNICODE_STRINGS: + return s.decode('UTF-8') + spos = s + is_non_ascii = 0 + while spos[0] != c'\0': + if spos[0] & 0x80: + is_non_ascii = 1 + break + spos += 1 + slen = spos - s + if spos[0] != c'\0': + slen += cstring_h.strlen( spos) + if is_non_ascii: + return s[:slen].decode('UTF-8') + return s[:slen] + +cdef bytes _utf8(object s): + """Test if a string is valid user input and encode it to UTF-8. + Reject all bytes/unicode input that contains non-XML characters. + Reject all bytes input that contains non-ASCII characters. + """ + cdef int valid + cdef bytes utf8_string + if python.IS_PYTHON2 and type(s) is bytes: + utf8_string = s + valid = _is_valid_xml_ascii(utf8_string) + elif isinstance(s, unicode): + utf8_string = (s).encode('utf8') + valid = _is_valid_xml_utf8(utf8_string) + elif isinstance(s, (bytes, bytearray)): + utf8_string = bytes(s) + valid = _is_valid_xml_ascii(utf8_string) + else: + raise TypeError("Argument must be bytes or unicode, got '%.200s'" % type(s).__name__) + if not valid: + raise ValueError( + "All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters") + return utf8_string + + +cdef bytes _utf8orNone(object s): + return _utf8(s) if s is not None else None + + +cdef strrepr(s): + """Build a representation of strings which we can use in __repr__ + methods, e.g. _Element.__repr__(). + """ + return s.encode('unicode-escape') if python.IS_PYTHON2 else s + + +cdef enum: + NO_FILE_PATH = 0 + ABS_UNIX_FILE_PATH = 1 + ABS_WIN_FILE_PATH = 2 + REL_FILE_PATH = 3 + + +cdef bint _isFilePath(const_xmlChar* c_path): + u"simple heuristic to see if a path is a filename" + cdef xmlChar c + # test if it looks like an absolute Unix path or a Windows network path + if c_path[0] == c'/': + return ABS_UNIX_FILE_PATH + + # test if it looks like an absolute Windows path or URL + if c'a' <= c_path[0] <= c'z' or c'A' <= c_path[0] <= c'Z': + c_path += 1 + if c_path[0] == c':' and c_path[1] in b'\0\\': + return ABS_WIN_FILE_PATH # C: or C:\... + + # test if it looks like a URL with scheme:// + while c'a' <= c_path[0] <= c'z' or c'A' <= c_path[0] <= c'Z': + c_path += 1 + if c_path[0] == c':' and c_path[1] == c'/' and c_path[2] == c'/': + return NO_FILE_PATH + + # assume it's a relative path + return REL_FILE_PATH + +cdef object _NO_FSPATH = object() + +cdef object _getFSPathOrObject(object obj): + """ + Get the __fspath__ attribute of an object if it exists. + Otherwise, the original object is returned. + """ + if _isString(obj): + return obj + if python.PY_VERSION_HEX >= 0x03060000: + try: + return python.PY_FSPath(obj) + except TypeError: + return obj + fspath = getattr(obj, '__fspath__', _NO_FSPATH) + if fspath is not _NO_FSPATH and callable(fspath): + return fspath() + return obj + +cdef object _encodeFilename(object filename): + u"""Make sure a filename is 8-bit encoded (or None). + """ + if filename is None: + return None + elif isinstance(filename, bytes): + return filename + elif isinstance(filename, unicode): + filename8 = (filename).encode('utf8') + if _isFilePath(filename8): + try: + return python.PyUnicode_AsEncodedString( + filename, _C_FILENAME_ENCODING, NULL) + except UnicodeEncodeError: + pass + return filename8 + else: + raise TypeError("Argument must be string or unicode.") + +cdef object _decodeFilename(const_xmlChar* c_path): + u"""Make the filename a unicode string if we are in Py3. + """ + return _decodeFilenameWithLength(c_path, tree.xmlStrlen(c_path)) + +cdef object _decodeFilenameWithLength(const_xmlChar* c_path, size_t c_len): + u"""Make the filename a unicode string if we are in Py3. + """ + if _isFilePath(c_path): + try: + return python.PyUnicode_Decode( + c_path, c_len, _C_FILENAME_ENCODING, NULL) + except UnicodeDecodeError: + pass + try: + return (c_path)[:c_len].decode('UTF-8') + except UnicodeDecodeError: + # this is a stupid fallback, but it might still work... + return (c_path)[:c_len].decode('latin-1', 'replace') + +cdef object _encodeFilenameUTF8(object filename): + u"""Recode filename as UTF-8. Tries ASCII, local filesystem encoding and + UTF-8 as source encoding. + """ + cdef char* c_filename + if filename is None: + return None + elif isinstance(filename, bytes): + if not isutf8l(filename, len(filename)): + # plain ASCII! + return filename + c_filename = _cstr(filename) + try: + # try to decode with default encoding + filename = python.PyUnicode_Decode( + c_filename, len(filename), + _C_FILENAME_ENCODING, NULL) + except UnicodeDecodeError as decode_exc: + try: + # try if it's proper UTF-8 + (filename).decode('utf8') + return filename + except UnicodeDecodeError: + raise decode_exc # otherwise re-raise original exception + if isinstance(filename, unicode): + return (filename).encode('utf8') + else: + raise TypeError("Argument must be string or unicode.") + +cdef tuple _getNsTag(tag): + u"""Given a tag, find namespace URI and tag name. + Return None for NS uri if no namespace URI provided. + """ + return __getNsTag(tag, 0) + +cdef tuple _getNsTagWithEmptyNs(tag): + u"""Given a tag, find namespace URI and tag name. Return None for NS uri + if no namespace URI provided, or the empty string if namespace + part is '{}'. + """ + return __getNsTag(tag, 1) + +cdef tuple __getNsTag(tag, bint empty_ns): + cdef char* c_tag + cdef char* c_ns_end + cdef Py_ssize_t taglen + cdef Py_ssize_t nslen + cdef bytes ns = None + # _isString() is much faster than isinstance() + if not _isString(tag) and isinstance(tag, QName): + tag = (tag).text + tag = _utf8(tag) + c_tag = _cstr(tag) + if c_tag[0] == c'{': + c_tag += 1 + c_ns_end = cstring_h.strchr(c_tag, c'}') + if c_ns_end is NULL: + raise ValueError, u"Invalid tag name" + nslen = c_ns_end - c_tag + taglen = python.PyBytes_GET_SIZE(tag) - nslen - 2 + if taglen == 0: + raise ValueError, u"Empty tag name" + if nslen > 0: + ns = c_tag[:nslen] + elif empty_ns: + ns = b'' + tag = c_ns_end[1:taglen+1] + elif python.PyBytes_GET_SIZE(tag) == 0: + raise ValueError, u"Empty tag name" + return ns, tag + +cdef inline int _pyXmlNameIsValid(name_utf8): + return _xmlNameIsValid(_xcstr(name_utf8)) and b':' not in name_utf8 + +cdef inline int _pyHtmlNameIsValid(name_utf8): + return _htmlNameIsValid(_xcstr(name_utf8)) + +cdef inline int _xmlNameIsValid(const_xmlChar* c_name): + return tree.xmlValidateNameValue(c_name) + +cdef int _htmlNameIsValid(const_xmlChar* c_name): + if c_name is NULL or c_name[0] == c'\0': + return 0 + while c_name[0] != c'\0': + if c_name[0] in b'&<>/"\'\t\n\x0B\x0C\r ': + return 0 + c_name += 1 + return 1 + +cdef bint _characterReferenceIsValid(const_xmlChar* c_name): + cdef bint is_hex + if c_name[0] == c'x': + c_name += 1 + is_hex = 1 + else: + is_hex = 0 + if c_name[0] == c'\0': + return 0 + while c_name[0] != c'\0': + if c_name[0] < c'0' or c_name[0] > c'9': + if not is_hex: + return 0 + if not (c'a' <= c_name[0] <= c'f'): + if not (c'A' <= c_name[0] <= c'F'): + return 0 + c_name += 1 + return 1 + +cdef int _tagValidOrRaise(tag_utf) except -1: + if not _pyXmlNameIsValid(tag_utf): + raise ValueError(f"Invalid tag name {(tag_utf).decode('utf8')!r}") + return 0 + +cdef int _htmlTagValidOrRaise(tag_utf) except -1: + if not _pyHtmlNameIsValid(tag_utf): + raise ValueError(f"Invalid HTML tag name {(tag_utf).decode('utf8')!r}") + return 0 + +cdef int _attributeValidOrRaise(name_utf) except -1: + if not _pyXmlNameIsValid(name_utf): + raise ValueError(f"Invalid attribute name {(name_utf).decode('utf8')!r}") + return 0 + +cdef int _prefixValidOrRaise(tag_utf) except -1: + if not _pyXmlNameIsValid(tag_utf): + raise ValueError(f"Invalid namespace prefix {(tag_utf).decode('utf8')!r}") + return 0 + +cdef int _uriValidOrRaise(uri_utf) except -1: + cdef uri.xmlURI* c_uri = uri.xmlParseURI(_cstr(uri_utf)) + if c_uri is NULL: + raise ValueError(f"Invalid namespace URI {(uri_utf).decode('utf8')!r}") + uri.xmlFreeURI(c_uri) + return 0 + +cdef inline object _namespacedName(xmlNode* c_node): + return _namespacedNameFromNsName(_getNs(c_node), c_node.name) + +cdef object _namespacedNameFromNsName(const_xmlChar* href, const_xmlChar* name): + if href is NULL: + return funicode(name) + elif not python.IS_PYPY and (python.LXML_UNICODE_STRINGS or isutf8(name) or isutf8(href)): + return python.PyUnicode_FromFormat("{%s}%s", href, name) + else: + s = python.PyBytes_FromFormat("{%s}%s", href, name) + if python.IS_PYPY and (python.LXML_UNICODE_STRINGS or isutf8l(s, len(s))): + return (s).decode('utf8') + else: + return s + +cdef _getFilenameForFile(source): + u"""Given a Python File or Gzip object, give filename back. + + Returns None if not a file object. + """ + # urllib2 provides a geturl() method + try: + return source.geturl() + except: + pass + # file instances have a name attribute + try: + filename = source.name + if _isString(filename): + return os_path_abspath(filename) + except: + pass + # gzip file instances have a filename attribute (before Py3k) + try: + filename = source.filename + if _isString(filename): + return os_path_abspath(filename) + except: + pass + # can't determine filename + return None diff --git a/.venv/lib/python3.7/site-packages/lxml/builder.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/lxml/builder.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..e14bc1eee628556262746c69e5374416f7f020d9 GIT binary patch literal 188260 zcmdSCeSB1Bng4%JGJzpY>i|I`Mw!;AsI;9{R95q~LrL3I({>7>rIsy&BrVtg5mKcq zyE~LXX$xOMc_>zpQPJhgvTjsXu}d|rxMG)eaYe;0yUqir(11!6ZB;bC_vf7ZBxg=j ziu?Qi{`iI0;W`iZ!*yRz_jO(Oea`&tbuHINA`#>NRho%LSBKte%w*u&XDf_}nySer zVMg$5f_ans+%GTK_nwG*RJk`J-t%i{l+2m;I@JoMXD42l{sr0v*-Y*aT}iDmiYrd8YZ|3;%lK=Pv)n zk6(Pt$M$?V`}!O1`^%$`3C9OHR9@qXRGO%+*KpkU;9IIjP3(Av)0h3lF7s|xno;ga z@>;c|zG}@>HD>>W=byYs?j2p<>=9`2`bQo?2d@*M>nB6)9o2yBpW3^8q<`hn<@%vZ zBQ%c&u2o)#|Ciw83n6^o6vB5P=9l*BZVo-45yIy`MR@zCzAg^6|C$iKPlf7V85l3( zWIi3ZR(o?o<^MT^-!q~1*M#t$6)Jy!==wU3rS1sS-?>nK&jt81hUY&Ijqi=2_7;Wc zaV+%wHG%fk-X)>&ZVJ_J4UOj?0`-OO8$$R`3|;?asJ*WR#-sYH+21?KRBSqcRYmeb)o+M7^)u_j!97eFGBom3*q;*Ps29oekC-X&xFSR z*--nvq520y?cW=!|JzXccZbUF4wZi>bp7cNy%q)tB6`L{^tvWAo`*uupAYq)47IhBNL?+-n{HAKH#Li|dE_;Yor{C|YnI~&4p4fHttL1XH`V~n}Tv~#^L zUE%sOqs=%bz&ZCUT)b$`(yqBny5`I=b8c+CX--@FlJU`GTjzeH zquqNp{F6EJmd%}W_ku-pI~M#^yXjc)k+|<5s&P{VWIu_3}bJF+EXsrlZ|;&dp8Ggnzhv>k>lZIsI9I)ENVL`7*|lKtqMPP+&70r8 z)a_M+9K_K!ZTlW<$ZzDvg`JDx%G9>Dn-;g-2M2~avjlKy1?g_=YF|jJ3l`l&8TTe5 z)y>-%bj|k%BAjlYyJXQIk~iPC@FVR@=G?fbt$mqrX6(0oynV^t9g9EV*YPpzXrH^} z_V&5Z>+Yo#opTEVTL`bO@0hDDRrN#d8nsI@^#oRf7!8gL5)IxA;;tqvcGn3NZ@f+I zcZ1vl(X(aoqI>3u!aCu))fKN9U30tI#Z+7WmU(b3lKNUV?+hlSa0D8KsW!xWB7? zsf)Qc@TrU1W=KZ{Yl`{TTg_Rb5jM4Z5)DZ{KDT3z{u2%^U2JbRF1>LPg1Bg2pdBmP zA@Zs#sYX!P7cXjocRtN-mb6K22gMcKM60Iu&L!>h=89U98c()vnK5VSqD};@>uweE z5p=cE#ZcV1tsRwGyl7~Q+>OV%Y;erg zWX}jpAEcQpC;{`}sx9(zUuTCaDQ*u?B&Z~FKD21@Cl%BHfQFd)+Lw&e*hlGy{^*U{TmlyMWG}A4+`szO}1H&7=E*sG#>D%)6)L&_70Ed zssdG}NfB-J+vaxMH)y3=u-9{@c6PQeY7@hKje{_4_nU?73+FBDwADl$uTKfa^>aIx z4jH6Di;(V^JFgwX<6|ll;UlUB=6DU$f_v4nc=5gWsRI`cj}ATxE(sP%vIk{zNNHe) zh7;rlm)__lN_xNzkEWKb7Rl-D3+FBXFP|I|hXo(GuWOJb-VD&xzI5J_&@?c8!MyoH zQ;O&swu#=*r(J*FqIpsPzy6>+%Djp9?H}>@94rAWyT}bi7TmqSwQRPrz!da{W*nRC-9OmLhT@YT=fY0I~<_?)R%R>m@;iYb6 z#HTJ5;7Vi%*TJVj85l&~9lXVEP={x9EWq+1dv?S(v1|mlgwPiJU#E;_BL1qhSr4;4+EV|vrP5SDQECBtfucq+>E1Q^=wY({mbSobm#Cn z3zp82+|KD(wy~2oH?-V%?X)>pU!io`uzvwJyX<+uT^zhWRCefW z@ZtZ@PLwIszs2A!e>}layI{e^%9cH5eSbY~x6c9gdBxy!* zJZ9l(3(r_+KIn}jYGJK~brw#vaFT_yEu3%R9t(RdJZ)j!hrD*{Eu3iKBnzil*l1z1 zg)J7&x3I&)E(@1g*lpoj3pZJqvv8+{yDZ#m;XVuZTX@jILlz#k@R)^p3y)iP#=^4} zzGPvv#T#$T!a57u>}C&-8VhSJtg|p-VS|MeEu3WGWDBQQ*koa|g{>COvT*Cv z3Nwy;;WojGjL8Ys7_(Clk7}3TCC2O#WTNdAe48;mo;9& zdB(gX*v6Wg;N3WE_*LWX!LJjXZ%j;Zp)oarIE-<@PW(Z^CFDc}KTb|p@P2$r!R4$Q z3;wk+69rdOKUHB~i(?%ZBtKg#NFKIMko<4GAbIA5AUczQves!MCz*EjW?&e8IOH(SuC)0nM-B+$1BUXJ_-UWNP!UXA<+z6<#gB$DYBd^hqV_#Wg(@V&^7;1uLX@Gp=b z!S^9Qg6~Iu1RIeb!T*K)2z~(h5xfTZ5lkUJf>V(n!E2Ep!D+~kU=#8qi2R)uyb<{k zL=MjhehB$Nj$V5c@*{XN@*|jr|AM!|f5GYSUvLKe7i@+9g15nc!Q0`#;4Jtr_+j`j zcqjZ9oDKg4?}Gn=bKt+=M~q1c61X%8E`a}nABF#d_ria{4)`y)2>uIx4E_r)h5v$G z@L%vg_%HYg_%FB&{tNyU{1^Nr{1^Ni_%Hak@LwgTf58Xfzu-#vFW3$L1y@0z z)aB2=yV{(JWuH75&0p?B^E;eN^6T@lGv9QMy|KcWe_3C=^qIBAV}IQ5_~%Cg=Z6C4 z2Lk8&1Lu1K=X(O@I|Jw20_U3o=W7G!-GTGvf%C4wc}L*9EpR?NaNZg?ZwZ_?14M9;H<^V5OzcJK>xt`>A?B%!1=Mj`H{f+p}_fp!1?~b`QE_!p1}Fe!1=bo z`KG}6+Q4~t;Cy-Dyen|t5jbxPoX-xNw+7Bz0_RPE^TxpWM)8)#ceP-A`_IBFSk*)x$-2LT#Dk zDyNb@qdcpkTpfM5ZKpRmk@R(xomn#JZpWl^W5>JYHaTj~FNZ79f8KVIwBz=vzPjl{ zeR*w|biU-b0}lPVjsR}}*Y6Gt^b4OeE1o>L_H7lWGr7a*WKO6|uFpr(xk5a?(OGk` zap|Wv>oq>pT8gG~5!|6_@Gap^^;bcI3g~i)rOVlYfhVAM8BX5#%g3d@JDGc$-^zYK z_!!C14sBI-GWOJV=aD}RoLZaM;Z!8n=S6SmP@Rp#=Tx*9Nj`d_(#$MGQr&o7;KZ|$ z)Ez;a;>VrTH7WQt$PbSXxWzBy1Fm2HB*tDzo5pN(o>E=-XHxk}XjT2+TvySScp_Rg zzpla@=Rplq)Jlg*bTi!syVe46{cPwjAO`qt+UCk_=x znHhzcnH~{ME6uHi3X_hUF^7;@Gaj5vxXk_j{gL#)?5Z8kveC53v&!V=6OlOd0MC!p zF78Z!hUem0G$q+>MFxgs9rtK_6Lm!w)q9U{>`WJr4-8aar}N}v0X{t_87z3bdd!i$ z`?4b${Rwr%Gb29J#yi06G;})+k0RMz$z<2Lc!*yw;2Pr#TxxcaH z;PDf?D7Whs%5~Xt=rA%ypUHJjma z;+d6Cp6q#Th1pkEVPf!k?{D#&8Y;{&V3uPIM+Zk2$1IKvM~Y(#M-BXtJi9!(b%ztZ zbca*dx6zS27-X~}vH3)E-!`Y#tSnZT*)F{!8VfpfX6lnCfBeUR{@pd`9W*998~^n` z4xBo`_{4jIPD-vPBUk-(ltE740v{%uP0p0eCitH&HDXsLcXm5dI2t)5Lk8P6WFxW; zLt^Yb&JcfZD?ua5Z3&cHZSB?;SAK@d&a`EHTldN~PBJ8&ISehcwH4-wuQ#_~w|jDh zqqppEj$R3kQtR_au92>9Iw88<^0S+Y(X8ZIJbn~7tI(KO=S;q8oiod34Q|U2&w9BkUOZl`FaS zCW9RT_ot{6NnT&9G^>l1@UE&4J<157reSM-_8Oa-soWbYq;9$Qbp z;G4z{eE)bJys!cN%RYc@S%gkfU$h#LS)Y$HKSh~OrX*K8e{b6~X0=lXUDJ0_R{bN( z!eOF)ewycTp6i~TpSAZd;$GqswZA?;UiYx$DaIIApV(&g$Gpt^yvi}7w>X!m402Dn zTph(WwStT0K4kcb{QuhF-EdQ7nS|0 zEw`02pK<%_aeC@$%k4AkY)fp$Cqdui;AzXU7w?HF7LN@h%=os(9ZuV9kDii`!&j|3 zUfVMcJnkr6CVnPnLhG4M+>8T0S|F8DUBR{Zi@sFPblZB!f&Trm#5kuWuDa7pk@!^X zq^Z8cJ||_=@5Lj}LQi8}|;|duO>flY495Z)L~I==z8m@8Xb2 z7jNQur)^t0`g>buHs(JRhymorJJ4F(VNkMT*=qXW}d&D=cmy(10U-Oo1OZnHaj`=v@%0E z=FljI=F>QKv<}--%TdD-<7mL{B=YN=`aa5J);S~40olR|`ncYXtA#$|^pUXr>sid@ zQM#1o*{DGO4YvPX^zZkrKGlD)--?8XkNQ`?J`T3;!rN@$t+f9_m8qUY-$`hIZkA*} z4(B!x+Ka27d8l=Z$XrXb}M>acq12_qvFfHmSH;7Lk{tk4&-$Z_)rEPyU?f)C? zFT2C@yCh#zz~d~mKNH{VJZ;NmDEDp3HG_8}&+$F*0oFMwuA4@0cJ|qFZIt_l@TIQ! z*HYN*q@O|;J2f|YG@1yFq8wp-eVR3Nu5BS5^KCnvM(%4K@8H?Z z_SsaP&H4mBZ0GuXZTi6?bSQk;;`TnCrNBw!(ma8@6*`%NqGpSeOg`uwvE`DKQ@t*p zo#5V4#!{JPZeuZ-B5n?x! z%%W=#IEvSTKD2zUE=#W}p6z-!am+Yxj__l)Q9R$ueHSn0sQ7CZ7jhNqKT|vqHT^H4 zgK=bDbM0NWttX=9iTQsT=x?K*a8+H!a~juYEf2nI%QUr9hG*jEGWgxDHnQpBJjOBU zKE;t+JQ?eJ(B*N@DCVDBx=4Dvx*Fg4A@ElH<&?Wkb@A6e%rnV@?scm?^2G8E_hu4r zoAF1xcQ~=^`g}`dtMe_%GxHy`7_YoV3w2If9Adq>NQ~S;ER&18z&!jBp66OE50Jg( zqqjO+8MoUnv~R-SYO(jm*fv-$K*mkK`sTd4PWLIx^1}EL*<7J@?+&Lmy2H7sS9ALM ze0KDwiL`zE4#zGReIvuB$axu1BUhxF_Gopkpc{-)97H1ka4Ecf|H7`md?j z;mmq7$5{2f>4a>KztZ1*@ZcRaTfx97ch4*xkqEF)bpi3jl^kZHn$YtmeC%18gKS;jj^Njp*^s^D3uI?y zi(8S+9_FJ+ zV{#nZXlxJpoCaVT*al~plgms0lC?UZ@;qmLL0xhcyEwWzrc_s$THwx6T#utHFawMO z`>2rOm~tBJ1MdT4$Pdwf1`9CpIo3rT&N*7*;rykMv_&6~%y7%>`Z0N@XDJUn_){Xs z5wykqWj~^Aj{H&9dAaTdHdRrH;}FE_{Rv}+`167F9D9-zn9q7#nVo+r^JV-|ClX&l z&fx)cBkQyxW1Fy(NvjW<^H-7&bm#6@(TC`*69#2k`ZFJymh8M}+wx_4G3_aaO(BPa zx~OYpGLn>CQl9DMxvLAo!P8q$W_=xerS_zMv%v4CFAbb(ChyYHxvrSbt}7}RqxfHI z0Vb0xtc#jc$F7>-(ro+{D~mOK8=a%(+QQ+_9zqZAEEx0Qi0p6$CmzF;SzRK$e=L_+-S^{;_7g(n`P^aYr z>jGPhvROi;`C*$L;i9hbj%a_J_v`ImimN!puS}G@C_txjHjuQu& z_4y=g6-~)?#a8lc*xI7zlCO;M>b#q|x$RvOoSmZ|N6sI2DzTT1)^;U%_GkO6e|Y3HX zSWjp08^Ez(>y;fhQSbg~m zt1rv$nSkB(%0EF_=?Zaq|JvIpIBQ2vu=&CD`5NM~`F)$6{g-Zb)?JbapmuY8T{ z+&=Eb@a?1VTsXDREK)4D(|PMkuWah&hLZ&$n$Gmnm|Njxxy_^7&yF}b!vLHRCO?h4$8+}zh`AJE}tYro`pIZ3ynUT8^ze6|4d6W_0_w;(^1XSl7r`= z&E7u@xNAeo@4s8|6=QBy9cXh9e`nfNxgT7eoc8p}*C+m~c)f%dJ zAYObz?SKz9yZ=hgGw%qEIjb>mb;nHH`i$x#OC{Cy$8xEQ-`2sg1jnHnoSHZns{PNb)cE84LXK0*S$A7&o%f5^8XBp>N#(6d{PUY`JW32`J{ci_O&FWB8`leUi-m0vZI{)cE5aLw0F25ennDsXSj98qNB}~6{d;f$k~Y5NgGpW zV@j}%__Vy*oI2W*qt8xQk$)=QTX?1RqO@f=*3uqft7)Nb%OKw9X7Y#N=k`BZ{lwip zI@+t^t(#5cUZvS_;_rSlaOxTMJk)a?K@Z*WB);v$*<-V>qQbP${xRzor$vcxkOeJ_{2!v*bM^RvUb_iad*+ zwU*e|6ASMF;$EG-ppN;e>r#8F5{Pv92@QHt)j?j1X%=Y8ayy%iEX%2DsoTYMwq`@9%uzBcdMcU2B zRacC%}MPu9iRm!aqATD9i2;Iq2(JgYy?v&4CxHJsQUi1e*3 zn!XkA|55a^n|ajcMN&LVHK7;mxk{~cXlpF$RUHKf>73-!ms|fHd&@DETV@!PIIB(w+ zIkN=!@QvB$fy-Q;hZ24r7N;0A(75G8ONV6dG~NidFa`~@PvnBf3|^6>XB#!|$u7#) z*S-P|s?mjyY7W#+Kt% zoNC{W4_7X3%V|GL?Rna(wdH&odNv}s2hWq2;F_X*;NbPK(DnDZmX6DgY0MGVMlc^` zhUO#J7l-ei%)kD4WmC0xIrz*U<8aUXanVLh^^^+-D6+YhLHkK6DC)ShUv z^^~Va%7O3u9ex=4v@^k)2l^x#s7P!huDrE?y&Q`_P>C-vzBSQ99+AG8Yg{{siJow~E z@=Ar3$(4CM$EVo+b+;Waze1j)|I7_fo_z6F1N}`#IIqut-j4IXv_^-GJWZKz=pMAu z*nOK9d_Uo4o|A*>Uj{9-CYk@Xw-$LA*a}_bYq)f^dgA$8D;@b${yhGai&whX%6mKV zV>IXczKrHizg!)2pC6-mYYXC2)}2p!E$(%u+mZjIdft0Ow-#f1cLP4KccXeD>-Mq( zQM1wcuIjK~WGeS_I%k}`vWgy&HFu4k1 z6hHp;KXn*A zYAbf7zQw1Bhwgtfak!vo58Tl0>RYh_=(5|s`+{D6 z*wPdmTkYGN5efJlcrWTdC?osSRfxFzN3^e_3!KkbJYxACXU$Z6MdURb|IG7>s}-NT zrmv1!$KU6hf;UNy+7fAB~6gFzi2mA?G#m4OLUE zT#kh1?)ya0Q8ZE6cd2Y#@!G9gOQ|;O(TVj*U$v)t(}}a~uZ8nYXt(iTZzGkVg$9T z`|NX69K&cr&pg`nd=t$AuLNU^+Ie~0 znSuUIx{oaJU-c)r)*c#fF3pzBrI*uQ>^$+Q9~YB{t5!}b8sCK7CY~}Ih|eBnJssIL z=^w@zL*?iP-1m0sQY(1&fIH6y<5cCKM8_OD5x276c$zmb&_VG|xl_sK2>Q}|&A0~R z^Q4WFzs@s1CLOMvA9w#B%K5p};mXz7_C8HHKd(Amxq4e}9p(HS>u}`~w%p%R&d;|F zSFXX9`xxc?-0N`VCfaiIDCg&4hbuS9mYYdAKPNj}xyiQN4V3fqv%{5Zw&mE5QSIky zhbyO?r+g{w9{at#T<~z^T5UN#VNyNCmQzgCh#W~i@jsu9W>Q6Ti2Ux?$W^Q=${xx` zP(DC5B$!|GbY&=qs&=Y~>9Hx#sC^a*nDcX`Ddb6I$24yQWl(k{cumfp7w8TSM2=xQ<)>xE8xqi!Ukq$lgeou4cS~mt&U%rB@&R zJV`A5d%iSFPO7_577$&1Rqj{tYYd%I4s zp7>Vp{dv)@(P(}Q*f;u@Z>oI@joMR*KK%#%Ui+42muy33YtvgKXfk^Ky` z-(<@(4(6Jn{9>c6+kBqBgjX~5|4}rsi=P9rDXHjQ8f*f2_gd_54>UKcDi8Dc@_$cf3mZ4$9v{`EFaj^Hs`sQhpBQXW8;yuTs8?^0!ld zk}bdNRmv};{4JC>_8p7vv|_oL>`j!NXU`%!vploW$+Di%&9R&#YHllBj}CW7$ax^M zLvh^8_xtkAhvKh7wsT78dSdAML!s*#q3b(C*YiTx_lB;QhOWc5pS{s#bIBv2>y4r7 zPlv8QAG-c~uH{=k`SXEOdoJ_jsODApPy-)sgyvaWe$A_tUqkt+ly9}=*Pf^RTFOcn zl=p5}AJJF$5oyJ<=S6+8P0d|*P8U+ z&`IWC(P!)V#tVJ6GG^rv_S^E?Ydb*`!9y(h@XY<)_O&Z zx$P)9yj>g}9E}_`9LI=u_i!xdXyK^mIL)H-evY*qvpFVloWq0Z`Y{KyUlT_y$8n;l zy&T;f2Z;SPadh^P|BUwxuHn?=r^2&s&YOO@xFA31OGW&GeC~%@2gQ!)dnwhfonY>( zjI4#oehlT!N3GwJAR?IY@jZn)rTDE52yNj46@t z8?QP)qwa;oP2>nJXgv{myr8&7`C5P7Z8(|n*Av~m3I3fsKKLq`R<0p9_p?u+Og^<1 z9emDv@nzSCxIRETqWhD?@v&qanv5+yfiG17J>=Vbo%{0Xv=%LYt`%Mx<^JZ5Eh=x0 zu8&v!iR{5qzBdvXTY3v)Qv9bpMy=ZEOe-%MQw~S_2Q`K}bU(CL%w+srUip48IqyyX?#1kFy}a*)Go>|v1o@^&kLT-(2C)pXo<;7` zJvDb@t>$DDVHR}L1;4ZpKjx?_-_N~P)k0m#cBNrU0Nv~q9 zKgWIE<7b~?ocv!+n*D~Id?O`Ezl=rn*Sr177yVc?0-vwBw0eASujVW5J0+&$J;z)j zp`12r33cRSr;*$JPx;y4qdhd*V+lU=%e&6Vf%elXU#q=iKE6MKPF+T{Tc3YKeIrwD zzB838J;$?0U3|PXiC}+fYb0%v<0I#W+$3^^QFcrx^&Tf<`B&=enesUrYth~(C)Gde z``&s)_V3{f-)|C6+NSgEil@Exp3K$c20J&OsD)n@S!@pbjg{lBftHdDjpJ^{(MUP< z<=^Aemem!+p?3*yVwN`1fwh@v!r#yH5VmM5dx%$KqqIJ;hP=sY?rm~XS#rX<$DSzJ zEBRZ~Y3CR+5tN0Bo}o3NR%AhZmYj<|?wSzzHo0^geocscrn@GD9IgH zM6G#+?S*W`2A=PxoZ?p>2Y-BD;{HmWA3ManNl@><$9I79)4RO9=P{sch4PmMxs?39 z*TsWx#AV#Q*ws7VB^$Lq-<^_uZgtm4mUnJ+suDvs^q<%ZiVhau3cs`XJo0t)y)<|` zK0B2>EHdZGV7L2@uyjN|hw!dRuW96@=@U5B^x_0Xg$%Pkxmdg(|VaUF+ zj_BLhFmKOTI!SjWQ&T#(IFqwmoW>p?vADiJ)X1T6{Xu=Fcz+vQ^nS}^=?%P@Lis73 zl%sBA&uZ*~bng7|gXBKumV5QwtZT>IvgO}NBR4{9T|O7peonS*W=Zd@b$34Q?2_DI z2j^0MdG>L49R51pO)h_Cxje>hJew^%2#-GF@<_HNn|vHSn^BN|t$awV?}p+7tl3t^ z*XETYt27%??XXP|e-cR59p-ueHPX+A9Lyp&v_Z_2PKmIu120c@` zHN}z0!NcsEezqTe;~U%#4G%CcKLmXw^UJdvo$k(+(B_UpHn-Bj2YI3oISTW_+b30? zXV-q`ike($wyRI+QcC=h?Zpm>R?&18d(Hu^rVdve{6%NV?W+RWC zcxdW_FN;$rVH1Krm15AHM=hrZw8+_VmpVkTZ4q&hB@azJ1VeE)pj(vi;v7dtn2VMK1 zd1`inchsu)2d<}b{WVM5Pl{jgX~f(I^SrC-(x4{yAo~U%a_1)buO8NNfM{$F9w!nJmOYI5hN+e)8xaV(d! z$?m=K`APn}}5!_@eHD6NQT{|G|KdC+1-n%S(*VT@Nd87J^oXdx-0&nF7e$00p zYM=Jj&VR`H8P+6X=?%_Ho!_hM9^L5MxR6T^vE*7jr+F{Ia9`hIB;l0Ln&GabNw& zpVPj(io|2?`-u1^e7}+R3ZNT4tPA%&MJ@w^%Elk2tiDa?`b_x9lL9fW=Ex|t@xNV& z54O9tk2UB>ed*1@k1?{Bpn4DO$iI$r9_y1`o$ZYg`e^Seo3;5~5&Ds^V>Dl-%&mpj zs1286v88j!f!59U z^m$`E-nYYfi8)I9X*CDs4Eqss_=uWwI{EHnX1g;fyWL5qw>$rJ5*;oCQo8pb!@8}M?9}-deqJ28b-&BJn*Cj$<{rAv*y^ZX&k@g1 zF7XJ*R>r~ietFiw{mC4O-fm}NR?k_NC-(K)S;hR7D@{uC?NiF6IJ7?4%+bP;=3pvq`ktENKJA&1tjuG4I~DV#p@F>z--&I#*e7Pj z7Vo2s=8tG6a+=;;McJ{^%b(F-2YJ%6xiawnhE-?|_#N z5(}^9JFBMpOO)LejzrKUm4Tt)efni8~hZZp;ClB)8Xntns>9gch<;ut>($u4{yh4T zkIP;T?TblJM)~$7F5Vu^j_TURw*Lq&E|0NGycb_3e}KI0cpsO^cHEl(M2k@gj~<_Q z@yZn#OMj=u=O&9!FZh6eNxtknx11Marohk3Ne$um(usjnn)^Ln@y74>`PbY(@=fF! zJC(pNDz>cqv^Q4>u6dkq!*D3Z+`4*)vz2e8>DyhEom)?g#CH5bw9hCW!(OH2%cM&$ zaIXgY@9inne7(x4B?b$}S>l`4nQPPJH?V8JVi@1^!)v{y-cFVbFJs6Fk2)OWaPYxFGI zsTrmn<|enD8h1QPOTXbdN_(}Ea~u0%bD+nAif_vH9+3aQpBu`n|4Zol$DwQO^QmQw znzwhx_5EFM{)kkJE&WpcTG{va*fA*$exLqVoQHV<>&s#h?U~$1Tp{1MS#zKK1Li&T z^)u?b-}ZvxNT9Urk=Mr-z>x9ok;cl6fsy=m*Tp*>le-#mQFwqB-yk&%?OMmcC!(g1436sruT#8l{ftdNn?NRR;b;JLSbRpH$ekiLD0P z{^={U?d1_>mQGUkclem{iGQWC;D&!aSpR#kP+$I&aKkQFzexQ`>K9cumoEO0d)0Pq z-*D@f$1xh4{7Th7NZCJ7|6<0sOXCaixRU+0W_v^qON=xZ^9AJ(Kd~ zxm^F`LpQ+7@ZRtRt{j&CHihJ@jefT>H)_A~HvHX)*?L0PZhk2)`_bdP==NW(e@lmH zZxL;^PVOBf@_R`nC5}JFeq`WQ;GVu6&YmQP`t0-G3#;TEOT8N=`>OSnDDPO|e~*8kV%CKB z{;%Gf9EwFBz-Gz5dNHzRfACAS?nOCYZ}GAEHBUDWj&IwERA_vA7+;d-N#oIQG&Gj} zKHz?{(Z2ilPu`e!F)od*nQ`pfLcGV3#(cj=gE~v`_?(%b$I`U zIZvw7l_a@|_faKF9m=8TAI2iG+GIoId0az^1ilDB42{*40iEd4RjD(QXq$(yej zAM>K?lfFuR+M{z?-@Jd-dEK}?Nqc)JL+wH@*9S0xcLd}!>so$hMm*kY*CJTIRgB;A zv7s3MJ&L#U8~7f3y1-g)bxmePaRl`x9n22PTjX#Q)+&s_!fVR&&pd$bKUReQCyA3*cq1S`|blhwb0 zK8lN#AMu~>XP%XwN0Yfi78@p9uvg3@Gu-?^Ew+YVu_o5Oc`(-Qr~DBZoi$=d>PjDSihZi1$`L@{R(=~KGOb?m^!R9;cUI%xy8@Kit#@rBk+VB6d|dlbd6%5=dUW^(N2E?*?qv zf#MG50QOA3Ij8lmSe|w2_-9Tur?xwhK4d6I`xzj)hn6JvXX>haZO^)59p7S%cVe%w zXBvmTQ?Ku`*KzHxcLSqIyVjlX@`cqVSGdaZ_a?@p{CXXBOL9i8ztFCG$Xb;0%Av@A zdp$C4+_`E-L9swIDS0QZap$)o|NO&x)(ie_9>AlsJ4Yw}8C#|HygZiLSMKL5^{aY6 z#D10S&PB=9C&&@^S0%1>uPeBge_<@H_(@O5ua44I5MShuy(u#bR|;>%?Y3<<&(*uC z7{o>EG8d5#6D}7qKFOL%FxK8jihezE0^=L;Ph_{E3FvQnP9(Y394|lekH=;2^T_IU zzSkhz=E=h~(5d0@I`=y~|KyfQm*jt`tnB6Y?Y%cJjgvWzm~Rt zZ0r1Q+F^~q-+w1p@3OM*ikNS^(}S*UVty5_mC2q#U-yR=PtkOPZHG1FYT0Dvmqc^X zUOW-)@1s58B--qzOdZb^yXjir28!`aeHgRh#6G2KQ&l8lrg!B3T=-E-t+53C= zh7U)SL$YqN(~F1Z>~IcUS>B^CdJlv5k+Yt>tBhhyH-8!(Q~KKqbUwqoc6`5GaaJYoFZ~7I6i1f($MD-C z7XdE;j^g-clK0y(hYKt3SzR!hyV3iPmn8E|mS)R2H<>)|XXFZrp6$+P-A|>99sGVp zjBzLqPz;$d8=dD%Jkvam?|pZ~JTWvslWUW#k^k=m9{GS5-yW&?w!1gUk7b#H>^pwa zmD@^R<$4cggYWqbhz2>unjbEmQ=3{#(46kZgIY@%iY3Fjqwi5(Yp8xqutMLZqW%z` z)X%avz-?D^&n!2d{S$ad-?bk2Ri4$m_-kG54tEZUyEuLd`SbRK?1NwaTDF^y!k;9K z53cC_pwIGvv(N2^STm*Zs{J+CR?XGr@n?hNjy!|rCfVNCRhsdWtgeOq5Ygp}$TD`S zzw-*d^RC~uk&RD)8+_t7lAfQ>J?XpbX6ADC8okluhwslv;c=S#>5F|I-}6tO6}?h9 z{dP*fZ2zB%o-Ax+9204ibunn5d}*$*kKDCqQ?l5W2k_t4I{T54%k=J*WF(u$SIt#I zkBS4-AEFC;GhG^#uSFf=H)Y)YCbYjVzR~GdJILX^E)B&i_ZwKy4ttJGQVboA?}wwU z+qVxB2+?(F}Y}bA<8^pK-@9ls~yP(8m{fRz>}{>HBML{%jibl&tW396a0qPV&_J zCXILp-X+BmovvI<5B##j(^R~?2VRC{=z8ucZz9@=j#qIVv=fSxWiu473(9VMJoByR ze#vz>_GK-cdqeTjwOohCKOA4G7|Y3bki)3<#-?$-k8x=~?a}w~JvVHhuWtr=9ps*W z{ddTZ``t$Rjm5_nzs_?vPn#o8+qwFaCX! zr7Zao$veD#weK<}L4dB`^9y#Ngziv1(E#7T(R=Rxz z<9KXmg=|8(KAe0zv>C-b0*>C=)B60ckP*F$q`6`QHvdob`yuSW6&%dF{7f9aI&^jO z8}ujna9sYB+nYPxd*wNUCih->Zoqqwsl40_%4u%WoD_$aHQ+71t!F;d-1hqdzoQ0z zrYGmF#Z_=FpGx-r%`Uv7^iF7B&)i;@-R?9q2CXlu4b|_bzUrQtGGq^W<%2+n8f?xs z(GNPy54-`sM|y579t@P-8z{TMmQ7H$-j@Au@K;}lZ9hGMx_bh3AFy?`x01E&s?YOX zM)jrjfxBHEdg}$tx!$kqOs;SvV;Kqko4F_Zd7JL%(#5%qTXUTBBGs!og50LL)141$ zvJX3N1Gif#d-83sEU(wuH5bio(%bi2nVsh1;>m3IyAZ)Omqk`)@ekZNb;x!+?6B^Q z{FUdlG=_McmlM)&*=YZ3$Lsw0!pjLQq3_u|n?2II&z$Jmr)JldZFOXS)Xz20rIB)t zp>iLf96oZtXYW=!5UskNa`m>HZ|^2k?rGW}W-8(Lv(B3oP zZ-YA@u+I~|dUL~S&auht*^NQB5?oR6|&lbpYiYst|F=Ee$qq-vgh z%zY0p|xMi?kLp&f?MtjOl2Foi)u(g&oG}bN@Be^~hwo2dRkS#ezJdN$bKggA) zYX31Z$Zv@3{sMR$Vh>mw^@yQ~!#y9Zl5&b$)7)2_;eI1F!EamAM-%1MzVEAj3chco zoh3&5ZPTTb$cN@S>EGWSIW*+zZN({ohajOX>fjgy&aFcJGxe(*9}Mzgp+ubs08f676lJ4S&wleD~e_z$xk0 zL|ZO@ZeaXA%5{axJxRHr@*Qgb+aU7;a^23k&s(hR#4h zdN1?rqsKGZKz_@@ju%C9H0(#F+PT(6Pl!K2!TeA0O z1E=nTuXW;ehQ0lKYg%@p)?R;tXPS@V_FD6%@-kiIVU8@uwvo@!cdPMB@XNQHi1g$N z@?(|bs_4uWIyj%8x=DVQmh%UcXGx=TtRLQ7VV>Da{mR}QSszk1E zGrv2g^~MiYkW=sc6zeni4vOvL+S`iX#~y-K{9ThE-*)xbqI`#1d`!c4y!cI^>M8Ug zzgqYy7oc2GyX=f|G31Z@`|phMPPy>0<-SVY$=Ddp>qq!~L;v^he!#iG_K$=vu5W;k zA^bkY?{prvd78sLyi-7~<1B6VkyFrb(rJCPBC+K}MLdNqn3f+sVR2#XHH!(GH+H!;v0(0QS7-LU06f8xcQM2@B68fxRm@H`@}~kDvBfHk)rBld7d!w z(wk%WBEUMcYD|M!Rgp0DrF!>XeW@<~(3pn!L%1Q+OZRfG0@&MkIMSQ{L46^lgs(!FIPU`^;4*oi1*M ze&V&y=bFw{&Let8Ug6WwN_iRWMb`X!B)-wvqG#C72P(}IwK?KH{Gn7zeqC#6JA7;5 z`4sXrWif2emJ|NB;ucpD!ywWl``i;yFs9pH?YH{oq`i+wZ70(`(oP_cZ zhwC8wdI6zPJd--`F5UZpP+I%p6|T| z{bJvss|$P!6yA+Wd;8??pzJyK_j{#Jw-zR%CljgXmnC^qefqzl7e4b4@@qHR*1xX`;9M4rJmXes@*5Ivc}rFU~#X^Yl9lsXUVDf*KbDN6O{9>BUR*-=r2ZFQQiq2tLMNdd?o&? zl1$BqKf7q7jIUYgqxahwH&vNuH2=unx_iB$+np{?hu_=z+K9)~6uETSlV zBR}>C`la_D(XZ?y0sVRqo{PuQw}+f~&x7dJW@JhHy}eX`J|k(XVd5+E;CXl;nUy@s zUb}m2k;C8pmvn3B_eoyqo!2X|iR$Y)`ts)aX$(R6So<53$h~rggY!U$SDp@q=ZXt| z&qBX}QE6_->vu|-BKVr|jz?VInwlRXKoA5SkWgP;C7JdLs^;8FGj%q;Au zjMm{Rh?}(kUiZGvJ@r$`I;Xde%(vS5Ryp5SJPu8QbLIE&x8)l#zq5ZKSNM{6fjk^T zR^(s(1J66`Z}{fP!L+>={q2)qg^xxoqW70u--^v49?@Ry7M`0v>=9$q^TRH0<&&MC zS3|bjFZTene!0!lZv&sH@@V!HI4ifb(Or+ol@idn1Kp6{>937GJ<^Qt8eFd_&$Ye_ zA2dvlx4ZYs^BRiLd^`4U$^rF|CxUn3*e&ATE2ppa#f9G~8cDg}-f;Gr?S3o#)A#*? z??SzfxNRiw7LDXRs7~I4a&rs33l;C%?qss-oHpn@zlZhuzRgv}eU8-#W=CEA zd+!Ft!O_?2HE#Q!Of&bqOs3_}A105{jPA&vlm5uZJ`~^R{0e-v&sM&e{0Tif&OOgJ z^kwfs=No~(E6`QH?*;Td3Z9JWfhXjZMr~NhdtbDJ4z)23tzFl|Z)DF4>rPx}((9bO zn`h(uSzI3!{jm)wGkuot+1n<2k>kCj6h0#|b_m)xPs^cK1^J8DpCGXVO6H!XCZKbFCgO z;XG@(4tQnC-;cYHxoDE`t1Jw5+yUZUZ$@?{?Q7=W?H$_xrJPQ~U((;Yh#}r^^F;hKu$lD;?*%{1w{`CD zawt1zQ-{2WYp`4z5!Q%1FKMw5HTr(0}gooyusuZ~Nu5*3{ zF8C__ve(l2751H*MXtZRnfJ@&Z{ZX5=Eh!R->sG()MW4fTt3Rx69)ZRts`dCuVQ-2 z#pBzZ>Z{gZ|5?vtE~x2UGtP@iS74*DH}q=~(3mv>l6FoNcx&A`&b#gIJ4&pZY@(eD zvAJPe?&)p0FA!e$y5IH3%JsjC`Q@lPruBLKX8BR(Ea|JiPp1WZ++0yFJ`Ush5Z6(D zQ#Z=Ks!HO0ytYsKa>AkKW+!xsrmM|ag{n?` z>&{iyx1LqtH>aq6d+FDjD~TC~@ECsoj^@$|NKi)vs?Kbeb3mFn}>k-)f-lvsP5EWLw=tPepTg&XL>kN zxq@_dVj7*}h;uY>__|+*t^KC-#p>O^qIY4r;r9<;rsFNrDfxk&p3gDzV?#biP5g$U z_~QD5NzWfVV87|q{YUH-JlHS06{6MG-L;2uzu_z3Bi%jo(}7d1@0MPz&!0>Vt?!G^ zdj2`9^BJRjQu7%0I2o z{{=m&;aBx=etWO=+dD&kd$!zf??E=*Zwck3=N~Thxv}J(rQ`0}OL;u?Gy02$V&7-M z`^^Da({FBy57O%f;-!nyw42Qp#xZYH(#J$(M>)Sr=-|&&@>k`9&ZVswd6ZymQiq(n zey|;*zR{q#L@|ouk~+@i`_AXQrf=&|e8PHYFh043aVj^e9Gjmzdygx(GfVH{H!H*X zam6tD@pi^$Os@28 z-QPqf)Rx*;eYK-D&O&F!50#V)`^MMPMh~_omhke)$}3Ax{rCyLqzWC0bTJhv@(Oz?z)iaTu)gaara8EH_P?Cw(#yBOTc0lSSA6=)t{w*WJ?kzEkBt(>`&ZZcmDyk|oj2om-(>**sewUoB-`ipF`L*5HG5 z=1OCb<47`B$jav8Yh5S1jSsH<{u-BZIK$1I`SIPU8=boPPpGNJwtw!q z{l_;rSJD57IBTu&saNkTpxeh4a~S3clcFB)w-}ov?Xx-3>^4X9%SEg$jsRZ*LuBms z67NJ;S2Hd*XOu}7{|njET_`r@t#%AwUKpb1DqC{2{fY z`pWlx1YL^1#*2MNs6O%&NAH96{a8+Q{dy*qE6t#8LnnR|ZOI0xuefa^DcaD#>bmt( z+ui*UkC9y;}NPxGg2$(ymo;dneInq)m6=wiyt9(_+ZTB?0 z*t^ilp3%yyR^)5q)5rt6b8tazXP`qHG@akM&gs!NrgHrD7vl}epyZ=EF(k+0OGOIW zTbay5!+%6R8n6$%MA+Y8Hao|FqQ87E$yPY__2$>|b)+~v(>qbYHP0|Vet>?c+>h}c zJJ?^|!9H{CO(B;2yyha!aZ$#@rX)9aavB?-A%Cnq-5c!hOnvDO1G~S9j8rkEXxv+W z{zO1VKl&23xM#cTlaFGo6ML|y9Pbxxt9QWP_4)BCkG|gY67xR%2*x+Eq!^;vF`_2Up)AF_QivXuRro1H6Qyvr0V@M{L~&f(|6c0`5!o&p`~P1@q%vyZiC*U z??~$VHp2BMddY*+#`|SklG|P1;+6F1YRc5~Dpn)E;mYf$otR|DmDfkCj7oNW|7sd@ zocCUa-gVM^9!pz!g$8_^q5pjvZ*Q*fWzH``Zd@5imFt}B%UJpjKNJ3XR>QNpq?Z$s zK1eTooj3$7T-i)o`x+R3jQXOFa(SXbwWX1K!yuiM%TPI$AvW#T`jXzy)jP2A7bdcH zE4gSu&cvrEeJH;tK8e=yrzXQA@v1-{@*lKErt!sr@y~Pp|FC!N@l_R9-{0qwYwtjeQnZh@PcJ@wtiIph%-+dK#A@I7pZAaE^EuhGX4cHCS+mxfHJ3g6 z;3>Sfz&UZrY0%Hf`R7Srp-JUxtx)u6&hQkpl+$P8X{a~ZuIWCg-oAXwj*=E89BW5+ zrQc-wFTcwBb%@{Fd5BogcwIy~v*Bizl;3gsezE<^TN#UTdwP26>(Z zzqk1|lXoIU)Wm5&^>?TY#?uNTm$&ubLpk@b=V@hAd*ZkCt1S6G`pyVzN~~M-MjXyk zEul=UL3OGObo3(mXtjD*nDZ>GapL=DpRc(1E%ZBnBRrQcD0`^)E1Wp~f4uk58RV}c z&573@eoFYrq^De@{VcUd{vJ*u`G>CO**tbFZ+ITv*`V_W zS}Vh09Kkqe&dsM$eujT%xOhCcF86U{L^Ql}ZSYT~?xEw&LW664C9Saq^p?`sdKX1= zRdZ$pyA^9^oHMk`7JQtr_z>8FD^0zU+Yqz`<+us_LfS5R>$!99C)hKsi>P0o{F&{S zBHrg7E=RHf&m%`8kt3Zom%i=u?i$b|>7?{f`g^I$!CuLi(pZ#%{s=$t*MuXV?G56k zGn#ij{5R|W{8@ST)gJx|yottHzh$1$PCKoBT+sIg@vQb>->|!}1nWpGq}5QqYzRE*3rP;EY7ZZv%meI~DqeO$?U*P!us?(R+}6+b4E<== z!qnb?r?MBx`wX%_j~t`Tza?I47{hs?_^9$m-$m$-{AsOaX>VEMljgE}DZ{Q~oWXdZwTo-e3)+;h`XQYQ=5t2B7*jgT-20+F z-a{XuaZ7R|9n}4a<~^Tby5o=*=ueGf$NGRzR_B)Vl~Cqz`3gb5aoCw3bH3ngsVuPE#(OREWaGyJsq%Dtci?B+sE2k8F%Di&xf~1c2{(rP8shu-pVeg z(|^Id@LJ|S19K_p?qJPpc%LiJG|H^vY`FN)>*##UvP1W>F1k0avq($Ky$rE~?Dt?h zu{}q*)8R$FnRke_+!0#C3UjuUb1_eC-zWTw`gD)c4(y_Qh-=`x+ALXcX}6Vw+P;q_ zwVn6MM%+T1qrF4rUSp%}@41_DE|qs_)y_f(4hepUIx(!^`a+=PsU4hB$M+ zjC0~Ve{+?+k8X09bK#zLo_`+>0mD{Jk(z1GlmH*&BC zl>)!aS_(Ai?10YyMV;P5?c6VMQ0*Z84chf?-v)ge9KE~s?1$Ms*uY)P&~)z-_JO(o zB-D*vrrvNnZKTe0)^a4PqKSL{`mZK$I^)^16COSEdg4jyXKjP}ba##Duy?R&Jka;S zStI3ck#?WA;(w~*_=be;V5y;g-NEP7qR&om-xBb4Y`UvocdN=SZeoo07>nc7XZIJb zI;?Mx>pOYraqiSamg@1RbU#j<^LIK|ZFH0Ld*ZU$!q=TSx-)>gH%YHUZx_T+zp5Mho}|nw{3XqYwT>Qv zc8%GuqbGy@i}nZDXEXV)>eqZ!=XeEs-Moi~&;PQ@tF1kJjiDRAqKfviFPGkXO@Ev< zA1Cqgey^RUY2UW~%Y+C2Vg^6?{oZ5W@0KDN;T|_LcJ}P#?o50t?Rwdp8Pv>y@B7MzPEF9@pn6N#ay0#NTqE@NROg7>a!R!6ZBh;Y>bch zS9HLf|0fSRnE&8o^l3fk{`ZpynM&u*Wc4+RlljN{{j5EB>{#fhjFm^OR6noi`=jAy zu!f*D$=<#z{eG4_HBKJv=kWXLXYQW#`&nmMy{c>bH~9TL-_*tX%*gEL z_$0wNdo}HqtdHu(#~J9SYx^rrIYZCjOjR8Ix9zW?zO(gPhwkC`@D5&2gm(qdG0Cvz z+>*Zz-4lmzge@_3+V``E?i;Se$4b_xY0x?RuDb%!Ui(Q)d+mJu6y^rC*Y)ciuHo-w znmcL&o%VJ4%k+`P3dw=yYop=8@H(WY+^>?qpSmRLo#Hd{($6?^#ZTUT<-rq0Cvp~N zOzg&wl+8j0rWsz<_VLOQw#vVIhq)=QA>l*m4ixRVEam-g-6xHXaF>+)Ch6f=#gRvM zPkF=zcT01WXGH9v@_ndpozAr~x0Ae$XN(=PZ^J!T+WXBTUbaB@KIv?$+L=llchi<0 zXxDha(8u>FSntC36vtoeO}L^-vLHWD z^o0Go`h57Ue_Hxj|3CUXKFaglyCa?i^*%(sXOfl*9S`yRDSKd_;n|IEp#GAse3kat zeWxXdzHEFRyLYt%-@@L>HF*E^F7k>d@e5zqhU>WlN<2@Zm;OGwvL)p7;NR%IzWrM` zr^RnQzx2&~6OBQ-o8R8EIWKmuPz<7dumLVI^w*a^!15MQ*=~m?X0eEo*9dgm7ZYjY#Z$uJi|YH ztpHbyIVbaZ>K~`O>4(k#)c*AMSywSWAZruD_RR5B^DCe) zH-Wr3+~vx8mfkCneSpCu^sTXAP0Zo@Cn?}Zi5mf~&1d%=ZJuRz{E}ZeurGf#I;T9^ zOCDS^o4lWQd#EQp&N!cV^w6`RN6=k6zOz4*|38+vM2gluo&v++(jXggW=e$^`_jblr`WBfxk9P!}1Z$?WO}vt?FTR~5n&64@ zK8bvtm^kD6`X;0H1mp4U{xc@@K6h2(s%O=XXjt#WEbBW{`lz*mf&Sm_%gk=d!CnpT zi+AZa(J@@UWCs}=&Hl2|RzAzSk49E&`#7`ykeSa6)O&2X(>j6t65Z*c^AYL1gSUr0 zk}%_m?1J>Qi2Jd25EtB!wT*Ycwy~F@G>t`?TUElFF5&$y*Rm}J5Z%M)a zW&en_9~}OkS^MsnrR!Rke4claHOFMm+Gp;1sP8@W2zj(ld8}^;aE@%??tP9V)0gLK zJuvh0jOX81KKz#uXDEp~B;PWn9X{^kSH+LAzrpyqlr@eN>J0WKZeR=@?i1gradp4m zq1(gv;lAJ3jh@ZL$B47<6FGg&LA7&1FKhk>Z-04(_T)0JJh2+UKcB{c2g%F&GHaPj`?OCG>FGVR7~aZ$bH3oABkYCf{bBW`)+-;NFB{Ff zZQO^KYuARpV)(wR-)+ZsP`~B^;+N=@Ond#T|Oa&*Bcc~n-i|L{$CE+36|J?>APaQ#8~XX((D?4#YH^f%hJ9w33L^1n2Q3rm-Z+|(& zI_}N*F8T&>DBg{Gv7`^D;5x~L&XUO|dN}_4A*~t8uar;udBR10_$P$RMJu*o2jSq% zpm~pmvN{<@)#l+o&f|W2)Q(&Hb{v3a*%CuPHti|wYLSs6`##48V3jpVaS8T+;D?vk z-;Z1#-AtV39o+SEw3fAuTGldTJHGCZqaLz-I{O2~l<^nd-O|{g@jzpP#)NPg{*?cI zp~hIvfiy-Gn!CWjW_+ed~{) z-|2)o^LeBY9DVyo`r3=l7mu^3Z!c>GvZ)i0`*(iBsrHZy4!#?HEWU>J1I%63wTB|a z+qDFH26Pc+i(e{Vi9bv~2L9G)$_n)K6y)P}^hLU%xIum0-mkUrG~?HkMn48R zQUy;nho}O-0@)8am-bDe9QoFPJnH?JKpwe6iQ$!doz0S`eF2QpjI1iE*<++>ZtJAsnXC`%0?hC+w z;TH!_@3#eQSGzw#yO|>&(z)CPW#jv|#mCc6l5hK65{)P7uXU0&?1_9N>7V%db$Fag zdMa_6k89jknryIi1i$@|bYv>`U1NFc9<9?L^&S@%tALq@HdA+Bgd44;6 z7ivH2u=G~GVzrTrgMAU|anQ5CMys6Nlv5cRk7({Zcvx-1<|2$2K+5Y@1)C;)4)eG_ntUbW-p>mN2udX>TrmQ$c`p%GIyq% zJ)?Tst+rEV#Mhe-P;b$RqG{*Bg@lnh*p(*2j-etTLvu*2F%vhJS%-rlV7{d=KBw2B_L;L5|v=h7nP)`yxN=#1BTGGv#L* zTjB@%G&TivKSwys*n2BJB5mmV4z}^Tj_s>%`f42M^^?Z;*Uu8|vj29jDLoMVUBqiI zJ-FwuJ9~V8H~4B}VAJk`&IZ~cn{$+>WGMx{2J&Rql^BBtecfZ#xs`UmNu26;yz%|f1ojP{BO86v3C;NeKX40lNhhE6X$pZ8(DX}q z9CkQ2;p=1&A1kUc%PC~{8Wzxp+o&qx2duS*4@-Kq9u+BM3hvesCe~g}rwhF&Z8ly#@Y+1MN ze~ohnmND@PmE*5_j;CF+yJ@x7_Uaw&*vXtjA2VpD)F;c4tH06DvOh+zfQ?>3*PE0l zU6J0fr*gE4{F1G8gk$y0U65tjEZMucl%G5|TMJy!&bI=3EDdSo6Eo$QRmTI;G{ept>swiWy;`RR^eC&72cP2bsjj1x(Hpu0RY zHpEPSzxTRku(r#-3I4@UU7TX(r$gtxI>-7)`K<8&PV8f#Q^B~S_Wc8%u0KWml3d^1 z|Hji6e}dX5-l+{f?_LAMg}VqH}wCE@+%U9{X82w#BcFXdK785>k_K#_vC-R za6B?$WkljeLGdU!+zc*()NO)*aDz z7x9~EHfu<|y_pr1F?=6~MC|#{ee2(__pG&T>Aq+bJr{$w2wf4aM%NO(X6?Y7IYBQt zpZbv2dgM!6Umd+go^{4V>#Dyde?sf3oRx^R-_pO8`Q%pW!8c@0S8dsOa640W%zs7gCppPpiSW~*-5c6y1`P_x{6lbYV zw6vPFWXdq-aC`9cNU!&GQ}b!9DSZc7?FCdVCuNv^B2D{&OgBapiB{(>zRg*CNc-vq%-u{R zH{TLn^v!L+YFiD@I^tHIZRfFzm`uMKviF>5zWVTrkeNfSEM{KHFCC%i;kkDjb4kLB zc-}jgyH_p zzp_C4bNZHXFM9=?D}d^w#$T+{ zZ+!O}o0Y}6@ErNt*eoCZSk8-c#DDue=?%#03rTRCIaT>Sjh7eo-A`D1!SdlgulcFj zD_+vq%zB?}rrx>J8GP<^dPsQMpHsZC@%yBg7xjGznzmAYx${ZW=b9hM_G%wo_4pVl((#AnpEs^BGk zuC?ut!Iw&nIearbrhS^kJm_9}==6{?P507-zjE`-dZ)y$TV3C;ef|RK)tp=7v6)MO zukTK1uA;JQXus(*+N`sClY3Y*qCbwXH>PiWXj~3gXTI@L^FE-`%7>>^<^(6YGQ2kzh}T zdcFxS%)TY{yu|pgJ2aeO<(v5;aY6Y;rqM&49cSYDsmCrFyKKg5M@lOZJ_0NUim&unKz-667?T8_}p|Y!xQ`Ss}(Z3$MA>9h{ zG$P01@n)aDo$SMkXNK4G1>+Aoy0lMy;c!M#XE%oTV?y`|&fmj>o1_=WqQ7&Sv z*B*@R15T3572xPwEFXm5vX2cs`F6~q>CmRO?|c&7IK}GA5Z|Ml`4{QcKCQ*{9q&A3 zvEMdg5%@|Q?t7f<oclw96*nj_>VO^&a{hI$x_fqr-O_ zdSyqDxmv!#+J04ktd{Tk)SLPGh~a#Fhg{%q+I|~)mc`10fA7(NJoslY&H0&sEjxBS z+y6G_u)ZBmgOOk8Pm^B02d-Tke}A|GXMByW2J{|V$K_X9K4?8X!1aA2=56w20$JR_ z{gykp-%@LOR!4Up{I%{$WGvy{#SxNi*~W#)5BA5{Y4w+6PT%{x3b}FEcjL~M5!hpM zmP_-M6~r6g9ep2sxBRMp$~siX9!r$?u%Y8dW0!RA!yi>v4}J*YQx%4f+~Yptb>=Fs zN3E~^Y2Rjl6&e}G4>PVE#*XoA>%qC$H?Skpm;LWDFQQ;;f1yR~q#+|(m>0G9b0W

#d9r|uF^D5t8 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

  • dK_i{uxiqTrs-MWD4Y(*EXUhGS} zBN<>IdfTP5tNJ=Sm&wYBjtJ9SK6-l7EhxNteR3V#3+lF0!!>CbJg9Pet5_znq&iL< z$VFOcS$9ugc4<1@f$4$u-mN1oO^|SawL68M*Hpft!cO-n?Ou`R%;(}R=AC` zkkaA;lx}N-6;{#>P0dP++1j7#&2aW)o5HCtRx8IdnWQi?;X=lq^rNmlbRbuV;|f=- z9aPEH(4Q`-#p2Ge4N>YIEc`iLq5AJgHfGjSgM`(^^jlTtT#H~{uuy6fG#k4w9GdfQ z7W*{=)W3D~a;XYhE2b3J%Cs!kZ8`%m$DkLm9?2cpvO&R;d?*vPtg}6v?IgSGTF(GH z098WMSIW9IC42_X3UNWlQsBz$VL^6V>h|gvx%R}iB*kcEdOG_u98mC2`#&F>hDPor zlBuqq?0~ItL3e6Pl8g6V4W)1Q#0aYs`k%5oBZ<+4`AX7uV}FtEO}4i8w_|^+{B}4G zPZ_4;00M}@DUB*MOS`o#T$R>9zR=TuXMki~wq`KZl65m@H6#*=_#9L21?lc??BAf% z>r!o8i&WLyyJ6rkDPiQdr+Zs<;ZbJ$bL?pXwR25-OGjtKcWQ&*f_c!IN=9S_pJFej zs|}+7MZ$K~iBvQO3PqjAgzAT(;sziPbJ1;7nN(-n9{p%+#**p!v1VYSZV8ih^N-%J zD7k#us)beC0?BF-QYH2CW!gH>5f$Qns(>O zYIV-gyCKxIaZTtBSlgQ2p=MBgKQ}vV!4nOnKZ^MapMR@(JiX9kbXC@fbtx>6G?6P{ z#Nd0;^2k0#t46WC_y(HyZ)}lfQpxCht2DO5F}41#htg1#;*|tl@G4T=4RPnNU@JCe zYq0iUtKp_f1e_>$Ys2$6=}Cp+fJ?9iF$MHv0iEU+xEd0=u^KVuEhNB=s@J^l^q_EZQ>wQ) zozcY-@e(-jZm-0Z2HSSHQ_xo%ez=w=;Ur)?_5*NvBxr%UvnP2P+V5|mtl#cY9I zDZ#9Tc)QP<0d;lI1XjCKnG}i{_ihv91`WomXJh_DkYo)OCV*Z(I;IB#4$!0+5D@pH#PM-eM3f5H=+lv^ZVM`oPT1Ipn;P>qHku{p-bJmuwoWN z?<@*No3#@2aTy&@NDY5sbiF-YQfJ!#S#I^=^6duMtwD>Z{uwUgO=3MbaPz?$!vf39 zAw}E<{0HP+B>`j8WlE7m0o`7#Z|bL&z8+`us86!h-;hp2ZUdXV zoj!b8#!YC?>7v-6Siq*GGu71H*MsN*w#-~DDYI3uC;k9(+FRT;*wWr9_5lk&bOna4 z&GW&m?$6Y~-C`KIEf^=2O-0*XTa|Qd=FFNsCoyYIf-^=$CPU6SgRXJ80PCS$r&-_J zp52O25Z#-Mvj~h^s8xt)yb2O}B=IapfHYE5Hxr(>8)O}a`=ZlM`vD`otUJ>K-$r&USpIvt0O7}!dj`Y-q=b$>D!F9!YPepA zzi_qI;7b_xq9oL>)bOTqK+V$VqiKL+o*_Q4_gfxSQBAc|1igA>^VXHYU zy1UI{uDjTx)XaH>1w$-M(1S_Ko$wafC-(3!0%4d+7{(gu zz_~%=wWNvy22Q%xkpjluO82COua*G>eUr90?eo{ZSu^Y5>0u zwl}v^>5^FyiioiY4yT0mJWnQ@oB^J=#?VKWuqUUUI?8bU#TQx+r%c8REr_R)P*(#( zSjREUjb9rA9o@1{KyslA`&rR6Oaqb4?@kn3~=1`9uOilwC7zG(j zRi)34x984BY>Z`bRh>!uK2Xrw2XP`ok_iXPg1X>N4{#RaTwuMh0M#I0ix5#3tJH?| zO4c(56mzqbk#brFIr^dXQm&gpw1Ve5o}1OCXD04Q&{3L?oZDGx4PEq6cra>o{Ro6o z6D>B3C=Yj?$#f4l_|6>35=(tr*w@uH03H_T;i9s^)f4+IY~shL^6eorvI->(l4b8$#u=MXxVs$yVmae6p|{zD zVPqj}Td?=*$&K`inKDYr=60O-C1t1Af&DC22)8wrIW6`zu=PhQzjk7`?vdx9AM?c+ z+w1;RW%|GF)p1Co=TD(D#5_Tr$k%!v75l15=^!Y;rB_Z7bS~n+54$U^$3=6X3ld*M zcb#u#9SI{M3m6n$gm^T=EMh!onDJ!Tb}RgDJ$rMzxZK$rEg}O9n2v5}1FQ*|CLZVL zX)tbnpjJ_gXoJ=kX9E;0nVc0M3~JtovJqy@fzQzj?PC~(n^goo@hjI#qyb6iOgGcw z^6&>c9LB&-N_RE4r}WgMjVmGQ$p&pW?sHB|_YOVv4VJ9hShb*TR@Ln3Gp5I@YP#f3 zLk(`s9EOFyl?gq4hxNDh;9IscQ_~7%htp2wSQ)ebX(kis}of< zZQF5n){lQ-*IPPjFq^Ux+Ny!Wg19j@VHEJ9) zNLjONf%Tu75V|zzJN)=wQ&$cpW&n32z5lDTjNw_3?oCIQ5TqsLz&@G9T@N0eWjOOO zQM}q=cd+O&wvtf~pG}6UtY`6iEM~G;%Iaoa=!l*^p%V<-b2k_C^0XByjyN-p5ilgq zTJ-CNMQ+Aml6pK*AT10$VZ~RQ%PSY6Tx2%LBzSJ<6h@WkGriM97>&m63=2y;Sf@^h zz9PN5M59^}lcRTXWuaIYXv`h-PuSJV0bIcux!Afsh0twQHb;9(k-FTmJ>A_ofC13M zb1(LU@dp8Z{t#(cZc@Gd;bjRmqwvZxlUq}r*s-%J&MXuDin@j{0KrII2D@b4IzdGl zZt_Es{o#0aqf+eqH9TYxg>Y_3O0JEGC%n#*|wB}^e;1J47o948i7(FD)d^5L!JdH>oM;h(8~{t)5B8oZ;?$;gAWFyq_gq{TU4J(Yi-1E6-cXC zQMWf0q8ub1v!FAb!Ev(ZeTnf(Sscn1LM}>jLZNkHpNzmDRwCIAWiaHh2+pEJ<_fMV zaDTT&!mJA!GgQUH*<=&@AkLt1iiwQT|KH;fu1^igW(4YZ9E=4uvsI=!LNGJy!)S=7 zQ(`8(Gg4YJ-fWPoE>?sZER(yJ8AKgCX5-Z-_Rib$O6$h&#W*`ry_c-I-i&9g}d&X2WWDv%) zb!({m4DMr-yv>)u>^9N<2SVXsU@gtvKvJ2od5fjsE&@UtElqF|tlAZI7O{n;aJO_C z*CRIUL?Ej+lniSgW@A`v=I*B*;<#d1sq@?`;{PtK0~%zBxS1ofVGkoHE=JHp;fpmw z_uFt3@3tR%+zG=hdw8Fs*#$b3M23-K3S z3t-~llEK$>x?$Run-$!bizkW$13j`!B2a_yq->UD5;{}MsQ*bkM$(26=-FYLZ!^H~ zQlQ0qHUX<5O}Gi6Yo5_z+F{EcZq)6@j2>9?Y3bUY_MV#UTXC7KrnNq?tz}zhN^XcJ z=ggQrt6^qqBGE9Tu0Azq=A5?XmUv73?E1Ra=H}V68H>^YB^YhtYUK8Jn-?r?T&HKi zFtlAgktG%5EbgrA32`4&2VJf*=w_396pg7mxll-Z1VFT}dySro`)HFF%^{H4+a$YU zDjFH}?g}~WWE*b#z2_N2JkOg!eQ5o zgOOt_Tb>KZxeY%gazP^M7u>S-KxD03 z-0+akA};90dK56jrE`=nia6eK$1}NoD~3!iufc|?(~HX-ybi<-u-qq9_0?5xBTR-{ z@xqB>Rt3b{8L`6T<_*`-qvmOy@`?$(IE9ODE^JNr1xm6bi?cePOKOF`7$KbGM47ZG zEtWC(^fc`*Dvi#{4J54yi<9{+8a>riPEwOH+Ynj6Khvlgdf3_7-jhL{A~6gKZYLY- z4ChL)pcO1ble%#x0v!Z&kF?D>HHLEp8jjGT zFwj{@L921LMW#3|tZJN)9Sz`*2w&dREal9N>u7?4*9WQ;= zBThuP_5Ljck01d~V%=422sgaE&by$fP_3D-=B5fW(FQvuKEAcLVut%N3q=>vW03B1 zK#RGXN(apr8|;;f{4F}qc-ZYnA+GxI%+XK=z~0*k}px>_sllEWav5%WAGcT$9qwO#dvz}BV2hc{;zys59@JW853 za&IB{+(jgjyY@LeDDq>SD(>8@Q};hS`Pd_S72F)H4m{W$&E03YZ_6phE=aJi1#wLL zarP3zfJHqi*_z4Hf27v)x&w|ZLYGgLt@YdG9{%dwoft?Zi7iMM+zXy*tQpv>PX{H% z@sw$^H7$qmoMjqhA-%CpNx9Vpt=fv@E2Fb{>Oh1f8+db0>6BTyQj7T@x0F>KRWfcc z#JsBnO^q2Y@z#)jv7ovf=ZZq>T+=+K$>}ymIJpB?oZUrQF1?6uaoX?*AXkGsI={7tq!%uIxo5d-E}I3Fx>`NF@GE2G;fcLz-g5pi-xOV1B+<69I8is7QVjL{pBn>EdN znhegTT@gSgb!9I`XH{AU7M+wRdC=O4W9)AA{#7D+CZ}W_c*cj}VciKy+$r2haxi!d z^%;+WXutM$=T}FSSE#VAG0>~+d(kcSc@1)K_sR4+a2q_V#xCsS^jp-kMLjYT4^;0z zS+?EPCkhQ3EfE9SL~$Z5aw)1Ay@=s%{!tQ~BWMk7(YC&J9LKP@s%B~b2y+vf>-=uFHZVBeGAKSmqg_~ArnjzfE{sDI_^QrTC2P1H|LB2#k`6XUzMU49Z5XNc0Sd zYUp0d%|NUzyDu2KxrKA~@c;RQp~!nh!h%5IZX{XnAInm;@NCPThaz@*F9-r>A~>XM^xnKjS`zu+?@r`5Ah%lt2!BF8!jBGO{*p;bnRLF$q5+xrDrk#|ye-d;($FQCVp{yHJoW%Z(St~2x)urc~7j(7{^;65P$;@jw%V1ZA~g_(&j!V+C&PrThyjdi?+nO>QFW7BUFPgL@)LIrGMd zecW^8AZfK9+yrYF-l->ccHw0$3N#XDTGmacgMJiE#*$RlMr9T4xVGINJ+%wZmy+_Z zEwsTYf9PnE|3EiV?cHq*TeEU!D$PNcu@W=6n=zvju1aItGwcETfUuj~=Uj=1sjPq$ zy=jyxe8hYuchg7HL9YOXpdLIds<`L6X=i23BWYF++>MT_bv@kSXOj)K;==#gZ@pT*I>D>mDR_j2bNo(@Jhr~O(4Cyo-W zU^hK&cMCWwX3iSikV&nUhX|WG!wafTft=Royck9M)7dH#zSny`@#TT{tJE_{Tir{y6UI(Bd`@a$hm zx1b4Ufq-T%PJ znYEjl2$$H;3>weevm{K6T04K3_7dIU^ppErkTstnOdf;xK47BYUUa$>Hz8WZyU>1; zmTRZns_B7%JG@7Ha5o0lUgD0reaP?v6T>ptu=Ka5@l0PkqrH6iczcsvzvMY{f^Fen zw+qENANI56AL%2!RA@J>Y?W%i+i9@!_iv0ItP<@}$94(#*m$rnxrZH~5bls2njL4< zq>g_QoORxO*G@}6@bq_5A~v`=yr#mfZI^&rNrE&9gYUNlbe+N>^5#Y<(^#3ox$$O zn#z6eK|QBX3){D}BfiW#lMtp0m|}hR+VG!`Z^kJ;qP8?}_9&ur1?-lj?JRI0!!A1G zhR22Z7!%ef#N!YkPM$uAIaj5LT-PdG=~Wz&xqL!z}BXL&h{-^dFm(b35xkg zDVTok-F4&;lNqCH6*RWCZU~4{y|KeV5r9rOJ#CWRx|s*@cF-P` z#=HIJ??*6u*NZI;j}+K%-50U@%W{W4oP}&T;vXQ|#&N}lI&$q$wh-8Q;^~0MLrkCP z&Fs~#k|l3V=km|URd|ez2L*AMBE8-1*;)=r?vezwNl)L!PHK1)+gp<;wMdNO|7loE zyf)q*m+lE{)gH!u1;GNueQ=GnH-*4{1~ce`Oi(Ydk za9*w9^$D>AS`2qgZ5UXAZS*XqLu|D?UhK`l-5(@g5fAM3ROm~1OcmJkl!)xQhUDJ7 zDwN!>bLky{ymbaA*bFX(-j z&70G>=8SSs#XcU?Vv9(h4gQSGU9}H6(K25)$qcfqS73S%=TXCLxg)1^FO*$xOET(od2XP&OC7B z6<+K?2#t1xTNv!qvzYy01qXzk?x<1Z=kB!Gnn%N;HU+ZXxMA^Zxb;{e)19sE6(-v5 zYHT=pg9lWDjpQCxa&Cxb{IZ@N$&^|Xfr2d8!KgUh&JIJvPLP&w@inwY%syn`)Z z06@=IWM66W! zq5z!UZM;N?4Irig_aR^$(LO%Qb+nuMim0%E-rJittd|u@2bSE48;2@!p~|@}{mBlz-i%ip%j`sJlb>-+FbslUkD$*Ehpc#a8Ch6jsED$Ow3KzB_9 zZnx_W~VHYbk15mA9NE3Efg%z8{{zsCq)6eTzPwZ ze-~v2fOk$+#4tJ7dt)8LRMZF4H61U^!$k%s2&ZPE^|^4koz-XwXE1FlBd{61kqCxa zM+KL3;9*(^Fs3j|a_X}CKFA*+Mjk{lb*O3V@MtIA%VjDp3ks)%+AwiA@SOVm#)Za- z=m8yw@cA>$a(AW790Wvda9Hn@o{PiYo={Rb|C@M{W{QM%3qwVEBdd+Nem^q!aoxY|b3(q7T5hZo*3XuAI9xl;cx|en#^`S z*bMIg|9OFSj*&h~g5wvMfWU@}0W(|`X~$ux-rsTICN-?Gb#gABF4=fN@m@Y3T3Wum z!8iy?`66R{^7*Q7eCCE2FEGdFG5ll@Klyl@J3rlgxjR1j0bXy9&*{bT4=~=TjL!oh z#=Fq*d2gcpgM9wVA%4@K+F`A@IK=qfNPHgK&*kHd_xMaT2J?eL!3T$Ugy8#UD#Q5! zeo}#-BeWm+0e-s@pFttUZ{grGB*gepKzv4rc&y-Ho-3~%jn8*jJGOO|!}!G^?~@;l z^AP2OAAj&Z`2l`u$ou36_zec{lOL3Oh~+D6gfw|j@c#cS#n(5EbY#PW~m^Kc>PhTwO=PPhCR@Y%qvhS|T@fc2yOd)vdy zK~L<{FI^L*U*q9+&=b!EiId-%UOwe_zK6d6dg6mU`a8XR(%8#bI4d<4657;?D%U3 zKE=Z~0$=Lk-vHm{;gK*A4|%u|_yu5&E9>tBesXe#GPF0WY8Q zPkMMR=!tLk=sVeI`DlN4c=#C56Z`bVM@Q+aJe&nRu^UfT)#~MwpH2@mzvq}}eP??3 zTGU6(a+LQEfgb~&ZTLChK`zmL3DPGW2V+Sg z9t1se_17OCrQfg{F7@gwLwVv;j9>QmA}_xI`JE_#zL)>TZuNcY;l-dQzSryTr6-`U ze02QoJi#FP+YEYQ+A+ufolUv?rTBWkhffDRaVgRr{gYlk>7ViN<)9~?VDxtZzX$C1 zXGb$K<)i$a;^B8ePh5q0!uAGZ$=;R1@4tYacp~tV!1D~x1|HppUjQ*od7c8SAFcmP z53dD1@iQQB{n@Z3N`I7x)1W7w2Uo$-$GfBSmwMxOCg_Rp_3EE@V3dA^hpz)Yaq&L6 z`VWXj>96$KWB*2{qxr=iz6O=b3pO4bd z^Dz0HaC$U0Wu(x8ag# zey4})Q6KS@V{-CXdQ+7CgsxqQm+E8osxw!h|=In4ZvJk0z- zPe=2MJr&S_1%r~#Q(rJJAF9#`6&IF9wtB8 zx1#w+y`96%f6eo^iQWDKKdu(MgZ79IL3$o=3AQv_fiay0PXg`)=1zrw>w!-J277`R z0G|nrY6PzbKHtMFz?TBUY)gI*@GfBdBluK&x!KD<7x+$K&QG>?Iq*HeuKinq9|Fd7 zk^K9B9|JBn{4DS*9)1V-L$Cb5fCrW3_!&M7^84{{Zj}z^?u0fbRiz@_rro zeqbl>Pk)#iF5AgD@1g-~m`g9}kY+%Rloxt;eoqqfPcqy>s_X*$)z!lcsyTCmj z9sx$r2X^C81AH?u$b`SS!1n+<{#F7%1nl(dXy8YHU3(qC&j34qb^yNs?D#zk_%&cB zze|DN11_@mz6m_2B1iuN;6h->&y&EVz~!z#!1cgxeE$hN*TaQid?B!F4?i3jtnu)4 z;NyTD|MP&i0y}vx2k!LnCg2_qHv?yZ9e;hmrvtnC&H_Fk*!BMk;7frWzh4F31q`-D z-uD6D?3I5M_#R+a|4YCR0QVYw0VZDkguGy~;pxCf0Z%f#9(V^Zib?%jfzJkZ`o9DC zB4D_KlK%zZOMzYgzXW_G@L`t!9pLAHU4I?|egzoImz1Y{oNe(EcuK)9kWZ}b6-#`g z$KogW!N}ls3oH9{vgN zogV%J@Vy@X5cmNP=Z}Vddw4AHlOC=He#XNI;O9KN5cmZTZvcM9!)?H?dAJ|=4G*6U z{5G)aM@hgRJpa_ozYBQK>YV(320X;WF98>N_>aJ&J^XjzVh<04-%#q|3g8JIo(^2) z;YGkxJ$y9q0Uk~RAMD}Nf#V*&4Y=OJ&j8Q%@b7?^diZ1D6&@~tp3-r?bwflu-9hrnlhxB!Om zd=Kvje5r>I0lw11%Yk=!cr)+~9&Q2tiii7wZ}#vxz_)q$YT!FPd<*bB9=;FwUJpMB ze7}d^0Di#3bSxh7a5?ZJ9Mp6%fV;CaA~pH;w1z5Gt#HD3M~fsgX? zZvsBf!*>Ip;L$$@yw%J96L2Rm%na6tlHgO|E4}=os-dz4xqlv-gX8_uAezLJ^AEAR(|s59(Ns!k8Ualjo@Zv>`MPJ<>%uQ|j(oiLnR#dCop(OZoHO$v8kOEz z{FV0`Npig!Z(qXrtS>wdKwd7pet)O997-OA|Fs6o^V3Ps{|<;QdiZxCFIeO+dH&Q# z-k)$j!0?~;{Qn5y1xxtXJpX6mzmD;aIbi)^eDXdAEh%{s{(|=bGya2f_)lGjlDA=^ zC|Kf`_d_7SPTt9hqPKLXqJ4zs zDC|+#Bd|cxUj*hT+DB-P!XAY^0t*!VMPQDieT3#H>`~Ywut3pY1m-B(M`(`19)&#u z3l#lDV2+}FgytyhQP?A}K+#_W<|x`nXpX`jg*^fb6#YeDj-q{p<|yn@*dwq&(O(4S zDB4G8j=~;=Jpv09{Y7AoqJ4zsDC|+#Bd|cxUj*hT+DB-P!XAY^0t*!VMPQEqXYGUE z$G?{wd%gWiQ@}h=;vdcVANK-3i|_Mg|K%rvk9zw99s~ZIhyNUSvF*+)cmbH_UHm#e z>F0iix4%c92k-!rC4N8f(fhHd%HY$$PkHGzfO(!m&4m9=V4lBl7F!$`{tLh-J^lY4 z_%oh9-=;s#n|R5@e>2VvxYhILIRZzqf1MY1H7o)1Jc2DFzYY9pPyW|{-|+Oi49xRp z*ixv^H-NdnM(?+{KKT#e2fXlyvGJDYVLfH!e+roAK^!#s>jFRM$v+HyyO+Nwfn~o8 z_YXY{%<~EkV&4YSKQI97$-fVn=a<}P(yIYad;a$WU-HuXJn)kqeg>H5OT29C{Vm}8 zy!`L`F!t)VMJ@;ckRK5#dio_=yN#j_{Ww{0|ZS zW`y5}@OwWXxzp|E)(C$n!gCS+XoMRP{zQZyj_{)q{(}gAIl|wF@V6rTriTZRwQFw< z^LHe|gAtyL@ZAy4B78Bz4@CH(2tO9#ry~3p5q>ekFGu*z2p|4nnBSuj9**!-gqI@R zjqrmJe#FBA`;R1_^)TDZ7b5)E5q=@U{~Y1hBfS5XFn>Q3;eiO>8sQTWUWjlt!dnsk z)d)Wt;U^>fOoX40@V`d*^#~uhHO%k3B79?n%Mo6PaO&X!M7`}{me+$3{*4Gf5#gsJ z{9J^;9^scG{9h5i=C&}u?~d>-5uS>0a;(?w9IJ1v9y?d99;P&0T2d8^`9LN8ggXr6lk3H9R1ZWgTOntwiRK`nYOn{~a4)6tAMM=vQA3!0*$J_Vvop%ayXcB2i}& zIh0=utvfFur8ayuUxDJzX!h9Z7^K>2Z>QaM2IAb7kuc)zZ3IZGpzHz-*p>1hwIQvH zCdo)?`SJu=n{+H!WOv z!8(+ae8|O+%iGD2o9SLDrpXPVLx9}N(q=fvHh5jd?we$0Fypxn6AmhyF$E8pA0&3o zplp(Itdg7LjR0d*x7F)ZT{?=p!-nm4s%iaVqb}w_EY7cw=tFCUIuk{b)z@q&k7>oI z6cQha)^^sUBjx|Q6}_f%r%`N53=%3r7vW_ziPOoFw@BK`vCta~X| zFkMx=O^g9-(TXcnVkLL9{VgQ2fr|wV%MJ_@z`ofE-9S_&ajEjjw!q;TI+41|)#%OC z<5!oULaDc@=&z;Y(#S>@ldr)WJV$8?5=BhP!MYt2K=peE+>iaOmsXEOlmVtO8bZ3_PAiTWcQg<}fRYDQxD{ev$Q zC*bgk`)Pmek*RMpotmClnXth?K!?hrc+E8LAy{%sL&wYGBSu83o#ljbJqVr5#D-b? z{+O4wxfzxuocY7}jx#eR+umO5umb3I+pdH4KA=)M-xsG}LHc|hOEV)k3~^!%1ILVQ z3_Kn}H3|0u4@uSJNC(y;@DxeKHxUd;{7!;Y%YGb^q>~so5_BvVaipRBF+~XFc z8LiR|SU5K<)%2=~-OW}R%s8^(y|zu*^T&0mE8f5*PSTLPn3zq!FQjOHt5p#M0~46- z!9%#GM%tz(aXrXsYfQuqXhiWaLARjmqk}iFQK{YfQHs0Sisl(!1ud*}^=OG8j~*W_ zm&=2E@S<_(Rz`~)92+c4O;O3Z@scnuZ@TsMYjo`ERp}Vl3cB@;t#pigdggfN36+HK zdw%8Sk0x}Gc_V+z04{;Ox<*@^7(afZJbpr&6{RR)hX6Xn70Rse(46$nnVZr%w^LRb z?4MMsRB|Va^kG85q)Z%lsM!$TZ6e6fr&jz%6HLnJ?e}U*T(1QQ9jfF!ns`vs5a|{+T6z7>oN51R)Xb&WjJ3jXBA#5&vqgE?7wD#JquM3Pma$G92UI4?p z0b?JFQxc$pRJ?;Hs@~dKsS0ZDPIeBnNzfv1fwdCE)@ppMwNm{SAgyh+IvB}%7s0$r zB5lyuV(oPNIQyO)sdNobcObd%RJPMhk$CGVr?9PhNIymTqB_G@TzYXtox|~y(p7{V zibm(C#g7e%HS;=-F*{T33ntxeelY38!jdb?{3UQ69+plma4w$^&2no^xJ>1273cS= z0{0pEszN(H)ij-1nwUS8o?4i;Yj85zc5| c#4h&c^wY8sZkwA5YY3EAp6L+URyF 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/lxml/builder.py b/.venv/lib/python3.7/site-packages/lxml/builder.py new file mode 100644 index 0000000..d66c70b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/builder.py @@ -0,0 +1,233 @@ +# cython: language_level=2 + +# +# Element generator factory by Fredrik Lundh. +# +# Source: +# http://online.effbot.org/2006_11_01_archive.htm#et-builder +# http://effbot.python-hosting.com/file/stuff/sandbox/elementlib/builder.py +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2004 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + +""" +The ``E`` Element factory for generating XML documents. +""" + +from __future__ import absolute_import + +import lxml.etree as ET +_QName = ET.QName + +from functools import partial + +try: + basestring +except NameError: + basestring = str + +try: + unicode +except NameError: + unicode = str + + +class ElementMaker(object): + """Element generator factory. + + Unlike the ordinary Element factory, the E factory allows you to pass in + more than just a tag and some optional attributes; you can also pass in + text and other elements. The text is added as either text or tail + attributes, and elements are inserted at the right spot. Some small + examples:: + + >>> from lxml import etree as ET + >>> from lxml.builder import E + + >>> ET.tostring(E("tag")) + '' + >>> ET.tostring(E("tag", "text")) + 'text' + >>> ET.tostring(E("tag", "text", key="value")) + 'text' + >>> ET.tostring(E("tag", E("subtag", "text"), "tail")) + 'texttail' + + For simple tags, the factory also allows you to write ``E.tag(...)`` instead + of ``E('tag', ...)``:: + + >>> ET.tostring(E.tag()) + '' + >>> ET.tostring(E.tag("text")) + 'text' + >>> ET.tostring(E.tag(E.subtag("text"), "tail")) + 'texttail' + + Here's a somewhat larger example; this shows how to generate HTML + documents, using a mix of prepared factory functions for inline elements, + nested ``E.tag`` calls, and embedded XHTML fragments:: + + # some common inline elements + A = E.a + I = E.i + B = E.b + + def CLASS(v): + # helper function, 'class' is a reserved word + return {'class': v} + + page = ( + E.html( + E.head( + E.title("This is a sample document") + ), + E.body( + E.h1("Hello!", CLASS("title")), + E.p("This is a paragraph with ", B("bold"), " text in it!"), + E.p("This is another paragraph, with a ", + A("link", href="http://www.python.org"), "."), + E.p("Here are some reserved characters: ."), + ET.XML("

    And finally, here is an embedded XHTML fragment.

    "), + ) + ) + ) + + print ET.tostring(page) + + Here's a prettyprinted version of the output from the above script:: + + + + This is a sample document + + +

    Hello!

    +

    This is a paragraph with bold text in it!

    +
    +

    Here are some reserved characters: <spam&egg>.

    +

    And finally, here is an embedded XHTML fragment.

    + + + + For namespace support, you can pass a namespace map (``nsmap``) + and/or a specific target ``namespace`` to the ElementMaker class:: + + >>> E = ElementMaker(namespace="http://my.ns/") + >>> print(ET.tostring( E.test )) + + + >>> E = ElementMaker(namespace="http://my.ns/", nsmap={'p':'http://my.ns/'}) + >>> print(ET.tostring( E.test )) + + """ + + def __init__(self, typemap=None, + namespace=None, nsmap=None, makeelement=None): + self._namespace = '{' + namespace + '}' if namespace is not None else None + self._nsmap = dict(nsmap) if nsmap else None + + assert makeelement is None or callable(makeelement) + self._makeelement = makeelement if makeelement is not None else ET.Element + + # initialize the default type map functions for this element factory + typemap = dict(typemap) if typemap else {} + + def add_text(elem, item): + try: + last_child = elem[-1] + except IndexError: + elem.text = (elem.text or "") + item + else: + last_child.tail = (last_child.tail or "") + item + + def add_cdata(elem, cdata): + if elem.text: + raise ValueError("Can't add a CDATA section. Element already has some text: %r" % elem.text) + elem.text = cdata + + if str not in typemap: + typemap[str] = add_text + if unicode not in typemap: + typemap[unicode] = add_text + if ET.CDATA not in typemap: + typemap[ET.CDATA] = add_cdata + + def add_dict(elem, item): + attrib = elem.attrib + for k, v in item.items(): + if isinstance(v, basestring): + attrib[k] = v + else: + attrib[k] = typemap[type(v)](None, v) + + if dict not in typemap: + typemap[dict] = add_dict + + self._typemap = typemap + + def __call__(self, tag, *children, **attrib): + typemap = self._typemap + + # We'll usually get a 'str', and the compiled type check is very fast. + if not isinstance(tag, str) and isinstance(tag, _QName): + # A QName is explicitly qualified, do not look at self._namespace. + tag = tag.text + elif self._namespace is not None and tag[0] != '{': + tag = self._namespace + tag + elem = self._makeelement(tag, nsmap=self._nsmap) + if attrib: + typemap[dict](elem, attrib) + + for item in children: + if callable(item): + item = item() + t = typemap.get(type(item)) + if t is None: + if ET.iselement(item): + elem.append(item) + continue + for basetype in type(item).__mro__: + # See if the typemap knows of any of this type's bases. + t = typemap.get(basetype) + if t is not None: + break + else: + raise TypeError("bad argument type: %s(%r)" % + (type(item).__name__, item)) + v = t(elem, item) + if v: + typemap.get(type(v))(elem, v) + + return elem + + def __getattr__(self, tag): + return partial(self, tag) + + +# create factory object +E = ElementMaker() diff --git a/.venv/lib/python3.7/site-packages/lxml/classlookup.pxi b/.venv/lib/python3.7/site-packages/lxml/classlookup.pxi new file mode 100644 index 0000000..ba55927 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/classlookup.pxi @@ -0,0 +1,580 @@ +# Configurable Element class lookup + +################################################################################ +# Custom Element classes + +cdef public class ElementBase(_Element) [ type LxmlElementBaseType, + object LxmlElementBase ]: + u"""ElementBase(*children, attrib=None, nsmap=None, **_extra) + + The public Element class. All custom Element classes must inherit + from this one. To create an Element, use the `Element()` factory. + + BIG FAT WARNING: Subclasses *must not* override __init__ or + __new__ as it is absolutely undefined when these objects will be + created or destroyed. All persistent state of Elements must be + stored in the underlying XML. If you really need to initialize + the object after creation, you can implement an ``_init(self)`` + method that will be called directly after object creation. + + Subclasses of this class can be instantiated to create a new + Element. By default, the tag name will be the class name and the + namespace will be empty. You can modify this with the following + class attributes: + + * TAG - the tag name, possibly containing a namespace in Clark + notation + + * NAMESPACE - the default namespace URI, unless provided as part + of the TAG attribute. + + * HTML - flag if the class is an HTML tag, as opposed to an XML + tag. This only applies to un-namespaced tags and defaults to + false (i.e. XML). + + * PARSER - the parser that provides the configuration for the + newly created document. Providing an HTML parser here will + default to creating an HTML element. + + In user code, the latter three are commonly inherited in class + hierarchies that implement a common namespace. + """ + def __init__(self, *children, attrib=None, nsmap=None, **_extra): + u"""ElementBase(*children, attrib=None, nsmap=None, **_extra) + """ + cdef bint is_html = 0 + cdef _BaseParser parser + cdef _Element last_child + # don't use normal attribute access as it might be overridden + _getattr = object.__getattribute__ + try: + namespace = _utf8(_getattr(self, 'NAMESPACE')) + except AttributeError: + namespace = None + try: + ns, tag = _getNsTag(_getattr(self, 'TAG')) + if ns is not None: + namespace = ns + except AttributeError: + tag = _utf8(_getattr(_getattr(self, '__class__'), '__name__')) + if b'.' in tag: + tag = tag.split(b'.')[-1] + try: + parser = _getattr(self, 'PARSER') + except AttributeError: + parser = None + for child in children: + if isinstance(child, _Element): + parser = (<_Element>child)._doc._parser + break + if isinstance(parser, HTMLParser): + is_html = 1 + if namespace is None: + try: + is_html = _getattr(self, 'HTML') + except AttributeError: + pass + _initNewElement(self, is_html, tag, namespace, parser, + attrib, nsmap, _extra) + last_child = None + for child in children: + if _isString(child): + if last_child is None: + _setNodeText(self._c_node, + (_collectText(self._c_node.children) or '') + child) + else: + _setTailText(last_child._c_node, + (_collectText(last_child._c_node.next) or '') + child) + elif isinstance(child, _Element): + last_child = child + _appendChild(self, last_child) + elif isinstance(child, type) and issubclass(child, ElementBase): + last_child = child() + _appendChild(self, last_child) + else: + raise TypeError, f"Invalid child type: {type(child)!r}" + +cdef class CommentBase(_Comment): + u"""All custom Comment classes must inherit from this one. + + To create an XML Comment instance, use the ``Comment()`` factory. + + Subclasses *must not* override __init__ or __new__ as it is + absolutely undefined when these objects will be created or + destroyed. All persistent state of Comments must be stored in the + underlying XML. If you really need to initialize the object after + creation, you can implement an ``_init(self)`` method that will be + called after object creation. + """ + def __init__(self, text): + # copied from Comment() factory + cdef _Document doc + cdef xmlDoc* c_doc + if text is None: + text = b'' + else: + text = _utf8(text) + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + self._c_node = _createComment(c_doc, _xcstr(text)) + if self._c_node is NULL: + raise MemoryError() + tree.xmlAddChild(c_doc, self._c_node) + _registerProxy(self, doc, self._c_node) + self._init() + +cdef class PIBase(_ProcessingInstruction): + u"""All custom Processing Instruction classes must inherit from this one. + + To create an XML ProcessingInstruction instance, use the ``PI()`` + factory. + + Subclasses *must not* override __init__ or __new__ as it is + absolutely undefined when these objects will be created or + destroyed. All persistent state of PIs must be stored in the + underlying XML. If you really need to initialize the object after + creation, you can implement an ``_init(self)`` method that will be + called after object creation. + """ + def __init__(self, target, text=None): + # copied from PI() factory + cdef _Document doc + cdef xmlDoc* c_doc + target = _utf8(target) + if text is None: + text = b'' + else: + text = _utf8(text) + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + self._c_node = _createPI(c_doc, _xcstr(target), _xcstr(text)) + if self._c_node is NULL: + raise MemoryError() + tree.xmlAddChild(c_doc, self._c_node) + _registerProxy(self, doc, self._c_node) + self._init() + +cdef class EntityBase(_Entity): + u"""All custom Entity classes must inherit from this one. + + To create an XML Entity instance, use the ``Entity()`` factory. + + Subclasses *must not* override __init__ or __new__ as it is + absolutely undefined when these objects will be created or + destroyed. All persistent state of Entities must be stored in the + underlying XML. If you really need to initialize the object after + creation, you can implement an ``_init(self)`` method that will be + called after object creation. + """ + def __init__(self, name): + cdef _Document doc + cdef xmlDoc* c_doc + name_utf = _utf8(name) + c_name = _xcstr(name_utf) + if c_name[0] == c'#': + if not _characterReferenceIsValid(c_name + 1): + raise ValueError, f"Invalid character reference: '{name}'" + elif not _xmlNameIsValid(c_name): + raise ValueError, f"Invalid entity reference: '{name}'" + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + self._c_node = _createEntity(c_doc, c_name) + if self._c_node is NULL: + raise MemoryError() + tree.xmlAddChild(c_doc, self._c_node) + _registerProxy(self, doc, self._c_node) + self._init() + + +cdef int _validateNodeClass(xmlNode* c_node, cls) except -1: + if c_node.type == tree.XML_ELEMENT_NODE: + expected = ElementBase + elif c_node.type == tree.XML_COMMENT_NODE: + expected = CommentBase + elif c_node.type == tree.XML_ENTITY_REF_NODE: + expected = EntityBase + elif c_node.type == tree.XML_PI_NODE: + expected = PIBase + else: + assert False, f"Unknown node type: {c_node.type}" + + if not (isinstance(cls, type) and issubclass(cls, expected)): + raise TypeError( + f"result of class lookup must be subclass of {type(expected)}, got {type(cls)}") + return 0 + + +################################################################################ +# Element class lookup + +ctypedef public object (*_element_class_lookup_function)(object, _Document, xmlNode*) + +# class to store element class lookup functions +cdef public class ElementClassLookup [ type LxmlElementClassLookupType, + object LxmlElementClassLookup ]: + u"""ElementClassLookup(self) + Superclass of Element class lookups. + """ + cdef _element_class_lookup_function _lookup_function + + +cdef public class FallbackElementClassLookup(ElementClassLookup) \ + [ type LxmlFallbackElementClassLookupType, + object LxmlFallbackElementClassLookup ]: + u"""FallbackElementClassLookup(self, fallback=None) + + Superclass of Element class lookups with additional fallback. + """ + cdef readonly ElementClassLookup fallback + cdef _element_class_lookup_function _fallback_function + def __cinit__(self): + # fall back to default lookup + self._fallback_function = _lookupDefaultElementClass + + def __init__(self, ElementClassLookup fallback=None): + if fallback is not None: + self._setFallback(fallback) + else: + self._fallback_function = _lookupDefaultElementClass + + cdef void _setFallback(self, ElementClassLookup lookup): + u"""Sets the fallback scheme for this lookup method. + """ + self.fallback = lookup + self._fallback_function = lookup._lookup_function + if self._fallback_function is NULL: + self._fallback_function = _lookupDefaultElementClass + + def set_fallback(self, ElementClassLookup lookup not None): + u"""set_fallback(self, lookup) + + Sets the fallback scheme for this lookup method. + """ + self._setFallback(lookup) + +cdef inline object _callLookupFallback(FallbackElementClassLookup lookup, + _Document doc, xmlNode* c_node): + return lookup._fallback_function(lookup.fallback, doc, c_node) + + +################################################################################ +# default lookup scheme + +cdef class ElementDefaultClassLookup(ElementClassLookup): + u"""ElementDefaultClassLookup(self, element=None, comment=None, pi=None, entity=None) + Element class lookup scheme that always returns the default Element + class. + + The keyword arguments ``element``, ``comment``, ``pi`` and ``entity`` + accept the respective Element classes. + """ + cdef readonly object element_class + cdef readonly object comment_class + cdef readonly object pi_class + cdef readonly object entity_class + def __cinit__(self): + self._lookup_function = _lookupDefaultElementClass + + def __init__(self, element=None, comment=None, pi=None, entity=None): + if element is None: + self.element_class = _Element + elif issubclass(element, ElementBase): + self.element_class = element + else: + raise TypeError, u"element class must be subclass of ElementBase" + + if comment is None: + self.comment_class = _Comment + elif issubclass(comment, CommentBase): + self.comment_class = comment + else: + raise TypeError, u"comment class must be subclass of CommentBase" + + if entity is None: + self.entity_class = _Entity + elif issubclass(entity, EntityBase): + self.entity_class = entity + else: + raise TypeError, u"Entity class must be subclass of EntityBase" + + if pi is None: + self.pi_class = None # special case, see below + elif issubclass(pi, PIBase): + self.pi_class = pi + else: + raise TypeError, u"PI class must be subclass of PIBase" + +cdef object _lookupDefaultElementClass(state, _Document _doc, xmlNode* c_node): + u"Trivial class lookup function that always returns the default class." + if c_node.type == tree.XML_ELEMENT_NODE: + if state is not None: + return (state).element_class + else: + return _Element + elif c_node.type == tree.XML_COMMENT_NODE: + if state is not None: + return (state).comment_class + else: + return _Comment + elif c_node.type == tree.XML_ENTITY_REF_NODE: + if state is not None: + return (state).entity_class + else: + return _Entity + elif c_node.type == tree.XML_PI_NODE: + if state is None or (state).pi_class is None: + # special case XSLT-PI + if c_node.name is not NULL and c_node.content is not NULL: + if tree.xmlStrcmp(c_node.name, "xml-stylesheet") == 0: + if tree.xmlStrstr(c_node.content, "text/xsl") is not NULL or \ + tree.xmlStrstr(c_node.content, "text/xml") is not NULL: + return _XSLTProcessingInstruction + return _ProcessingInstruction + else: + return (state).pi_class + else: + assert False, f"Unknown node type: {c_node.type}" + + +################################################################################ +# attribute based lookup scheme + +cdef class AttributeBasedElementClassLookup(FallbackElementClassLookup): + u"""AttributeBasedElementClassLookup(self, attribute_name, class_mapping, fallback=None) + Checks an attribute of an Element and looks up the value in a + class dictionary. + + Arguments: + - attribute name - '{ns}name' style string + - class mapping - Python dict mapping attribute values to Element classes + - fallback - optional fallback lookup mechanism + + A None key in the class mapping will be checked if the attribute is + missing. + """ + cdef object _class_mapping + cdef tuple _pytag + cdef const_xmlChar* _c_ns + cdef const_xmlChar* _c_name + def __cinit__(self): + self._lookup_function = _attribute_class_lookup + + def __init__(self, attribute_name, class_mapping, + ElementClassLookup fallback=None): + self._pytag = _getNsTag(attribute_name) + ns, name = self._pytag + if ns is None: + self._c_ns = NULL + else: + self._c_ns = _xcstr(ns) + self._c_name = _xcstr(name) + self._class_mapping = dict(class_mapping) + + FallbackElementClassLookup.__init__(self, fallback) + +cdef object _attribute_class_lookup(state, _Document doc, xmlNode* c_node): + cdef AttributeBasedElementClassLookup lookup + cdef python.PyObject* dict_result + + lookup = state + if c_node.type == tree.XML_ELEMENT_NODE: + value = _attributeValueFromNsName( + c_node, lookup._c_ns, lookup._c_name) + dict_result = python.PyDict_GetItem(lookup._class_mapping, value) + if dict_result is not NULL: + cls = dict_result + _validateNodeClass(c_node, cls) + return cls + return _callLookupFallback(lookup, doc, c_node) + + +################################################################################ +# per-parser lookup scheme + +cdef class ParserBasedElementClassLookup(FallbackElementClassLookup): + u"""ParserBasedElementClassLookup(self, fallback=None) + Element class lookup based on the XML parser. + """ + def __cinit__(self): + self._lookup_function = _parser_class_lookup + +cdef object _parser_class_lookup(state, _Document doc, xmlNode* c_node): + if doc._parser._class_lookup is not None: + return doc._parser._class_lookup._lookup_function( + doc._parser._class_lookup, doc, c_node) + return _callLookupFallback(state, doc, c_node) + + +################################################################################ +# custom class lookup based on node type, namespace, name + +cdef class CustomElementClassLookup(FallbackElementClassLookup): + u"""CustomElementClassLookup(self, fallback=None) + Element class lookup based on a subclass method. + + You can inherit from this class and override the method:: + + lookup(self, type, doc, namespace, name) + + to lookup the element class for a node. Arguments of the method: + * type: one of 'element', 'comment', 'PI', 'entity' + * doc: document that the node is in + * namespace: namespace URI of the node (or None for comments/PIs/entities) + * name: name of the element/entity, None for comments, target for PIs + + If you return None from this method, the fallback will be called. + """ + def __cinit__(self): + self._lookup_function = _custom_class_lookup + + def lookup(self, type, doc, namespace, name): + u"lookup(self, type, doc, namespace, name)" + return None + +cdef object _custom_class_lookup(state, _Document doc, xmlNode* c_node): + cdef CustomElementClassLookup lookup + + lookup = state + + if c_node.type == tree.XML_ELEMENT_NODE: + element_type = u"element" + elif c_node.type == tree.XML_COMMENT_NODE: + element_type = u"comment" + elif c_node.type == tree.XML_PI_NODE: + element_type = u"PI" + elif c_node.type == tree.XML_ENTITY_REF_NODE: + element_type = u"entity" + else: + element_type = u"element" + if c_node.name is NULL: + name = None + else: + name = funicode(c_node.name) + c_str = tree._getNs(c_node) + ns = funicode(c_str) if c_str is not NULL else None + + cls = lookup.lookup(element_type, doc, ns, name) + if cls is not None: + _validateNodeClass(c_node, cls) + return cls + return _callLookupFallback(lookup, doc, c_node) + + +################################################################################ +# read-only tree based class lookup + +cdef class PythonElementClassLookup(FallbackElementClassLookup): + u"""PythonElementClassLookup(self, fallback=None) + Element class lookup based on a subclass method. + + This class lookup scheme allows access to the entire XML tree in + read-only mode. To use it, re-implement the ``lookup(self, doc, + root)`` method in a subclass:: + + from lxml import etree, pyclasslookup + + class MyElementClass(etree.ElementBase): + honkey = True + + class MyLookup(pyclasslookup.PythonElementClassLookup): + def lookup(self, doc, root): + if root.tag == "sometag": + return MyElementClass + else: + for child in root: + if child.tag == "someothertag": + return MyElementClass + # delegate to default + return None + + If you return None from this method, the fallback will be called. + + The first argument is the opaque document instance that contains + the Element. The second argument is a lightweight Element proxy + implementation that is only valid during the lookup. Do not try + to keep a reference to it. Once the lookup is done, the proxy + will be invalid. + + Also, you cannot wrap such a read-only Element in an ElementTree, + and you must take care not to keep a reference to them outside of + the `lookup()` method. + + Note that the API of the Element objects is not complete. It is + purely read-only and does not support all features of the normal + `lxml.etree` API (such as XPath, extended slicing or some + iteration methods). + + See https://lxml.de/element_classes.html + """ + def __cinit__(self): + self._lookup_function = _python_class_lookup + + def lookup(self, doc, element): + u"""lookup(self, doc, element) + + Override this method to implement your own lookup scheme. + """ + return None + +cdef object _python_class_lookup(state, _Document doc, tree.xmlNode* c_node): + cdef PythonElementClassLookup lookup + cdef _ReadOnlyProxy proxy + lookup = state + + proxy = _newReadOnlyProxy(None, c_node) + cls = lookup.lookup(doc, proxy) + _freeReadOnlyProxies(proxy) + + if cls is not None: + _validateNodeClass(c_node, cls) + return cls + return _callLookupFallback(lookup, doc, c_node) + +################################################################################ +# Global setup + +cdef _element_class_lookup_function LOOKUP_ELEMENT_CLASS +cdef object ELEMENT_CLASS_LOOKUP_STATE + +cdef void _setElementClassLookupFunction( + _element_class_lookup_function function, object state): + global LOOKUP_ELEMENT_CLASS, ELEMENT_CLASS_LOOKUP_STATE + if function is NULL: + state = DEFAULT_ELEMENT_CLASS_LOOKUP + function = DEFAULT_ELEMENT_CLASS_LOOKUP._lookup_function + + ELEMENT_CLASS_LOOKUP_STATE = state + LOOKUP_ELEMENT_CLASS = function + +def set_element_class_lookup(ElementClassLookup lookup = None): + u"""set_element_class_lookup(lookup = None) + + Set the global element class lookup method. + + This defines the main entry point for looking up element implementations. + The standard implementation uses the :class:`ParserBasedElementClassLookup` + to delegate to different lookup schemes for each parser. + + .. warning:: + + This should only be changed by applications, not by library packages. + In most cases, parser specific lookups should be preferred, + which can be configured via + :meth:`~lxml.etree.XMLParser.set_element_class_lookup` + (and the same for HTML parsers). + + Globally replacing the element class lookup by something other than a + :class:`ParserBasedElementClassLookup` will prevent parser specific lookup + schemes from working. Several tools rely on parser specific lookups, + including :mod:`lxml.html` and :mod:`lxml.objectify`. + """ + if lookup is None or lookup._lookup_function is NULL: + _setElementClassLookupFunction(NULL, None) + else: + _setElementClassLookupFunction(lookup._lookup_function, lookup) + +# default setup: parser delegation +cdef ParserBasedElementClassLookup DEFAULT_ELEMENT_CLASS_LOOKUP +DEFAULT_ELEMENT_CLASS_LOOKUP = ParserBasedElementClassLookup() + +set_element_class_lookup(DEFAULT_ELEMENT_CLASS_LOOKUP) diff --git a/.venv/lib/python3.7/site-packages/lxml/cleanup.pxi b/.venv/lib/python3.7/site-packages/lxml/cleanup.pxi new file mode 100644 index 0000000..ca9f5c6 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/cleanup.pxi @@ -0,0 +1,215 @@ +# functions for tree cleanup and removing elements from subtrees + +def cleanup_namespaces(tree_or_element, top_nsmap=None, keep_ns_prefixes=None): + u"""cleanup_namespaces(tree_or_element, top_nsmap=None, keep_ns_prefixes=None) + + Remove all namespace declarations from a subtree that are not used + by any of the elements or attributes in that tree. + + If a 'top_nsmap' is provided, it must be a mapping from prefixes + to namespace URIs. These namespaces will be declared on the top + element of the subtree before running the cleanup, which allows + moving namespace declarations to the top of the tree. + + If a 'keep_ns_prefixes' is provided, it must be a list of prefixes. + These prefixes will not be removed as part of the cleanup. + """ + element = _rootNodeOrRaise(tree_or_element) + c_element = element._c_node + + if top_nsmap: + doc = element._doc + # declare namespaces from nsmap, then apply them to the subtree + _setNodeNamespaces(c_element, doc, None, top_nsmap) + moveNodeToDocument(doc, c_element.doc, c_element) + + keep_ns_prefixes = ( + set([_utf8(prefix) for prefix in keep_ns_prefixes]) + if keep_ns_prefixes else None) + + _removeUnusedNamespaceDeclarations(c_element, keep_ns_prefixes) + + +def strip_attributes(tree_or_element, *attribute_names): + u"""strip_attributes(tree_or_element, *attribute_names) + + Delete all attributes with the provided attribute names from an + Element (or ElementTree) and its descendants. + + Attribute names can contain wildcards as in `_Element.iter`. + + Example usage:: + + strip_attributes(root_element, + 'simpleattr', + '{http://some/ns}attrname', + '{http://other/ns}*') + """ + cdef _MultiTagMatcher matcher + element = _rootNodeOrRaise(tree_or_element) + if not attribute_names: + return + + matcher = _MultiTagMatcher.__new__(_MultiTagMatcher, attribute_names) + matcher.cacheTags(element._doc) + if matcher.rejectsAllAttributes(): + return + _strip_attributes(element._c_node, matcher) + + +cdef _strip_attributes(xmlNode* c_node, _MultiTagMatcher matcher): + cdef xmlAttr* c_attr + cdef xmlAttr* c_next_attr + tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_node, c_node, 1) + if c_node.type == tree.XML_ELEMENT_NODE: + c_attr = c_node.properties + while c_attr is not NULL: + c_next_attr = c_attr.next + if matcher.matchesAttribute(c_attr): + tree.xmlRemoveProp(c_attr) + c_attr = c_next_attr + tree.END_FOR_EACH_ELEMENT_FROM(c_node) + + +def strip_elements(tree_or_element, *tag_names, bint with_tail=True): + u"""strip_elements(tree_or_element, *tag_names, with_tail=True) + + Delete all elements with the provided tag names from a tree or + subtree. This will remove the elements and their entire subtree, + including all their attributes, text content and descendants. It + will also remove the tail text of the element unless you + explicitly set the ``with_tail`` keyword argument option to False. + + Tag names can contain wildcards as in `_Element.iter`. + + Note that this will not delete the element (or ElementTree root + element) that you passed even if it matches. It will only treat + its descendants. If you want to include the root element, check + its tag name directly before even calling this function. + + Example usage:: + + strip_elements(some_element, + 'simpletagname', # non-namespaced tag + '{http://some/ns}tagname', # namespaced tag + '{http://some/other/ns}*' # any tag from a namespace + lxml.etree.Comment # comments + ) + """ + cdef _MultiTagMatcher matcher + doc = _documentOrRaise(tree_or_element) + element = _rootNodeOrRaise(tree_or_element) + if not tag_names: + return + + matcher = _MultiTagMatcher.__new__(_MultiTagMatcher, tag_names) + matcher.cacheTags(doc) + if matcher.rejectsAll(): + return + + if isinstance(tree_or_element, _ElementTree): + # include PIs and comments next to the root node + if matcher.matchesType(tree.XML_COMMENT_NODE): + _removeSiblings(element._c_node, tree.XML_COMMENT_NODE, with_tail) + if matcher.matchesType(tree.XML_PI_NODE): + _removeSiblings(element._c_node, tree.XML_PI_NODE, with_tail) + _strip_elements(doc, element._c_node, matcher, with_tail) + +cdef _strip_elements(_Document doc, xmlNode* c_node, _MultiTagMatcher matcher, + bint with_tail): + cdef xmlNode* c_child + cdef xmlNode* c_next + + tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_node, c_node, 1) + if c_node.type == tree.XML_ELEMENT_NODE: + # we run through the children here to prevent any problems + # with the tree iteration which would occur if we unlinked the + # c_node itself + c_child = _findChildForwards(c_node, 0) + while c_child is not NULL: + c_next = _nextElement(c_child) + if matcher.matches(c_child): + if c_child.type == tree.XML_ELEMENT_NODE: + if not with_tail: + tree.xmlUnlinkNode(c_child) + _removeNode(doc, c_child) + else: + if with_tail: + _removeText(c_child.next) + tree.xmlUnlinkNode(c_child) + attemptDeallocation(c_child) + c_child = c_next + tree.END_FOR_EACH_ELEMENT_FROM(c_node) + + +def strip_tags(tree_or_element, *tag_names): + u"""strip_tags(tree_or_element, *tag_names) + + Delete all elements with the provided tag names from a tree or + subtree. This will remove the elements and their attributes, but + *not* their text/tail content or descendants. Instead, it will + merge the text content and children of the element into its + parent. + + Tag names can contain wildcards as in `_Element.iter`. + + Note that this will not delete the element (or ElementTree root + element) that you passed even if it matches. It will only treat + its descendants. + + Example usage:: + + strip_tags(some_element, + 'simpletagname', # non-namespaced tag + '{http://some/ns}tagname', # namespaced tag + '{http://some/other/ns}*' # any tag from a namespace + Comment # comments (including their text!) + ) + """ + cdef _MultiTagMatcher matcher + doc = _documentOrRaise(tree_or_element) + element = _rootNodeOrRaise(tree_or_element) + if not tag_names: + return + + matcher = _MultiTagMatcher.__new__(_MultiTagMatcher, tag_names) + matcher.cacheTags(doc) + if matcher.rejectsAll(): + return + + if isinstance(tree_or_element, _ElementTree): + # include PIs and comments next to the root node + if matcher.matchesType(tree.XML_COMMENT_NODE): + _removeSiblings(element._c_node, tree.XML_COMMENT_NODE, 0) + if matcher.matchesType(tree.XML_PI_NODE): + _removeSiblings(element._c_node, tree.XML_PI_NODE, 0) + _strip_tags(doc, element._c_node, matcher) + +cdef _strip_tags(_Document doc, xmlNode* c_node, _MultiTagMatcher matcher): + cdef xmlNode* c_child + cdef xmlNode* c_next + + tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_node, c_node, 1) + if c_node.type == tree.XML_ELEMENT_NODE: + # we run through the children here to prevent any problems + # with the tree iteration which would occur if we unlinked the + # c_node itself + c_child = _findChildForwards(c_node, 0) + while c_child is not NULL: + if not matcher.matches(c_child): + c_child = _nextElement(c_child) + continue + if c_child.type == tree.XML_ELEMENT_NODE: + c_next = _findChildForwards(c_child, 0) or _nextElement(c_child) + _replaceNodeByChildren(doc, c_child) + if not attemptDeallocation(c_child): + if c_child.nsDef is not NULL: + # make namespaces absolute + moveNodeToDocument(doc, doc._c_doc, c_child) + c_child = c_next + else: + c_next = _nextElement(c_child) + tree.xmlUnlinkNode(c_child) + attemptDeallocation(c_child) + c_child = c_next + tree.END_FOR_EACH_ELEMENT_FROM(c_node) diff --git a/.venv/lib/python3.7/site-packages/lxml/cssselect.py b/.venv/lib/python3.7/site-packages/lxml/cssselect.py new file mode 100644 index 0000000..df57681 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/cssselect.py @@ -0,0 +1,102 @@ +"""CSS Selectors based on XPath. + +This module supports selecting XML/HTML tags based on CSS selectors. +See the `CSSSelector` class for details. + +This is a thin wrapper around cssselect 0.7 or later. +""" + +from __future__ import absolute_import + +from . import etree +try: + import cssselect as external_cssselect +except ImportError: + raise ImportError( + 'cssselect does not seem to be installed. ' + 'See https://pypi.org/project/cssselect/') + + +SelectorSyntaxError = external_cssselect.SelectorSyntaxError +ExpressionError = external_cssselect.ExpressionError +SelectorError = external_cssselect.SelectorError + + +__all__ = ['SelectorSyntaxError', 'ExpressionError', 'SelectorError', + 'CSSSelector'] + + +class LxmlTranslator(external_cssselect.GenericTranslator): + """ + A custom CSS selector to XPath translator with lxml-specific extensions. + """ + def xpath_contains_function(self, xpath, function): + # Defined there, removed in later drafts: + # http://www.w3.org/TR/2001/CR-css3-selectors-20011113/#content-selectors + if function.argument_types() not in (['STRING'], ['IDENT']): + raise ExpressionError( + "Expected a single string or ident for :contains(), got %r" + % function.arguments) + value = function.arguments[0].value + return xpath.add_condition( + 'contains(__lxml_internal_css:lower-case(string(.)), %s)' + % self.xpath_literal(value.lower())) + + +class LxmlHTMLTranslator(LxmlTranslator, external_cssselect.HTMLTranslator): + """ + lxml extensions + HTML support. + """ + + +def _make_lower_case(context, s): + return s.lower() + +ns = etree.FunctionNamespace('http://codespeak.net/lxml/css/') +ns.prefix = '__lxml_internal_css' +ns['lower-case'] = _make_lower_case + + +class CSSSelector(etree.XPath): + """A CSS selector. + + Usage:: + + >>> from lxml import etree, cssselect + >>> select = cssselect.CSSSelector("a tag > child") + + >>> root = etree.XML("TEXT") + >>> [ el.tag for el in select(root) ] + ['child'] + + To use CSS namespaces, you need to pass a prefix-to-namespace + mapping as ``namespaces`` keyword argument:: + + >>> rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' + >>> select_ns = cssselect.CSSSelector('root > rdf|Description', + ... namespaces={'rdf': rdfns}) + + >>> rdf = etree.XML(( + ... '' + ... 'blah' + ... '') % rdfns) + >>> [(el.tag, el.text) for el in select_ns(rdf)] + [('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description', 'blah')] + + """ + def __init__(self, css, namespaces=None, translator='xml'): + if translator == 'xml': + translator = LxmlTranslator() + elif translator == 'html': + translator = LxmlHTMLTranslator() + elif translator == 'xhtml': + translator = LxmlHTMLTranslator(xhtml=True) + path = translator.css_to_xpath(css) + etree.XPath.__init__(self, path, namespaces=namespaces) + self.css = css + + def __repr__(self): + return '<%s %s for %r>' % ( + self.__class__.__name__, + hex(abs(id(self)))[2:], + self.css) diff --git a/.venv/lib/python3.7/site-packages/lxml/debug.pxi b/.venv/lib/python3.7/site-packages/lxml/debug.pxi new file mode 100644 index 0000000..a0dc62e --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/debug.pxi @@ -0,0 +1,91 @@ + +@cython.final +@cython.internal +cdef class _MemDebug: + """Debugging support for the memory allocation in libxml2. + """ + def bytes_used(self): + """bytes_used(self) + + Returns the total amount of memory (in bytes) currently used by libxml2. + Note that libxml2 constrains this value to a C int, which limits + the accuracy on 64 bit systems. + """ + return tree.xmlMemUsed() + + def blocks_used(self): + """blocks_used(self) + + Returns the total number of memory blocks currently allocated by libxml2. + Note that libxml2 constrains this value to a C int, which limits + the accuracy on 64 bit systems. + """ + return tree.xmlMemBlocks() + + def dict_size(self): + """dict_size(self) + + Returns the current size of the global name dictionary used by libxml2 + for the current thread. Each thread has its own dictionary. + """ + c_dict = __GLOBAL_PARSER_CONTEXT._getThreadDict(NULL) + if c_dict is NULL: + raise MemoryError() + return tree.xmlDictSize(c_dict) + + def dump(self, output_file=None, byte_count=None): + """dump(self, output_file=None, byte_count=None) + + Dumps the current memory blocks allocated by libxml2 to a file. + + The optional parameter 'output_file' specifies the file path. It defaults + to the file ".memorylist" in the current directory. + + The optional parameter 'byte_count' limits the number of bytes in the dump. + Note that this parameter is ignored when lxml is compiled against a libxml2 + version before 2.7.0. + """ + cdef Py_ssize_t c_count + if output_file is None: + output_file = b'.memorylist' + elif isinstance(output_file, unicode): + output_file.encode(sys.getfilesystemencoding()) + + f = stdio.fopen(output_file, "w") + if f is NULL: + raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}") + try: + if byte_count is None: + tree.xmlMemDisplay(f) + else: + c_count = byte_count + tree.xmlMemDisplayLast(f, c_count) + finally: + stdio.fclose(f) + + def show(self, output_file=None, block_count=None): + """show(self, output_file=None, block_count=None) + + Dumps the current memory blocks allocated by libxml2 to a file. + The output file format is suitable for line diffing. + + The optional parameter 'output_file' specifies the file path. It defaults + to the file ".memorydump" in the current directory. + + The optional parameter 'block_count' limits the number of blocks + in the dump. + """ + if output_file is None: + output_file = b'.memorydump' + elif isinstance(output_file, unicode): + output_file.encode(sys.getfilesystemencoding()) + + f = stdio.fopen(output_file, "w") + if f is NULL: + raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}") + try: + tree.xmlMemShow(f, block_count if block_count is not None else tree.xmlMemBlocks()) + finally: + stdio.fclose(f) + +memory_debugger = _MemDebug() diff --git a/.venv/lib/python3.7/site-packages/lxml/docloader.pxi b/.venv/lib/python3.7/site-packages/lxml/docloader.pxi new file mode 100644 index 0000000..83ad612 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/docloader.pxi @@ -0,0 +1,178 @@ +# Custom resolver API + +ctypedef enum _InputDocumentDataType: + PARSER_DATA_INVALID + PARSER_DATA_EMPTY + PARSER_DATA_STRING + PARSER_DATA_FILENAME + PARSER_DATA_FILE + +@cython.final +@cython.internal +cdef class _InputDocument: + cdef _InputDocumentDataType _type + cdef bytes _data_bytes + cdef object _filename + cdef object _file + cdef bint _close_file + + def __cinit__(self): + self._type = PARSER_DATA_INVALID + + +cdef class Resolver: + u"This is the base class of all resolvers." + def resolve(self, system_url, public_id, context): + u"""resolve(self, system_url, public_id, context) + + Override this method to resolve an external source by + ``system_url`` and ``public_id``. The third argument is an + opaque context object. + + Return the result of one of the ``resolve_*()`` methods. + """ + return None + + def resolve_empty(self, context): + u"""resolve_empty(self, context) + + Return an empty input document. + + Pass context as parameter. + """ + cdef _InputDocument doc_ref + doc_ref = _InputDocument() + doc_ref._type = PARSER_DATA_EMPTY + return doc_ref + + def resolve_string(self, string, context, *, base_url=None): + u"""resolve_string(self, string, context, base_url=None) + + Return a parsable string as input document. + + Pass data string and context as parameters. You can pass the + source URL or filename through the ``base_url`` keyword + argument. + """ + cdef _InputDocument doc_ref + if isinstance(string, unicode): + string = (string).encode('utf8') + elif not isinstance(string, bytes): + raise TypeError, "argument must be a byte string or unicode string" + doc_ref = _InputDocument() + doc_ref._type = PARSER_DATA_STRING + doc_ref._data_bytes = string + if base_url is not None: + doc_ref._filename = _encodeFilename(base_url) + return doc_ref + + def resolve_filename(self, filename, context): + u"""resolve_filename(self, filename, context) + + Return the name of a parsable file as input document. + + Pass filename and context as parameters. You can also pass a + URL with an HTTP, FTP or file target. + """ + cdef _InputDocument doc_ref + doc_ref = _InputDocument() + doc_ref._type = PARSER_DATA_FILENAME + doc_ref._filename = _encodeFilename(filename) + return doc_ref + + def resolve_file(self, f, context, *, base_url=None, bint close=True): + u"""resolve_file(self, f, context, base_url=None, close=True) + + Return an open file-like object as input document. + + Pass open file and context as parameters. You can pass the + base URL or filename of the file through the ``base_url`` + keyword argument. If the ``close`` flag is True (the + default), the file will be closed after reading. + + Note that using ``.resolve_filename()`` is more efficient, + especially in threaded environments. + """ + cdef _InputDocument doc_ref + try: + f.read + except AttributeError: + raise TypeError, u"Argument is not a file-like object" + doc_ref = _InputDocument() + doc_ref._type = PARSER_DATA_FILE + if base_url is not None: + doc_ref._filename = _encodeFilename(base_url) + else: + doc_ref._filename = _getFilenameForFile(f) + doc_ref._close_file = close + doc_ref._file = f + return doc_ref + +@cython.final +@cython.internal +cdef class _ResolverRegistry: + cdef object _resolvers + cdef Resolver _default_resolver + def __cinit__(self, Resolver default_resolver=None): + self._resolvers = set() + self._default_resolver = default_resolver + + def add(self, Resolver resolver not None): + u"""add(self, resolver) + + Register a resolver. + + For each requested entity, the 'resolve' method of the resolver will + be called and the result will be passed to the parser. If this method + returns None, the request will be delegated to other resolvers or the + default resolver. The resolvers will be tested in an arbitrary order + until the first match is found. + """ + self._resolvers.add(resolver) + + def remove(self, resolver): + u"remove(self, resolver)" + self._resolvers.discard(resolver) + + cdef _ResolverRegistry _copy(self): + cdef _ResolverRegistry registry + registry = _ResolverRegistry(self._default_resolver) + registry._resolvers = self._resolvers.copy() + return registry + + def copy(self): + u"copy(self)" + return self._copy() + + def resolve(self, system_url, public_id, context): + u"resolve(self, system_url, public_id, context)" + for resolver in self._resolvers: + result = resolver.resolve(system_url, public_id, context) + if result is not None: + return result + if self._default_resolver is None: + return None + return self._default_resolver.resolve(system_url, public_id, context) + + def __repr__(self): + return repr(self._resolvers) + + +@cython.internal +cdef class _ResolverContext(_ExceptionContext): + cdef _ResolverRegistry _resolvers + cdef _TempStore _storage + + cdef int clear(self) except -1: + _ExceptionContext.clear(self) + self._storage.clear() + return 0 + + +cdef _initResolverContext(_ResolverContext context, + _ResolverRegistry resolvers): + if resolvers is None: + context._resolvers = _ResolverRegistry() + else: + context._resolvers = resolvers + context._storage = _TempStore() diff --git a/.venv/lib/python3.7/site-packages/lxml/doctestcompare.py b/.venv/lib/python3.7/site-packages/lxml/doctestcompare.py new file mode 100644 index 0000000..1b0daa4 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/doctestcompare.py @@ -0,0 +1,507 @@ +""" +lxml-based doctest output comparison. + +Note: normally, you should just import the `lxml.usedoctest` and +`lxml.html.usedoctest` modules from within a doctest, instead of this +one:: + + >>> import lxml.usedoctest # for XML output + + >>> import lxml.html.usedoctest # for HTML output + +To use this module directly, you must call ``lxmldoctest.install()``, +which will cause doctest to use this in all subsequent calls. + +This changes the way output is checked and comparisons are made for +XML or HTML-like content. + +XML or HTML content is noticed because the example starts with ``<`` +(it's HTML if it starts with ```` or include an ``any`` +attribute in the tag. An ``any`` tag matches any tag, while the +attribute matches any and all attributes. + +When a match fails, the reformatted example and gotten text is +displayed (indented), and a rough diff-like output is given. Anything +marked with ``+`` is in the output but wasn't supposed to be, and +similarly ``-`` means its in the example but wasn't in the output. + +You can disable parsing on one line with ``# doctest:+NOPARSE_MARKUP`` +""" + +from lxml import etree +import sys +import re +import doctest +try: + from html import escape as html_escape +except ImportError: + from cgi import escape as html_escape + +__all__ = ['PARSE_HTML', 'PARSE_XML', 'NOPARSE_MARKUP', 'LXMLOutputChecker', + 'LHTMLOutputChecker', 'install', 'temp_install'] + +try: + _basestring = basestring +except NameError: + _basestring = (str, bytes) + +_IS_PYTHON_3 = sys.version_info[0] >= 3 + +PARSE_HTML = doctest.register_optionflag('PARSE_HTML') +PARSE_XML = doctest.register_optionflag('PARSE_XML') +NOPARSE_MARKUP = doctest.register_optionflag('NOPARSE_MARKUP') + +OutputChecker = doctest.OutputChecker + +def strip(v): + if v is None: + return None + else: + return v.strip() + +def norm_whitespace(v): + return _norm_whitespace_re.sub(' ', v) + +_html_parser = etree.HTMLParser(recover=False, remove_blank_text=True) + +def html_fromstring(html): + return etree.fromstring(html, _html_parser) + +# We use this to distinguish repr()s from elements: +_repr_re = re.compile(r'^<[^>]+ (at|object) ') +_norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+') + +class LXMLOutputChecker(OutputChecker): + + empty_tags = ( + 'param', 'img', 'area', 'br', 'basefont', 'input', + 'base', 'meta', 'link', 'col') + + def get_default_parser(self): + return etree.XML + + def check_output(self, want, got, optionflags): + alt_self = getattr(self, '_temp_override_self', None) + if alt_self is not None: + super_method = self._temp_call_super_check_output + self = alt_self + else: + super_method = OutputChecker.check_output + parser = self.get_parser(want, got, optionflags) + if not parser: + return super_method( + self, want, got, optionflags) + try: + want_doc = parser(want) + except etree.XMLSyntaxError: + return False + try: + got_doc = parser(got) + except etree.XMLSyntaxError: + return False + return self.compare_docs(want_doc, got_doc) + + def get_parser(self, want, got, optionflags): + parser = None + if NOPARSE_MARKUP & optionflags: + return None + if PARSE_HTML & optionflags: + parser = html_fromstring + elif PARSE_XML & optionflags: + parser = etree.XML + elif (want.strip().lower().startswith('' % el.tag + return '<%s %s>' % (el.tag, ' '.join(attrs)) + + def format_end_tag(self, el): + if isinstance(el, etree.CommentBase): + # FIXME: probably PIs should be handled specially too? + return '-->' + return '' % el.tag + + def collect_diff(self, want, got, html, indent): + parts = [] + if not len(want) and not len(got): + parts.append(' '*indent) + parts.append(self.collect_diff_tag(want, got)) + if not self.html_empty_tag(got, html): + parts.append(self.collect_diff_text(want.text, got.text)) + parts.append(self.collect_diff_end_tag(want, got)) + parts.append(self.collect_diff_text(want.tail, got.tail)) + parts.append('\n') + return ''.join(parts) + parts.append(' '*indent) + parts.append(self.collect_diff_tag(want, got)) + parts.append('\n') + if strip(want.text) or strip(got.text): + parts.append(' '*indent) + parts.append(self.collect_diff_text(want.text, got.text)) + parts.append('\n') + want_children = list(want) + got_children = list(got) + while want_children or got_children: + if not want_children: + parts.append(self.format_doc(got_children.pop(0), html, indent+2, '+')) + continue + if not got_children: + parts.append(self.format_doc(want_children.pop(0), html, indent+2, '-')) + continue + parts.append(self.collect_diff( + want_children.pop(0), got_children.pop(0), html, indent+2)) + parts.append(' '*indent) + parts.append(self.collect_diff_end_tag(want, got)) + parts.append('\n') + if strip(want.tail) or strip(got.tail): + parts.append(' '*indent) + parts.append(self.collect_diff_text(want.tail, got.tail)) + parts.append('\n') + return ''.join(parts) + + def collect_diff_tag(self, want, got): + if not self.tag_compare(want.tag, got.tag): + tag = '%s (got: %s)' % (want.tag, got.tag) + else: + tag = got.tag + attrs = [] + any = want.tag == 'any' or 'any' in want.attrib + for name, value in sorted(got.attrib.items()): + if name not in want.attrib and not any: + attrs.append('+%s="%s"' % (name, self.format_text(value, False))) + else: + if name in want.attrib: + text = self.collect_diff_text(want.attrib[name], value, False) + else: + text = self.format_text(value, False) + attrs.append('%s="%s"' % (name, text)) + if not any: + for name, value in sorted(want.attrib.items()): + if name in got.attrib: + continue + attrs.append('-%s="%s"' % (name, self.format_text(value, False))) + if attrs: + tag = '<%s %s>' % (tag, ' '.join(attrs)) + else: + tag = '<%s>' % tag + return tag + + def collect_diff_end_tag(self, want, got): + if want.tag != got.tag: + tag = '%s (got: %s)' % (want.tag, got.tag) + else: + tag = got.tag + return '' % tag + + def collect_diff_text(self, want, got, strip=True): + if self.text_compare(want, got, strip): + if not got: + return '' + return self.format_text(got, strip) + text = '%s (got: %s)' % (want, got) + return self.format_text(text, strip) + +class LHTMLOutputChecker(LXMLOutputChecker): + def get_default_parser(self): + return html_fromstring + +def install(html=False): + """ + Install doctestcompare for all future doctests. + + If html is true, then by default the HTML parser will be used; + otherwise the XML parser is used. + """ + if html: + doctest.OutputChecker = LHTMLOutputChecker + else: + doctest.OutputChecker = LXMLOutputChecker + +def temp_install(html=False, del_module=None): + """ + Use this *inside* a doctest to enable this checker for this + doctest only. + + If html is true, then by default the HTML parser will be used; + otherwise the XML parser is used. + """ + if html: + Checker = LHTMLOutputChecker + else: + Checker = LXMLOutputChecker + frame = _find_doctest_frame() + dt_self = frame.f_locals['self'] + checker = Checker() + old_checker = dt_self._checker + dt_self._checker = checker + # The unfortunate thing is that there is a local variable 'check' + # in the function that runs the doctests, that is a bound method + # into the output checker. We have to update that. We can't + # modify the frame, so we have to modify the object in place. The + # only way to do this is to actually change the func_code + # attribute of the method. We change it, and then wait for + # __record_outcome to be run, which signals the end of the __run + # method, at which point we restore the previous check_output + # implementation. + if _IS_PYTHON_3: + check_func = frame.f_locals['check'].__func__ + checker_check_func = checker.check_output.__func__ + else: + check_func = frame.f_locals['check'].im_func + checker_check_func = checker.check_output.im_func + # Because we can't patch up func_globals, this is the only global + # in check_output that we care about: + doctest.etree = etree + _RestoreChecker(dt_self, old_checker, checker, + check_func, checker_check_func, + del_module) + +class _RestoreChecker(object): + def __init__(self, dt_self, old_checker, new_checker, check_func, clone_func, + del_module): + self.dt_self = dt_self + self.checker = old_checker + self.checker._temp_call_super_check_output = self.call_super + self.checker._temp_override_self = new_checker + self.check_func = check_func + self.clone_func = clone_func + self.del_module = del_module + self.install_clone() + self.install_dt_self() + def install_clone(self): + if _IS_PYTHON_3: + self.func_code = self.check_func.__code__ + self.func_globals = self.check_func.__globals__ + self.check_func.__code__ = self.clone_func.__code__ + else: + self.func_code = self.check_func.func_code + self.func_globals = self.check_func.func_globals + self.check_func.func_code = self.clone_func.func_code + def uninstall_clone(self): + if _IS_PYTHON_3: + self.check_func.__code__ = self.func_code + else: + self.check_func.func_code = self.func_code + def install_dt_self(self): + self.prev_func = self.dt_self._DocTestRunner__record_outcome + self.dt_self._DocTestRunner__record_outcome = self + def uninstall_dt_self(self): + self.dt_self._DocTestRunner__record_outcome = self.prev_func + def uninstall_module(self): + if self.del_module: + import sys + del sys.modules[self.del_module] + if '.' in self.del_module: + package, module = self.del_module.rsplit('.', 1) + package_mod = sys.modules[package] + delattr(package_mod, module) + def __call__(self, *args, **kw): + self.uninstall_clone() + self.uninstall_dt_self() + del self.checker._temp_override_self + del self.checker._temp_call_super_check_output + result = self.prev_func(*args, **kw) + self.uninstall_module() + return result + def call_super(self, *args, **kw): + self.uninstall_clone() + try: + return self.check_func(*args, **kw) + finally: + self.install_clone() + +def _find_doctest_frame(): + import sys + frame = sys._getframe(1) + while frame: + l = frame.f_locals + if 'BOOM' in l: + # Sign of doctest + return frame + frame = frame.f_back + raise LookupError( + "Could not find doctest (only use this function *inside* a doctest)") + +__test__ = { + 'basic': ''' + >>> temp_install() + >>> print """stuff""" + ... + >>> print """""" + + + + >>> print """blahblahblah""" # doctest: +NOPARSE_MARKUP, +ELLIPSIS + ...foo /> + '''} + +if __name__ == '__main__': + import doctest + doctest.testmod() + + diff --git a/.venv/lib/python3.7/site-packages/lxml/dtd.pxi b/.venv/lib/python3.7/site-packages/lxml/dtd.pxi new file mode 100644 index 0000000..17242fb --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/dtd.pxi @@ -0,0 +1,478 @@ +# support for DTD validation +from lxml.includes cimport dtdvalid + +cdef class DTDError(LxmlError): + """Base class for DTD errors. + """ + +cdef class DTDParseError(DTDError): + """Error while parsing a DTD. + """ + +cdef class DTDValidateError(DTDError): + """Error while validating an XML document with a DTD. + """ + + +cdef inline int _assertValidDTDNode(node, void *c_node) except -1: + assert c_node is not NULL, u"invalid DTD proxy at %s" % id(node) + + +@cython.final +@cython.internal +@cython.freelist(8) +cdef class _DTDElementContentDecl: + cdef DTD _dtd + cdef tree.xmlElementContent* _c_node + + def __repr__(self): + return "<%s.%s object name=%r type=%r occur=%r at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, self.type, self.occur, id(self)) + + @property + def name(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.name) + + @property + def type(self): + _assertValidDTDNode(self, self._c_node) + cdef int type = self._c_node.type + if type == tree.XML_ELEMENT_CONTENT_PCDATA: + return "pcdata" + elif type == tree.XML_ELEMENT_CONTENT_ELEMENT: + return "element" + elif type == tree.XML_ELEMENT_CONTENT_SEQ: + return "seq" + elif type == tree.XML_ELEMENT_CONTENT_OR: + return "or" + else: + return None + + @property + def occur(self): + _assertValidDTDNode(self, self._c_node) + cdef int occur = self._c_node.ocur + if occur == tree.XML_ELEMENT_CONTENT_ONCE: + return "once" + elif occur == tree.XML_ELEMENT_CONTENT_OPT: + return "opt" + elif occur == tree.XML_ELEMENT_CONTENT_MULT: + return "mult" + elif occur == tree.XML_ELEMENT_CONTENT_PLUS: + return "plus" + else: + return None + + @property + def left(self): + _assertValidDTDNode(self, self._c_node) + c1 = self._c_node.c1 + if c1: + node = <_DTDElementContentDecl>_DTDElementContentDecl.__new__(_DTDElementContentDecl) + node._dtd = self._dtd + node._c_node = c1 + return node + else: + return None + + @property + def right(self): + _assertValidDTDNode(self, self._c_node) + c2 = self._c_node.c2 + if c2: + node = <_DTDElementContentDecl>_DTDElementContentDecl.__new__(_DTDElementContentDecl) + node._dtd = self._dtd + node._c_node = c2 + return node + else: + return None + + +@cython.final +@cython.internal +@cython.freelist(8) +cdef class _DTDAttributeDecl: + cdef DTD _dtd + cdef tree.xmlAttribute* _c_node + + def __repr__(self): + return "<%s.%s object name=%r elemname=%r prefix=%r type=%r default=%r default_value=%r at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, self.elemname, self.prefix, self.type, self.default, self.default_value, id(self)) + + @property + def name(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.name) + + @property + def elemname(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.elem) + + @property + def prefix(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.prefix) + + @property + def type(self): + _assertValidDTDNode(self, self._c_node) + cdef int type = self._c_node.atype + if type == tree.XML_ATTRIBUTE_CDATA: + return "cdata" + elif type == tree.XML_ATTRIBUTE_ID: + return "id" + elif type == tree.XML_ATTRIBUTE_IDREF: + return "idref" + elif type == tree.XML_ATTRIBUTE_IDREFS: + return "idrefs" + elif type == tree.XML_ATTRIBUTE_ENTITY: + return "entity" + elif type == tree.XML_ATTRIBUTE_ENTITIES: + return "entities" + elif type == tree.XML_ATTRIBUTE_NMTOKEN: + return "nmtoken" + elif type == tree.XML_ATTRIBUTE_NMTOKENS: + return "nmtokens" + elif type == tree.XML_ATTRIBUTE_ENUMERATION: + return "enumeration" + elif type == tree.XML_ATTRIBUTE_NOTATION: + return "notation" + else: + return None + + @property + def default(self): + _assertValidDTDNode(self, self._c_node) + cdef int default = self._c_node.def_ + if default == tree.XML_ATTRIBUTE_NONE: + return "none" + elif default == tree.XML_ATTRIBUTE_REQUIRED: + return "required" + elif default == tree.XML_ATTRIBUTE_IMPLIED: + return "implied" + elif default == tree.XML_ATTRIBUTE_FIXED: + return "fixed" + else: + return None + + @property + def default_value(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.defaultValue) + + def itervalues(self): + _assertValidDTDNode(self, self._c_node) + cdef tree.xmlEnumeration *c_node = self._c_node.tree + while c_node is not NULL: + yield funicode(c_node.name) + c_node = c_node.next + + def values(self): + return list(self.itervalues()) + + +@cython.final +@cython.internal +@cython.freelist(8) +cdef class _DTDElementDecl: + cdef DTD _dtd + cdef tree.xmlElement* _c_node + + def __repr__(self): + return "<%s.%s object name=%r prefix=%r type=%r at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, self.prefix, self.type, id(self)) + + @property + def name(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.name) + + @property + def prefix(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.prefix) + + @property + def type(self): + _assertValidDTDNode(self, self._c_node) + cdef int type = self._c_node.etype + if type == tree.XML_ELEMENT_TYPE_UNDEFINED: + return "undefined" + elif type == tree.XML_ELEMENT_TYPE_EMPTY: + return "empty" + elif type == tree.XML_ELEMENT_TYPE_ANY: + return "any" + elif type == tree.XML_ELEMENT_TYPE_MIXED: + return "mixed" + elif type == tree.XML_ELEMENT_TYPE_ELEMENT: + return "element" + else: + return None + + @property + def content(self): + _assertValidDTDNode(self, self._c_node) + cdef tree.xmlElementContent *content = self._c_node.content + if content: + node = <_DTDElementContentDecl>_DTDElementContentDecl.__new__(_DTDElementContentDecl) + node._dtd = self._dtd + node._c_node = content + return node + else: + return None + + def iterattributes(self): + _assertValidDTDNode(self, self._c_node) + cdef tree.xmlAttribute *c_node = self._c_node.attributes + while c_node: + node = <_DTDAttributeDecl>_DTDAttributeDecl.__new__(_DTDAttributeDecl) + node._dtd = self._dtd + node._c_node = c_node + yield node + c_node = c_node.nexth + + def attributes(self): + return list(self.iterattributes()) + + +@cython.final +@cython.internal +@cython.freelist(8) +cdef class _DTDEntityDecl: + cdef DTD _dtd + cdef tree.xmlEntity* _c_node + def __repr__(self): + return "<%s.%s object name=%r at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, id(self)) + + @property + def name(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.name) + + @property + def orig(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.orig) + + @property + def content(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.content) + + @property + def system_url(self): + _assertValidDTDNode(self, self._c_node) + return funicodeOrNone(self._c_node.SystemID) + + +################################################################################ +# DTD + +cdef class DTD(_Validator): + u"""DTD(self, file=None, external_id=None) + A DTD validator. + + Can load from filesystem directly given a filename or file-like object. + Alternatively, pass the keyword parameter ``external_id`` to load from a + catalog. + """ + cdef tree.xmlDtd* _c_dtd + def __init__(self, file=None, *, external_id=None): + _Validator.__init__(self) + if file is not None: + file = _getFSPathOrObject(file) + if _isString(file): + file = _encodeFilename(file) + with self._error_log: + orig_loader = _register_document_loader() + self._c_dtd = xmlparser.xmlParseDTD(NULL, _xcstr(file)) + _reset_document_loader(orig_loader) + elif hasattr(file, 'read'): + orig_loader = _register_document_loader() + self._c_dtd = _parseDtdFromFilelike(file) + _reset_document_loader(orig_loader) + else: + raise DTDParseError, u"file must be a filename, file-like or path-like object" + elif external_id is not None: + with self._error_log: + orig_loader = _register_document_loader() + self._c_dtd = xmlparser.xmlParseDTD(external_id, NULL) + _reset_document_loader(orig_loader) + else: + raise DTDParseError, u"either filename or external ID required" + + if self._c_dtd is NULL: + raise DTDParseError( + self._error_log._buildExceptionMessage(u"error parsing DTD"), + self._error_log) + + @property + def name(self): + if self._c_dtd is NULL: + return None + return funicodeOrNone(self._c_dtd.name) + + @property + def external_id(self): + if self._c_dtd is NULL: + return None + return funicodeOrNone(self._c_dtd.ExternalID) + + @property + def system_url(self): + if self._c_dtd is NULL: + return None + return funicodeOrNone(self._c_dtd.SystemID) + + def iterelements(self): + cdef tree.xmlNode *c_node = self._c_dtd.children if self._c_dtd is not NULL else NULL + while c_node is not NULL: + if c_node.type == tree.XML_ELEMENT_DECL: + node = _DTDElementDecl() + node._dtd = self + node._c_node = c_node + yield node + c_node = c_node.next + + def elements(self): + return list(self.iterelements()) + + def iterentities(self): + cdef tree.xmlNode *c_node = self._c_dtd.children if self._c_dtd is not NULL else NULL + while c_node is not NULL: + if c_node.type == tree.XML_ENTITY_DECL: + node = _DTDEntityDecl() + node._dtd = self + node._c_node = c_node + yield node + c_node = c_node.next + + def entities(self): + return list(self.iterentities()) + + def __dealloc__(self): + tree.xmlFreeDtd(self._c_dtd) + + def __call__(self, etree): + u"""__call__(self, etree) + + Validate doc using the DTD. + + Returns true if the document is valid, false if not. + """ + cdef _Document doc + cdef _Element root_node + cdef xmlDoc* c_doc + cdef dtdvalid.xmlValidCtxt* valid_ctxt + cdef int ret = -1 + + assert self._c_dtd is not NULL, "DTD not initialised" + doc = _documentOrRaise(etree) + root_node = _rootNodeOrRaise(etree) + + valid_ctxt = dtdvalid.xmlNewValidCtxt() + if valid_ctxt is NULL: + raise DTDError(u"Failed to create validation context") + + # work around error reporting bug in libxml2 <= 2.9.1 (and later?) + # https://bugzilla.gnome.org/show_bug.cgi?id=724903 + valid_ctxt.error = _nullGenericErrorFunc + valid_ctxt.userData = NULL + + try: + with self._error_log: + c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node) + ret = dtdvalid.xmlValidateDtd(valid_ctxt, c_doc, self._c_dtd) + _destroyFakeDoc(doc._c_doc, c_doc) + finally: + dtdvalid.xmlFreeValidCtxt(valid_ctxt) + + if ret == -1: + raise DTDValidateError(u"Internal error in DTD validation", + self._error_log) + return ret == 1 + + +cdef tree.xmlDtd* _parseDtdFromFilelike(file) except NULL: + cdef _ExceptionContext exc_context + cdef _FileReaderContext dtd_parser + cdef _ErrorLog error_log + cdef tree.xmlDtd* c_dtd = NULL + exc_context = _ExceptionContext() + dtd_parser = _FileReaderContext(file, exc_context, None) + error_log = _ErrorLog() + + with error_log: + c_dtd = dtd_parser._readDtd() + + exc_context._raise_if_stored() + if c_dtd is NULL: + raise DTDParseError(u"error parsing DTD", error_log) + return c_dtd + +cdef DTD _dtdFactory(tree.xmlDtd* c_dtd): + # do not run through DTD.__init__()! + cdef DTD dtd + if c_dtd is NULL: + return None + dtd = DTD.__new__(DTD) + dtd._c_dtd = _copyDtd(c_dtd) + _Validator.__init__(dtd) + return dtd + + +cdef tree.xmlDtd* _copyDtd(tree.xmlDtd* c_orig_dtd) except NULL: + """ + Copy a DTD. libxml2 (currently) fails to set up the element->attributes + links when copying DTDs, so we have to rebuild them here. + """ + c_dtd = tree.xmlCopyDtd(c_orig_dtd) + if not c_dtd: + raise MemoryError + cdef tree.xmlNode* c_node = c_dtd.children + while c_node: + if c_node.type == tree.XML_ATTRIBUTE_DECL: + _linkDtdAttribute(c_dtd, c_node) + c_node = c_node.next + return c_dtd + + +cdef void _linkDtdAttribute(tree.xmlDtd* c_dtd, tree.xmlAttribute* c_attr): + """ + Create the link to the DTD attribute declaration from the corresponding + element declaration. + """ + c_elem = dtdvalid.xmlGetDtdElementDesc(c_dtd, c_attr.elem) + if not c_elem: + # no such element? something is wrong with the DTD ... + return + c_pos = c_elem.attributes + if not c_pos: + c_elem.attributes = c_attr + c_attr.nexth = NULL + return + # libxml2 keeps namespace declarations first, and we need to make + # sure we don't re-insert attributes that are already there + if _isDtdNsDecl(c_attr): + if not _isDtdNsDecl(c_pos): + c_elem.attributes = c_attr + c_attr.nexth = c_pos + return + while c_pos != c_attr and c_pos.nexth and _isDtdNsDecl(c_pos.nexth): + c_pos = c_pos.nexth + else: + # append at end + while c_pos != c_attr and c_pos.nexth: + c_pos = c_pos.nexth + if c_pos == c_attr: + return + c_attr.nexth = c_pos.nexth + c_pos.nexth = c_attr + + +cdef bint _isDtdNsDecl(tree.xmlAttribute* c_attr): + if cstring_h.strcmp(c_attr.name, "xmlns") == 0: + return True + if (c_attr.prefix is not NULL and + cstring_h.strcmp(c_attr.prefix, "xmlns") == 0): + return True + return False diff --git a/.venv/lib/python3.7/site-packages/lxml/etree.cpython-37m-arm-linux-gnueabihf.so b/.venv/lib/python3.7/site-packages/lxml/etree.cpython-37m-arm-linux-gnueabihf.so new file mode 100755 index 0000000000000000000000000000000000000000..e2656333c7b41a5ca0c4b9ddd7e6e7ca3cf6c09e GIT binary patch literal 3840660 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฾GlNj$hzLm_Rb2+reNRC##reeHH+sK=W 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 z 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%0Dp|XITlX$-r$`s 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ͺEmvVLcC{l?PnKnfVu|=j$$HP+_K|xm^ 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 z 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ⅆW1F=WB$ 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

    h$-42UD7ND_-jW#%oEZHQwa+oKd*Szm|` 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 z9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e z!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*D zEDu@%%Y#=qSRO17S^>+0 zR>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*L zHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{ z!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmor ztUp*DEDu@%%Y#=qSRO17 zS^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix z6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-9 z0n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLL zusmortUp*DEDu@%%Y#=q zSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@% z%Y#=qSRO17S^>+0R>S&( z<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a z9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e z!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*D zEDu@%%Y#=qSRO17S^>+0 zR>S&(<-zix6|g*LHLO2a9xM-90n39{!}^2e!SbLLusmortUp*DEDu@%%Y#=qSRO17S^>+0R>S&(<-zix6|g*L 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%0AK{JKsNufy{PBCAJ9L@b-{g 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 TP`3ML|Ma&tree.xmlParserVersion).decode("ascii")).group(0)) +except Exception: + print u"Unknown libxml2 version: %s" % (tree.xmlParserVersion).decode("latin1") + _LIBXML_VERSION_INT = 0 + +LIBXML_VERSION = __unpackIntVersion(_LIBXML_VERSION_INT) +LIBXML_COMPILED_VERSION = __unpackIntVersion(tree.LIBXML_VERSION) +LXML_VERSION = __unpackDottedVersion(tree.LXML_VERSION_STRING) + +__version__ = tree.LXML_VERSION_STRING.decode("ascii") + + +# class for temporary storage of Python references, +# used e.g. for XPath results +@cython.final +@cython.internal +cdef class _TempStore: + cdef list _storage + def __init__(self): + self._storage = [] + + cdef int add(self, obj) except -1: + self._storage.append(obj) + return 0 + + cdef int clear(self) except -1: + del self._storage[:] + return 0 + + +# class for temporarily storing exceptions raised in extensions +@cython.internal +cdef class _ExceptionContext: + cdef object _exc_info + cdef int clear(self) except -1: + self._exc_info = None + return 0 + + cdef void _store_raised(self): + try: + self._exc_info = sys.exc_info() + except BaseException as e: + self._store_exception(e) + finally: + return # and swallow any further exceptions + + cdef int _store_exception(self, exception) except -1: + self._exc_info = (exception, None, None) + return 0 + + cdef bint _has_raised(self) except -1: + return self._exc_info is not None + + cdef int _raise_if_stored(self) except -1: + if self._exc_info is None: + return 0 + type, value, traceback = self._exc_info + self._exc_info = None + if value is None and traceback is None: + raise type + else: + raise type, value, traceback + + +# type of a function that steps from node to node +ctypedef public xmlNode* (*_node_to_node_function)(xmlNode*) + + +################################################################################ +# Include submodules + +include "proxy.pxi" # Proxy handling (element backpointers/memory/etc.) +include "apihelpers.pxi" # Private helper functions +include "xmlerror.pxi" # Error and log handling + + +################################################################################ +# Public Python API + +@cython.final +@cython.freelist(8) +cdef public class _Document [ type LxmlDocumentType, object LxmlDocument ]: + u"""Internal base class to reference a libxml document. + + When instances of this class are garbage collected, the libxml + document is cleaned up. + """ + cdef int _ns_counter + cdef bytes _prefix_tail + cdef xmlDoc* _c_doc + cdef _BaseParser _parser + + def __dealloc__(self): + # if there are no more references to the document, it is safe + # to clean the whole thing up, as all nodes have a reference to + # the document + tree.xmlFreeDoc(self._c_doc) + + @cython.final + cdef getroot(self): + # return an element proxy for the document root + cdef xmlNode* c_node + c_node = tree.xmlDocGetRootElement(self._c_doc) + if c_node is NULL: + return None + return _elementFactory(self, c_node) + + @cython.final + cdef bint hasdoctype(self): + # DOCTYPE gets parsed into internal subset (xmlDTD*) + return self._c_doc is not NULL and self._c_doc.intSubset is not NULL + + @cython.final + cdef getdoctype(self): + # get doctype info: root tag, public/system ID (or None if not known) + cdef tree.xmlDtd* c_dtd + cdef xmlNode* c_root_node + public_id = None + sys_url = None + c_dtd = self._c_doc.intSubset + if c_dtd is not NULL: + if c_dtd.ExternalID is not NULL: + public_id = funicode(c_dtd.ExternalID) + if c_dtd.SystemID is not NULL: + sys_url = funicode(c_dtd.SystemID) + c_dtd = self._c_doc.extSubset + if c_dtd is not NULL: + if not public_id and c_dtd.ExternalID is not NULL: + public_id = funicode(c_dtd.ExternalID) + if not sys_url and c_dtd.SystemID is not NULL: + sys_url = funicode(c_dtd.SystemID) + c_root_node = tree.xmlDocGetRootElement(self._c_doc) + if c_root_node is NULL: + root_name = None + else: + root_name = funicode(c_root_node.name) + return root_name, public_id, sys_url + + @cython.final + cdef getxmlinfo(self): + # return XML version and encoding (or None if not known) + cdef xmlDoc* c_doc = self._c_doc + if c_doc.version is NULL: + version = None + else: + version = funicode(c_doc.version) + if c_doc.encoding is NULL: + encoding = None + else: + encoding = funicode(c_doc.encoding) + return version, encoding + + @cython.final + cdef isstandalone(self): + # returns True for "standalone=true", + # False for "standalone=false", None if not provided + if self._c_doc.standalone == -1: + return None + else: + return (self._c_doc.standalone == 1) + + @cython.final + cdef bytes buildNewPrefix(self): + # get a new unique prefix ("nsX") for this document + cdef bytes ns + if self._ns_counter < len(_PREFIX_CACHE): + ns = _PREFIX_CACHE[self._ns_counter] + else: + ns = python.PyBytes_FromFormat("ns%d", self._ns_counter) + if self._prefix_tail is not None: + ns += self._prefix_tail + self._ns_counter += 1 + if self._ns_counter < 0: + # overflow! + self._ns_counter = 0 + if self._prefix_tail is None: + self._prefix_tail = b"A" + else: + self._prefix_tail += b"A" + return ns + + @cython.final + cdef xmlNs* _findOrBuildNodeNs(self, xmlNode* c_node, + const_xmlChar* c_href, const_xmlChar* c_prefix, + bint is_attribute) except NULL: + u"""Get or create namespace structure for a node. Reuses the prefix if + possible. + """ + cdef xmlNs* c_ns + cdef xmlNs* c_doc_ns + cdef python.PyObject* dict_result + if c_node.type != tree.XML_ELEMENT_NODE: + assert c_node.type == tree.XML_ELEMENT_NODE, \ + u"invalid node type %d, expected %d" % ( + c_node.type, tree.XML_ELEMENT_NODE) + # look for existing ns declaration + c_ns = _searchNsByHref(c_node, c_href, is_attribute) + if c_ns is not NULL: + if is_attribute and c_ns.prefix is NULL: + # do not put namespaced attributes into the default + # namespace as this would break serialisation + pass + else: + return c_ns + + # none found => determine a suitable new prefix + if c_prefix is NULL: + dict_result = python.PyDict_GetItem( + _DEFAULT_NAMESPACE_PREFIXES, c_href) + if dict_result is not NULL: + prefix = dict_result + else: + prefix = self.buildNewPrefix() + c_prefix = _xcstr(prefix) + + # make sure the prefix is not in use already + while tree.xmlSearchNs(self._c_doc, c_node, c_prefix) is not NULL: + prefix = self.buildNewPrefix() + c_prefix = _xcstr(prefix) + + # declare the namespace and return it + c_ns = tree.xmlNewNs(c_node, c_href, c_prefix) + if c_ns is NULL: + raise MemoryError() + return c_ns + + @cython.final + cdef int _setNodeNs(self, xmlNode* c_node, const_xmlChar* c_href) except -1: + u"Lookup namespace structure and set it for the node." + c_ns = self._findOrBuildNodeNs(c_node, c_href, NULL, 0) + tree.xmlSetNs(c_node, c_ns) + +cdef tuple __initPrefixCache(): + cdef int i + return tuple([ python.PyBytes_FromFormat("ns%d", i) + for i in range(30) ]) + +cdef tuple _PREFIX_CACHE = __initPrefixCache() + +cdef _Document _documentFactory(xmlDoc* c_doc, _BaseParser parser): + cdef _Document result + result = _Document.__new__(_Document) + result._c_doc = c_doc + result._ns_counter = 0 + result._prefix_tail = None + if parser is None: + parser = __GLOBAL_PARSER_CONTEXT.getDefaultParser() + result._parser = parser + return result + + +cdef object _find_invalid_public_id_characters = re.compile( + ur"[^\x20\x0D\x0Aa-zA-Z0-9'()+,./:=?;!*#@$_%-]+").search + + +cdef class DocInfo: + u"Document information provided by parser and DTD." + cdef _Document _doc + def __cinit__(self, tree): + u"Create a DocInfo object for an ElementTree object or root Element." + self._doc = _documentOrRaise(tree) + root_name, public_id, system_url = self._doc.getdoctype() + if not root_name and (public_id or system_url): + raise ValueError, u"Could not find root node" + + @property + def root_name(self): + """Returns the name of the root node as defined by the DOCTYPE.""" + root_name, public_id, system_url = self._doc.getdoctype() + return root_name + + @cython.final + cdef tree.xmlDtd* _get_c_dtd(self): + """"Return the DTD. Create it if it does not yet exist.""" + cdef xmlDoc* c_doc = self._doc._c_doc + cdef xmlNode* c_root_node + cdef const_xmlChar* c_name + + if c_doc.intSubset: + return c_doc.intSubset + + c_root_node = tree.xmlDocGetRootElement(c_doc) + c_name = c_root_node.name if c_root_node else NULL + return tree.xmlCreateIntSubset(c_doc, c_name, NULL, NULL) + + def clear(self): + u"""Removes DOCTYPE and internal subset from the document.""" + cdef xmlDoc* c_doc = self._doc._c_doc + cdef tree.xmlNode* c_dtd = c_doc.intSubset + if c_dtd is NULL: + return + tree.xmlUnlinkNode(c_dtd) + tree.xmlFreeNode(c_dtd) + + property public_id: + u"""Public ID of the DOCTYPE. + + Mutable. May be set to a valid string or None. If a DTD does not + exist, setting this variable (even to None) will create one. + """ + def __get__(self): + root_name, public_id, system_url = self._doc.getdoctype() + return public_id + + def __set__(self, value): + cdef xmlChar* c_value = NULL + if value is not None: + match = _find_invalid_public_id_characters(value) + if match: + raise ValueError, f'Invalid character(s) {match.group(0)!r} in public_id.' + value = _utf8(value) + c_value = tree.xmlStrdup(_xcstr(value)) + if not c_value: + raise MemoryError() + + c_dtd = self._get_c_dtd() + if not c_dtd: + tree.xmlFree(c_value) + raise MemoryError() + if c_dtd.ExternalID: + tree.xmlFree(c_dtd.ExternalID) + c_dtd.ExternalID = c_value + + property system_url: + u"""System ID of the DOCTYPE. + + Mutable. May be set to a valid string or None. If a DTD does not + exist, setting this variable (even to None) will create one. + """ + def __get__(self): + root_name, public_id, system_url = self._doc.getdoctype() + return system_url + + def __set__(self, value): + cdef xmlChar* c_value = NULL + if value is not None: + bvalue = _utf8(value) + # sys_url may be any valid unicode string that can be + # enclosed in single quotes or quotes. + if b"'" in bvalue and b'"' in bvalue: + raise ValueError( + 'System URL may not contain both single (\') and double quotes (").') + c_value = tree.xmlStrdup(_xcstr(bvalue)) + if not c_value: + raise MemoryError() + + c_dtd = self._get_c_dtd() + if not c_dtd: + tree.xmlFree(c_value) + raise MemoryError() + if c_dtd.SystemID: + tree.xmlFree(c_dtd.SystemID) + c_dtd.SystemID = c_value + + @property + def xml_version(self): + """Returns the XML version as declared by the document.""" + xml_version, encoding = self._doc.getxmlinfo() + return xml_version + + @property + def encoding(self): + """Returns the encoding name as declared by the document.""" + xml_version, encoding = self._doc.getxmlinfo() + return encoding + + @property + def standalone(self): + """Returns the standalone flag as declared by the document. The possible + values are True (``standalone='yes'``), False + (``standalone='no'`` or flag not provided in the declaration), + and None (unknown or no declaration found). Note that a + normal truth test on this value will always tell if the + ``standalone`` flag was set to ``'yes'`` or not. + """ + return self._doc.isstandalone() + + property URL: + u"The source URL of the document (or None if unknown)." + def __get__(self): + if self._doc._c_doc.URL is NULL: + return None + return _decodeFilename(self._doc._c_doc.URL) + def __set__(self, url): + url = _encodeFilename(url) + c_oldurl = self._doc._c_doc.URL + if url is None: + self._doc._c_doc.URL = NULL + else: + self._doc._c_doc.URL = tree.xmlStrdup(_xcstr(url)) + if c_oldurl is not NULL: + tree.xmlFree(c_oldurl) + + @property + def doctype(self): + """Returns a DOCTYPE declaration string for the document.""" + root_name, public_id, system_url = self._doc.getdoctype() + if system_url: + # If '"' in system_url, we must escape it with single + # quotes, otherwise escape with double quotes. If url + # contains both a single quote and a double quote, XML + # standard is being violated. + if '"' in system_url: + quoted_system_url = f"'{system_url}'" + else: + quoted_system_url = f'"{system_url}"' + if public_id: + if system_url: + return f'' + else: + return f'' + elif system_url: + return f'' + elif self._doc.hasdoctype(): + return f'' + else: + return u'' + + @property + def internalDTD(self): + """Returns a DTD validator based on the internal subset of the document.""" + return _dtdFactory(self._doc._c_doc.intSubset) + + @property + def externalDTD(self): + """Returns a DTD validator based on the external subset of the document.""" + return _dtdFactory(self._doc._c_doc.extSubset) + + +@cython.no_gc_clear +cdef public class _Element [ type LxmlElementType, object LxmlElement ]: + u"""Element class. + + References a document object and a libxml node. + + By pointing to a Document instance, a reference is kept to + _Document as long as there is some pointer to a node in it. + """ + cdef _Document _doc + cdef xmlNode* _c_node + cdef object _tag + + def _init(self): + u"""_init(self) + + Called after object initialisation. Custom subclasses may override + this if they recursively call _init() in the superclasses. + """ + + @cython.linetrace(False) + @cython.profile(False) + def __dealloc__(self): + #print "trying to free node:", self._c_node + #displayNode(self._c_node, 0) + if self._c_node is not NULL: + _unregisterProxy(self) + attemptDeallocation(self._c_node) + + # MANIPULATORS + + def __setitem__(self, x, value): + u"""__setitem__(self, x, value) + + Replaces the given subelement index or slice. + """ + cdef xmlNode* c_node = NULL + cdef xmlNode* c_next + cdef xmlDoc* c_source_doc + cdef _Element element + cdef bint left_to_right + cdef Py_ssize_t slicelength = 0, step = 0 + _assertValidNode(self) + if value is None: + raise ValueError, u"cannot assign None" + if isinstance(x, slice): + # slice assignment + _findChildSlice(x, self._c_node, &c_node, &step, &slicelength) + if step > 0: + left_to_right = 1 + else: + left_to_right = 0 + step = -step + _replaceSlice(self, c_node, slicelength, step, left_to_right, value) + return + else: + # otherwise: normal item assignment + element = value + _assertValidNode(element) + c_node = _findChild(self._c_node, x) + if c_node is NULL: + raise IndexError, u"list index out of range" + c_source_doc = element._c_node.doc + c_next = element._c_node.next + _removeText(c_node.next) + tree.xmlReplaceNode(c_node, element._c_node) + _moveTail(c_next, element._c_node) + moveNodeToDocument(self._doc, c_source_doc, element._c_node) + if not attemptDeallocation(c_node): + moveNodeToDocument(self._doc, c_node.doc, c_node) + + def __delitem__(self, x): + u"""__delitem__(self, x) + + Deletes the given subelement or a slice. + """ + cdef xmlNode* c_node = NULL + cdef xmlNode* c_next + cdef Py_ssize_t step = 0, slicelength = 0 + _assertValidNode(self) + if isinstance(x, slice): + # slice deletion + if _isFullSlice(x): + c_node = self._c_node.children + if c_node is not NULL: + if not _isElement(c_node): + c_node = _nextElement(c_node) + while c_node is not NULL: + c_next = _nextElement(c_node) + _removeNode(self._doc, c_node) + c_node = c_next + else: + _findChildSlice(x, self._c_node, &c_node, &step, &slicelength) + _deleteSlice(self._doc, c_node, slicelength, step) + else: + # item deletion + c_node = _findChild(self._c_node, x) + if c_node is NULL: + raise IndexError, f"index out of range: {x}" + _removeNode(self._doc, c_node) + + def __deepcopy__(self, memo): + u"__deepcopy__(self, memo)" + return self.__copy__() + + def __copy__(self): + u"__copy__(self)" + cdef xmlDoc* c_doc + cdef xmlNode* c_node + cdef _Document new_doc + _assertValidNode(self) + c_doc = _copyDocRoot(self._doc._c_doc, self._c_node) # recursive + new_doc = _documentFactory(c_doc, self._doc._parser) + root = new_doc.getroot() + if root is not None: + return root + # Comment/PI + c_node = c_doc.children + while c_node is not NULL and c_node.type != self._c_node.type: + c_node = c_node.next + if c_node is NULL: + return None + return _elementFactory(new_doc, c_node) + + def set(self, key, value): + u"""set(self, key, value) + + Sets an element attribute. + In HTML documents (not XML or XHTML), the value None is allowed and creates + an attribute without value (just the attribute name). + """ + _assertValidNode(self) + _setAttributeValue(self, key, value) + + def append(self, _Element element not None): + u"""append(self, element) + + Adds a subelement to the end of this element. + """ + _assertValidNode(self) + _assertValidNode(element) + _appendChild(self, element) + + def addnext(self, _Element element not None): + u"""addnext(self, element) + + Adds the element as a following sibling directly after this + element. + + This is normally used to set a processing instruction or comment after + the root node of a document. Note that tail text is automatically + discarded when adding at the root level. + """ + _assertValidNode(self) + _assertValidNode(element) + if self._c_node.parent != NULL and not _isElement(self._c_node.parent): + if element._c_node.type != tree.XML_PI_NODE: + if element._c_node.type != tree.XML_COMMENT_NODE: + raise TypeError, u"Only processing instructions and comments can be siblings of the root element" + element.tail = None + _appendSibling(self, element) + + def addprevious(self, _Element element not None): + u"""addprevious(self, element) + + Adds the element as a preceding sibling directly before this + element. + + This is normally used to set a processing instruction or comment + before the root node of a document. Note that tail text is + automatically discarded when adding at the root level. + """ + _assertValidNode(self) + _assertValidNode(element) + if self._c_node.parent != NULL and not _isElement(self._c_node.parent): + if element._c_node.type != tree.XML_PI_NODE: + if element._c_node.type != tree.XML_COMMENT_NODE: + raise TypeError, u"Only processing instructions and comments can be siblings of the root element" + element.tail = None + _prependSibling(self, element) + + def extend(self, elements): + u"""extend(self, elements) + + Extends the current children by the elements in the iterable. + """ + cdef _Element element + _assertValidNode(self) + for element in elements: + if element is None: + raise TypeError, u"Node must not be None" + _assertValidNode(element) + _appendChild(self, element) + + def clear(self, bint keep_tail=False): + u"""clear(self, keep_tail=False) + + Resets an element. This function removes all subelements, clears + all attributes and sets the text and tail properties to None. + + Pass ``keep_tail=True`` to leave the tail text untouched. + """ + cdef xmlAttr* c_attr + cdef xmlAttr* c_attr_next + cdef xmlNode* c_node + cdef xmlNode* c_node_next + _assertValidNode(self) + c_node = self._c_node + # remove self.text and self.tail + _removeText(c_node.children) + if not keep_tail: + _removeText(c_node.next) + # remove all attributes + c_attr = c_node.properties + if c_attr: + c_node.properties = NULL + tree.xmlFreePropList(c_attr) + # remove all subelements + c_node = c_node.children + if c_node and not _isElement(c_node): + c_node = _nextElement(c_node) + while c_node is not NULL: + c_node_next = _nextElement(c_node) + _removeNode(self._doc, c_node) + c_node = c_node_next + + def insert(self, index: int, _Element element not None): + u"""insert(self, index, element) + + Inserts a subelement at the given position in this element + """ + cdef xmlNode* c_node + cdef xmlNode* c_next + cdef xmlDoc* c_source_doc + _assertValidNode(self) + _assertValidNode(element) + c_node = _findChild(self._c_node, index) + if c_node is NULL: + _appendChild(self, element) + return + c_source_doc = element._c_node.doc + c_next = element._c_node.next + tree.xmlAddPrevSibling(c_node, element._c_node) + _moveTail(c_next, element._c_node) + moveNodeToDocument(self._doc, c_source_doc, element._c_node) + + def remove(self, _Element element not None): + u"""remove(self, element) + + Removes a matching subelement. Unlike the find methods, this + method compares elements based on identity, not on tag value + or contents. + """ + cdef xmlNode* c_node + cdef xmlNode* c_next + _assertValidNode(self) + _assertValidNode(element) + c_node = element._c_node + if c_node.parent is not self._c_node: + raise ValueError, u"Element is not a child of this node." + c_next = element._c_node.next + tree.xmlUnlinkNode(c_node) + _moveTail(c_next, c_node) + # fix namespace declarations + moveNodeToDocument(self._doc, c_node.doc, c_node) + + def replace(self, _Element old_element not None, + _Element new_element not None): + u"""replace(self, old_element, new_element) + + Replaces a subelement with the element passed as second argument. + """ + cdef xmlNode* c_old_node + cdef xmlNode* c_old_next + cdef xmlNode* c_new_node + cdef xmlNode* c_new_next + cdef xmlDoc* c_source_doc + _assertValidNode(self) + _assertValidNode(old_element) + _assertValidNode(new_element) + c_old_node = old_element._c_node + if c_old_node.parent is not self._c_node: + raise ValueError, u"Element is not a child of this node." + c_old_next = c_old_node.next + c_new_node = new_element._c_node + c_new_next = c_new_node.next + c_source_doc = c_new_node.doc + tree.xmlReplaceNode(c_old_node, c_new_node) + _moveTail(c_new_next, c_new_node) + _moveTail(c_old_next, c_old_node) + moveNodeToDocument(self._doc, c_source_doc, c_new_node) + # fix namespace declarations + moveNodeToDocument(self._doc, c_old_node.doc, c_old_node) + + # PROPERTIES + property tag: + u"""Element tag + """ + def __get__(self): + if self._tag is not None: + return self._tag + _assertValidNode(self) + self._tag = _namespacedName(self._c_node) + return self._tag + + def __set__(self, value): + cdef _BaseParser parser + _assertValidNode(self) + ns, name = _getNsTag(value) + parser = self._doc._parser + if parser is not None and parser._for_html: + _htmlTagValidOrRaise(name) + else: + _tagValidOrRaise(name) + self._tag = value + tree.xmlNodeSetName(self._c_node, _xcstr(name)) + if ns is None: + self._c_node.ns = NULL + else: + self._doc._setNodeNs(self._c_node, _xcstr(ns)) + + @property + def attrib(self): + """Element attribute dictionary. Where possible, use get(), set(), + keys(), values() and items() to access element attributes. + """ + return _Attrib.__new__(_Attrib, self) + + property text: + u"""Text before the first subelement. This is either a string or + the value None, if there was no text. + """ + def __get__(self): + _assertValidNode(self) + return _collectText(self._c_node.children) + + def __set__(self, value): + _assertValidNode(self) + if isinstance(value, QName): + value = _resolveQNameText(self, value).decode('utf8') + _setNodeText(self._c_node, value) + + # using 'del el.text' is the wrong thing to do + #def __del__(self): + # _setNodeText(self._c_node, None) + + property tail: + u"""Text after this element's end tag, but before the next sibling + element's start tag. This is either a string or the value None, if + there was no text. + """ + def __get__(self): + _assertValidNode(self) + return _collectText(self._c_node.next) + + def __set__(self, value): + _assertValidNode(self) + _setTailText(self._c_node, value) + + # using 'del el.tail' is the wrong thing to do + #def __del__(self): + # _setTailText(self._c_node, None) + + # not in ElementTree, read-only + @property + def prefix(self): + """Namespace prefix or None. + """ + if self._c_node.ns is not NULL: + if self._c_node.ns.prefix is not NULL: + return funicode(self._c_node.ns.prefix) + return None + + # not in ElementTree, read-only + property sourceline: + u"""Original line number as found by the parser or None if unknown. + """ + def __get__(self): + cdef long line + _assertValidNode(self) + line = tree.xmlGetLineNo(self._c_node) + return line if line > 0 else None + + def __set__(self, line): + _assertValidNode(self) + if line <= 0: + self._c_node.line = 0 + else: + self._c_node.line = line + + # not in ElementTree, read-only + @property + def nsmap(self): + """Namespace prefix->URI mapping known in the context of this + Element. This includes all namespace declarations of the + parents. + + Note that changing the returned dict has no effect on the Element. + """ + _assertValidNode(self) + return _build_nsmap(self._c_node) + + # not in ElementTree, read-only + property base: + u"""The base URI of the Element (xml:base or HTML base URL). + None if the base URI is unknown. + + Note that the value depends on the URL of the document that + holds the Element if there is no xml:base attribute on the + Element or its ancestors. + + Setting this property will set an xml:base attribute on the + Element, regardless of the document type (XML or HTML). + """ + def __get__(self): + _assertValidNode(self) + c_base = tree.xmlNodeGetBase(self._doc._c_doc, self._c_node) + if c_base is NULL: + if self._doc._c_doc.URL is NULL: + return None + return _decodeFilename(self._doc._c_doc.URL) + try: + base = _decodeFilename(c_base) + finally: + tree.xmlFree(c_base) + return base + + def __set__(self, url): + _assertValidNode(self) + if url is None: + c_base = NULL + else: + url = _encodeFilename(url) + c_base = _xcstr(url) + tree.xmlNodeSetBase(self._c_node, c_base) + + # ACCESSORS + def __repr__(self): + u"__repr__(self)" + return "" % (strrepr(self.tag), id(self)) + + def __getitem__(self, x): + u"""Returns the subelement at the given position or the requested + slice. + """ + cdef xmlNode* c_node = NULL + cdef Py_ssize_t step = 0, slicelength = 0 + cdef Py_ssize_t c, i + cdef _node_to_node_function next_element + cdef list result + _assertValidNode(self) + if isinstance(x, slice): + # slicing + if _isFullSlice(x): + return _collectChildren(self) + _findChildSlice(x, self._c_node, &c_node, &step, &slicelength) + if c_node is NULL: + return [] + if step > 0: + next_element = _nextElement + else: + step = -step + next_element = _previousElement + result = [] + c = 0 + while c_node is not NULL and c < slicelength: + result.append(_elementFactory(self._doc, c_node)) + c += 1 + for i in range(step): + c_node = next_element(c_node) + if c_node is NULL: + break + return result + else: + # indexing + c_node = _findChild(self._c_node, x) + if c_node is NULL: + raise IndexError, u"list index out of range" + return _elementFactory(self._doc, c_node) + + def __len__(self): + u"""__len__(self) + + Returns the number of subelements. + """ + _assertValidNode(self) + return _countElements(self._c_node.children) + + def __nonzero__(self): + #u"__nonzero__(self)" # currently fails in Py3.1 + import warnings + warnings.warn( + u"The behavior of this method will change in future versions. " + u"Use specific 'len(elem)' or 'elem is not None' test instead.", + FutureWarning + ) + # emulate old behaviour + _assertValidNode(self) + return _hasChild(self._c_node) + + def __contains__(self, element): + u"__contains__(self, element)" + cdef xmlNode* c_node + _assertValidNode(self) + if not isinstance(element, _Element): + return 0 + c_node = (<_Element>element)._c_node + return c_node is not NULL and c_node.parent is self._c_node + + def __iter__(self): + u"__iter__(self)" + return ElementChildIterator(self) + + def __reversed__(self): + u"__reversed__(self)" + return ElementChildIterator(self, reversed=True) + + def index(self, _Element child not None, start: int = None, stop: int = None): + u"""index(self, child, start=None, stop=None) + + Find the position of the child within the parent. + + This method is not part of the original ElementTree API. + """ + cdef Py_ssize_t k, l + cdef Py_ssize_t c_start, c_stop + cdef xmlNode* c_child + cdef xmlNode* c_start_node + _assertValidNode(self) + _assertValidNode(child) + c_child = child._c_node + if c_child.parent is not self._c_node: + raise ValueError, u"Element is not a child of this node." + + # handle the unbounded search straight away (normal case) + if stop is None and (start is None or start == 0): + k = 0 + c_child = c_child.prev + while c_child is not NULL: + if _isElement(c_child): + k += 1 + c_child = c_child.prev + return k + + # check indices + if start is None: + c_start = 0 + else: + c_start = start + if stop is None: + c_stop = 0 + else: + c_stop = stop + if c_stop == 0 or \ + c_start >= c_stop and (c_stop > 0 or c_start < 0): + raise ValueError, u"list.index(x): x not in slice" + + # for negative slice indices, check slice before searching index + if c_start < 0 or c_stop < 0: + # start from right, at most up to leftmost(c_start, c_stop) + if c_start < c_stop: + k = -c_start + else: + k = -c_stop + c_start_node = self._c_node.last + l = 1 + while c_start_node != c_child and l < k: + if _isElement(c_start_node): + l += 1 + c_start_node = c_start_node.prev + if c_start_node == c_child: + # found! before slice end? + if c_stop < 0 and l <= -c_stop: + raise ValueError, u"list.index(x): x not in slice" + elif c_start < 0: + raise ValueError, u"list.index(x): x not in slice" + + # now determine the index backwards from child + c_child = c_child.prev + k = 0 + if c_stop > 0: + # we can optimize: stop after c_stop elements if not found + while c_child != NULL and k < c_stop: + if _isElement(c_child): + k += 1 + c_child = c_child.prev + if k < c_stop: + return k + else: + # traverse all + while c_child != NULL: + if _isElement(c_child): + k = k + 1 + c_child = c_child.prev + if c_start > 0: + if k >= c_start: + return k + else: + return k + if c_start != 0 or c_stop != 0: + raise ValueError, u"list.index(x): x not in slice" + else: + raise ValueError, u"list.index(x): x not in list" + + def get(self, key, default=None): + u"""get(self, key, default=None) + + Gets an element attribute. + """ + _assertValidNode(self) + return _getAttributeValue(self, key, default) + + def keys(self): + u"""keys(self) + + Gets a list of attribute names. The names are returned in an + arbitrary order (just like for an ordinary Python dictionary). + """ + _assertValidNode(self) + return _collectAttributes(self._c_node, 1) + + def values(self): + u"""values(self) + + Gets element attribute values as a sequence of strings. The + attributes are returned in an arbitrary order. + """ + _assertValidNode(self) + return _collectAttributes(self._c_node, 2) + + def items(self): + u"""items(self) + + Gets element attributes, as a sequence. The attributes are returned in + an arbitrary order. + """ + _assertValidNode(self) + return _collectAttributes(self._c_node, 3) + + def getchildren(self): + u"""getchildren(self) + + Returns all direct children. The elements are returned in document + order. + + :deprecated: Note that this method has been deprecated as of + ElementTree 1.3 and lxml 2.0. New code should use + ``list(element)`` or simply iterate over elements. + """ + _assertValidNode(self) + return _collectChildren(self) + + def getparent(self): + u"""getparent(self) + + Returns the parent of this element or None for the root element. + """ + cdef xmlNode* c_node + #_assertValidNode(self) # not needed + c_node = _parentElement(self._c_node) + if c_node is NULL: + return None + return _elementFactory(self._doc, c_node) + + def getnext(self): + u"""getnext(self) + + Returns the following sibling of this element or None. + """ + cdef xmlNode* c_node + #_assertValidNode(self) # not needed + c_node = _nextElement(self._c_node) + if c_node is NULL: + return None + return _elementFactory(self._doc, c_node) + + def getprevious(self): + u"""getprevious(self) + + Returns the preceding sibling of this element or None. + """ + cdef xmlNode* c_node + #_assertValidNode(self) # not needed + c_node = _previousElement(self._c_node) + if c_node is NULL: + return None + return _elementFactory(self._doc, c_node) + + def itersiblings(self, tag=None, *tags, preceding=False): + u"""itersiblings(self, tag=None, *tags, preceding=False) + + Iterate over the following or preceding siblings of this element. + + The direction is determined by the 'preceding' keyword which + defaults to False, i.e. forward iteration over the following + siblings. When True, the iterator yields the preceding + siblings in reverse document order, i.e. starting right before + the current element and going backwards. + + Can be restricted to find only elements with specific tags, + see `iter`. + """ + if preceding: + if self._c_node and not self._c_node.prev: + return ITER_EMPTY + elif self._c_node and not self._c_node.next: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return SiblingsIterator(self, tags, preceding=preceding) + + def iterancestors(self, tag=None, *tags): + u"""iterancestors(self, tag=None, *tags) + + Iterate over the ancestors of this element (from parent to parent). + + Can be restricted to find only elements with specific tags, + see `iter`. + """ + if self._c_node and not self._c_node.parent: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return AncestorsIterator(self, tags) + + def iterdescendants(self, tag=None, *tags): + u"""iterdescendants(self, tag=None, *tags) + + Iterate over the descendants of this element in document order. + + As opposed to ``el.iter()``, this iterator does not yield the element + itself. The returned elements can be restricted to find only elements + with specific tags, see `iter`. + """ + if self._c_node and not self._c_node.children: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return ElementDepthFirstIterator(self, tags, inclusive=False) + + def iterchildren(self, tag=None, *tags, reversed=False): + u"""iterchildren(self, tag=None, *tags, reversed=False) + + Iterate over the children of this element. + + As opposed to using normal iteration on this element, the returned + elements can be reversed with the 'reversed' keyword and restricted + to find only elements with specific tags, see `iter`. + """ + if self._c_node and not self._c_node.children: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return ElementChildIterator(self, tags, reversed=reversed) + + def getroottree(self): + u"""getroottree(self) + + Return an ElementTree for the root node of the document that + contains this element. + + This is the same as following element.getparent() up the tree until it + returns None (for the root element) and then build an ElementTree for + the last parent that was returned.""" + _assertValidDoc(self._doc) + return _elementTreeFactory(self._doc, None) + + def getiterator(self, tag=None, *tags): + u"""getiterator(self, tag=None, *tags) + + Returns a sequence or iterator of all elements in the subtree in + document order (depth first pre-order), starting with this + element. + + Can be restricted to find only elements with specific tags, + see `iter`. + + :deprecated: Note that this method is deprecated as of + ElementTree 1.3 and lxml 2.0. It returns an iterator in + lxml, which diverges from the original ElementTree + behaviour. If you want an efficient iterator, use the + ``element.iter()`` method instead. You should only use this + method in new code if you require backwards compatibility + with older versions of lxml or ElementTree. + """ + if tag is not None: + tags += (tag,) + return ElementDepthFirstIterator(self, tags) + + def iter(self, tag=None, *tags): + u"""iter(self, tag=None, *tags) + + Iterate over all elements in the subtree in document order (depth + first pre-order), starting with this element. + + Can be restricted to find only elements with specific tags: + pass ``"{ns}localname"`` as tag. Either or both of ``ns`` and + ``localname`` can be ``*`` for a wildcard; ``ns`` can be empty + for no namespace. ``"localname"`` is equivalent to ``"{}localname"`` + (i.e. no namespace) but ``"*"`` is ``"{*}*"`` (any or no namespace), + not ``"{}*"``. + + You can also pass the Element, Comment, ProcessingInstruction and + Entity factory functions to look only for the specific element type. + + Passing multiple tags (or a sequence of tags) instead of a single tag + will let the iterator return all elements matching any of these tags, + in document order. + """ + if tag is not None: + tags += (tag,) + return ElementDepthFirstIterator(self, tags) + + def itertext(self, tag=None, *tags, with_tail=True): + u"""itertext(self, tag=None, *tags, with_tail=True) + + Iterates over the text content of a subtree. + + You can pass tag names to restrict text content to specific elements, + see `iter`. + + You can set the ``with_tail`` keyword argument to ``False`` to skip + over tail text. + """ + if tag is not None: + tags += (tag,) + return ElementTextIterator(self, tags, with_tail=with_tail) + + def makeelement(self, _tag, attrib=None, nsmap=None, **_extra): + u"""makeelement(self, _tag, attrib=None, nsmap=None, **_extra) + + Creates a new element associated with the same document. + """ + _assertValidDoc(self._doc) + return _makeElement(_tag, NULL, self._doc, None, None, None, + attrib, nsmap, _extra) + + def find(self, path, namespaces=None): + u"""find(self, path, namespaces=None) + + Finds the first matching subelement, by tag name or path. + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + if isinstance(path, QName): + path = (path).text + return _elementpath.find(self, path, namespaces) + + def findtext(self, path, default=None, namespaces=None): + u"""findtext(self, path, default=None, namespaces=None) + + Finds text for the first matching subelement, by tag name or path. + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + if isinstance(path, QName): + path = (path).text + return _elementpath.findtext(self, path, default, namespaces) + + def findall(self, path, namespaces=None): + u"""findall(self, path, namespaces=None) + + Finds all matching subelements, by tag name or path. + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + if isinstance(path, QName): + path = (path).text + return _elementpath.findall(self, path, namespaces) + + def iterfind(self, path, namespaces=None): + u"""iterfind(self, path, namespaces=None) + + Iterates over all matching subelements, by tag name or path. + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + if isinstance(path, QName): + path = (path).text + return _elementpath.iterfind(self, path, namespaces) + + def xpath(self, _path, *, namespaces=None, extensions=None, + smart_strings=True, **_variables): + u"""xpath(self, _path, namespaces=None, extensions=None, smart_strings=True, **_variables) + + Evaluate an xpath expression using the element as context node. + """ + evaluator = XPathElementEvaluator(self, namespaces=namespaces, + extensions=extensions, + smart_strings=smart_strings) + return evaluator(_path, **_variables) + + def cssselect(self, expr, *, translator='xml'): + """ + Run the CSS expression on this element and its children, + returning a list of the results. + + Equivalent to lxml.cssselect.CSSSelect(expr)(self) -- note + that pre-compiling the expression can provide a substantial + speedup. + """ + # Do the import here to make the dependency optional. + from lxml.cssselect import CSSSelector + return CSSSelector(expr, translator=translator)(self) + + +cdef extern from "includes/etree_defs.h": + # macro call to 't->tp_new()' for fast instantiation + cdef object NEW_ELEMENT "PY_NEW" (object t) + + +@cython.linetrace(False) +cdef _Element _elementFactory(_Document doc, xmlNode* c_node): + cdef _Element result + result = getProxy(c_node) + if result is not None: + return result + if c_node is NULL: + return None + + element_class = LOOKUP_ELEMENT_CLASS( + ELEMENT_CLASS_LOOKUP_STATE, doc, c_node) + if hasProxy(c_node): + # prevent re-entry race condition - we just called into Python + return getProxy(c_node) + result = NEW_ELEMENT(element_class) + if hasProxy(c_node): + # prevent re-entry race condition - we just called into Python + result._c_node = NULL + return getProxy(c_node) + + _registerProxy(result, doc, c_node) + if element_class is not _Element: + result._init() + return result + + +@cython.internal +cdef class __ContentOnlyElement(_Element): + cdef int _raiseImmutable(self) except -1: + raise TypeError, u"this element does not have children or attributes" + + def set(self, key, value): + u"set(self, key, value)" + self._raiseImmutable() + + def append(self, value): + u"append(self, value)" + self._raiseImmutable() + + def insert(self, index, value): + u"insert(self, index, value)" + self._raiseImmutable() + + def __setitem__(self, index, value): + u"__setitem__(self, index, value)" + self._raiseImmutable() + + @property + def attrib(self): + return IMMUTABLE_EMPTY_MAPPING + + property text: + def __get__(self): + _assertValidNode(self) + return funicodeOrEmpty(self._c_node.content) + + def __set__(self, value): + cdef tree.xmlDict* c_dict + _assertValidNode(self) + if value is None: + c_text = NULL + else: + value = _utf8(value) + c_text = _xcstr(value) + tree.xmlNodeSetContent(self._c_node, c_text) + + # ACCESSORS + def __getitem__(self, x): + u"__getitem__(self, x)" + if isinstance(x, slice): + return [] + else: + raise IndexError, u"list index out of range" + + def __len__(self): + u"__len__(self)" + return 0 + + def get(self, key, default=None): + u"get(self, key, default=None)" + return None + + def keys(self): + u"keys(self)" + return [] + + def items(self): + u"items(self)" + return [] + + def values(self): + u"values(self)" + return [] + +cdef class _Comment(__ContentOnlyElement): + @property + def tag(self): + return Comment + + def __repr__(self): + return "" % strrepr(self.text) + +cdef class _ProcessingInstruction(__ContentOnlyElement): + @property + def tag(self): + return ProcessingInstruction + + property target: + # not in ElementTree + def __get__(self): + _assertValidNode(self) + return funicode(self._c_node.name) + + def __set__(self, value): + _assertValidNode(self) + value = _utf8(value) + c_text = _xcstr(value) + tree.xmlNodeSetName(self._c_node, c_text) + + def __repr__(self): + text = self.text + if text: + return "" % (strrepr(self.target), + strrepr(text)) + else: + return "" % strrepr(self.target) + + def get(self, key, default=None): + u"""get(self, key, default=None) + + Try to parse pseudo-attributes from the text content of the + processing instruction, search for one with the given key as + name and return its associated value. + + Note that this is only a convenience method for the most + common case that all text content is structured in + attribute-like name-value pairs with properly quoted values. + It is not guaranteed to work for all possible text content. + """ + return self.attrib.get(key, default) + + @property + def attrib(self): + """Returns a dict containing all pseudo-attributes that can be + parsed from the text content of this processing instruction. + Note that modifying the dict currently has no effect on the + XML node, although this is not guaranteed to stay this way. + """ + return { attr : (value1 or value2) + for attr, value1, value2 in _FIND_PI_ATTRIBUTES(u' ' + self.text) } + +cdef object _FIND_PI_ATTRIBUTES = re.compile(ur'\s+(\w+)\s*=\s*(?:\'([^\']*)\'|"([^"]*)")', re.U).findall + +cdef class _Entity(__ContentOnlyElement): + @property + def tag(self): + return Entity + + property name: + # not in ElementTree + def __get__(self): + _assertValidNode(self) + return funicode(self._c_node.name) + + def __set__(self, value): + _assertValidNode(self) + value_utf = _utf8(value) + if b'&' in value_utf or b';' in value_utf: + raise ValueError, f"Invalid entity name '{value}'" + tree.xmlNodeSetName(self._c_node, _xcstr(value_utf)) + + @property + def text(self): + # FIXME: should this be None or '&[VALUE];' or the resolved + # entity value ? + _assertValidNode(self) + return f'&{funicode(self._c_node.name)};' + + def __repr__(self): + return "&%s;" % strrepr(self.name) + + +cdef class QName: + u"""QName(text_or_uri_or_element, tag=None) + + QName wrapper for qualified XML names. + + Pass a tag name by itself or a namespace URI and a tag name to + create a qualified name. Alternatively, pass an Element to + extract its tag name. ``None`` as first argument is ignored in + order to allow for generic 2-argument usage. + + The ``text`` property holds the qualified name in + ``{namespace}tagname`` notation. The ``namespace`` and + ``localname`` properties hold the respective parts of the tag + name. + + You can pass QName objects wherever a tag name is expected. Also, + setting Element text from a QName will resolve the namespace prefix + on assignment and set a qualified text value. This is helpful in XML + languages like SOAP or XML-Schema that use prefixed tag names in + their text content. + """ + cdef readonly unicode text + cdef readonly unicode localname + cdef readonly unicode namespace + def __init__(self, text_or_uri_or_element, tag=None): + if text_or_uri_or_element is None: + # Allow None as no namespace. + text_or_uri_or_element, tag = tag, None + if not _isString(text_or_uri_or_element): + if isinstance(text_or_uri_or_element, _Element): + text_or_uri_or_element = (<_Element>text_or_uri_or_element).tag + if not _isString(text_or_uri_or_element): + raise ValueError, f"Invalid input tag of type {type(text_or_uri_or_element)!r}" + elif isinstance(text_or_uri_or_element, QName): + text_or_uri_or_element = (text_or_uri_or_element).text + elif text_or_uri_or_element is not None: + text_or_uri_or_element = unicode(text_or_uri_or_element) + else: + raise ValueError, f"Invalid input tag of type {type(text_or_uri_or_element)!r}" + + ns_utf, tag_utf = _getNsTag(text_or_uri_or_element) + if tag is not None: + # either ('ns', 'tag') or ('{ns}oldtag', 'newtag') + if ns_utf is None: + ns_utf = tag_utf # case 1: namespace ended up as tag name + tag_utf = _utf8(tag) + _tagValidOrRaise(tag_utf) + self.localname = (tag_utf).decode('utf8') + if ns_utf is None: + self.namespace = None + self.text = self.localname + else: + self.namespace = (ns_utf).decode('utf8') + self.text = u"{%s}%s" % (self.namespace, self.localname) + def __str__(self): + return self.text + def __hash__(self): + return hash(self.text) + def __richcmp__(self, other, int op): + try: + if type(other) is QName: + other = (other).text + elif not isinstance(other, unicode): + other = unicode(other) + except (ValueError, UnicodeDecodeError): + return NotImplemented + return python.PyObject_RichCompare(self.text, other, op) + + +cdef public class _ElementTree [ type LxmlElementTreeType, + object LxmlElementTree ]: + cdef _Document _doc + cdef _Element _context_node + + # Note that _doc is only used to store the original document if we do not + # have a _context_node. All methods should prefer self._context_node._doc + # to honour tree restructuring. _doc can happily be None! + + @cython.final + cdef int _assertHasRoot(self) except -1: + u"""We have to take care here: the document may not have a root node! + This can happen if ElementTree() is called without any argument and + the caller 'forgets' to call parse() afterwards, so this is a bug in + the caller program. + """ + assert self._context_node is not None, \ + u"ElementTree not initialized, missing root" + return 0 + + def parse(self, source, _BaseParser parser=None, *, base_url=None): + u"""parse(self, source, parser=None, base_url=None) + + Updates self with the content of source and returns its root. + """ + cdef _Document doc = None + try: + doc = _parseDocument(source, parser, base_url) + except _TargetParserResult as result_container: + # raises a TypeError if we don't get an _Element + self._context_node = result_container.result + else: + self._context_node = doc.getroot() + self._doc = None if self._context_node is not None else doc + return self._context_node + + def _setroot(self, _Element root not None): + u"""_setroot(self, root) + + Relocate the ElementTree to a new root node. + """ + _assertValidNode(root) + if root._c_node.type != tree.XML_ELEMENT_NODE: + raise TypeError, u"Only elements can be the root of an ElementTree" + self._context_node = root + self._doc = None + + def getroot(self): + u"""getroot(self) + + Gets the root element for this tree. + """ + return self._context_node + + def __copy__(self): + return _elementTreeFactory(self._doc, self._context_node) + + def __deepcopy__(self, memo): + cdef _Element root + cdef _Document doc + cdef xmlDoc* c_doc + if self._context_node is not None: + root = self._context_node.__copy__() + assert root is not None + _assertValidNode(root) + _copyNonElementSiblings(self._context_node._c_node, root._c_node) + return _elementTreeFactory(None, root) + elif self._doc is not None: + _assertValidDoc(self._doc) + c_doc = tree.xmlCopyDoc(self._doc._c_doc, 1) + if c_doc is NULL: + raise MemoryError() + doc = _documentFactory(c_doc, self._doc._parser) + return _elementTreeFactory(doc, None) + else: + # so what ... + return self + + # not in ElementTree + @property + def docinfo(self) -> DocInfo: + """Information about the document provided by parser and DTD.""" + self._assertHasRoot() + return DocInfo(self._context_node._doc) + + # not in ElementTree, read-only + @property + def parser(self): + """The parser that was used to parse the document in this ElementTree. + """ + if self._context_node is not None and \ + self._context_node._doc is not None: + return self._context_node._doc._parser + if self._doc is not None: + return self._doc._parser + return None + + def write(self, file, *, encoding=None, method="xml", + bint pretty_print=False, xml_declaration=None, bint with_tail=True, + standalone=None, doctype=None, compression=0, + bint exclusive=False, inclusive_ns_prefixes=None, + bint with_comments=True, bint strip_text=False, + docstring=None): + u"""write(self, file, encoding=None, method="xml", + pretty_print=False, xml_declaration=None, with_tail=True, + standalone=None, doctype=None, compression=0, + exclusive=False, inclusive_ns_prefixes=None, + with_comments=True, strip_text=False) + + Write the tree to a filename, file or file-like object. + + Defaults to ASCII encoding and writing a declaration as needed. + + The keyword argument 'method' selects the output method: + 'xml', 'html', 'text' or 'c14n'. Default is 'xml'. + + With ``method="c14n"`` (C14N version 1), the options ``exclusive``, + ``with_comments`` and ``inclusive_ns_prefixes`` request exclusive + C14N, include comments, and list the inclusive prefixes respectively. + + With ``method="c14n2"`` (C14N version 2), the ``with_comments`` and + ``strip_text`` options control the output of comments and text space + according to C14N 2.0. + + Passing a boolean value to the ``standalone`` option will + output an XML declaration with the corresponding + ``standalone`` flag. + + The ``doctype`` option allows passing in a plain string that will + be serialised before the XML tree. Note that passing in non + well-formed content here will make the XML output non well-formed. + Also, an existing doctype in the document tree will not be removed + when serialising an ElementTree instance. + + The ``compression`` option enables GZip compression level 1-9. + + The ``inclusive_ns_prefixes`` should be a list of namespace strings + (i.e. ['xs', 'xsi']) that will be promoted to the top-level element + during exclusive C14N serialisation. This parameter is ignored if + exclusive mode=False. + + If exclusive=True and no list is provided, a namespace will only be + rendered if it is used by the immediate parent or one of its attributes + and its prefix and values have not already been rendered by an ancestor + of the namespace node's parent element. + """ + cdef bint write_declaration + cdef int is_standalone + + self._assertHasRoot() + _assertValidNode(self._context_node) + if compression is None or compression < 0: + compression = 0 + + # C14N serialisation + if method in ('c14n', 'c14n2'): + if encoding is not None: + raise ValueError("Cannot specify encoding with C14N") + if xml_declaration: + raise ValueError("Cannot enable XML declaration in C14N") + + if method == 'c14n': + _tofilelikeC14N(file, self._context_node, exclusive, with_comments, + compression, inclusive_ns_prefixes) + else: # c14n2 + with _open_utf8_file(file, compression=compression) as f: + target = C14NWriterTarget( + f.write, with_comments=with_comments, strip_text=strip_text) + _tree_to_target(self, target) + return + + if not with_comments: + raise ValueError("Can only discard comments in C14N serialisation") + # suppress decl. in default case (purely for ElementTree compatibility) + if xml_declaration is not None: + write_declaration = xml_declaration + if encoding is None: + encoding = 'ASCII' + else: + encoding = encoding.upper() + elif encoding is None: + encoding = 'ASCII' + write_declaration = 0 + else: + encoding = encoding.upper() + write_declaration = encoding not in ( + 'US-ASCII', 'ASCII', 'UTF8', 'UTF-8') + if standalone is None: + is_standalone = -1 + elif standalone: + write_declaration = 1 + is_standalone = 1 + else: + write_declaration = 1 + is_standalone = 0 + + if docstring is not None and doctype is None: + import warnings + warnings.warn( + "The 'docstring' option is deprecated. Use 'doctype' instead.", + DeprecationWarning) + doctype = docstring + + _tofilelike(file, self._context_node, encoding, doctype, method, + write_declaration, 1, pretty_print, with_tail, + is_standalone, compression) + + def getpath(self, _Element element not None): + u"""getpath(self, element) + + Returns a structural, absolute XPath expression to find the element. + + For namespaced elements, the expression uses prefixes from the + document, which therefore need to be provided in order to make any + use of the expression in XPath. + + Also see the method getelementpath(self, element), which returns a + self-contained ElementPath expression. + """ + cdef _Document doc + cdef _Element root + cdef xmlDoc* c_doc + _assertValidNode(element) + if self._context_node is not None: + root = self._context_node + doc = root._doc + elif self._doc is not None: + doc = self._doc + root = doc.getroot() + else: + raise ValueError, u"Element is not in this tree." + _assertValidDoc(doc) + _assertValidNode(root) + if element._doc is not doc: + raise ValueError, u"Element is not in this tree." + + c_doc = _fakeRootDoc(doc._c_doc, root._c_node) + c_path = tree.xmlGetNodePath(element._c_node) + _destroyFakeDoc(doc._c_doc, c_doc) + if c_path is NULL: + raise MemoryError() + path = funicode(c_path) + tree.xmlFree(c_path) + return path + + def getelementpath(self, _Element element not None): + u"""getelementpath(self, element) + + Returns a structural, absolute ElementPath expression to find the + element. This path can be used in the .find() method to look up + the element, provided that the elements along the path and their + list of immediate children were not modified in between. + + ElementPath has the advantage over an XPath expression (as returned + by the .getpath() method) that it does not require additional prefix + declarations. It is always self-contained. + """ + cdef _Element root + cdef Py_ssize_t count + _assertValidNode(element) + if element._c_node.type != tree.XML_ELEMENT_NODE: + raise ValueError, u"input is not an Element" + if self._context_node is not None: + root = self._context_node + elif self._doc is not None: + root = self._doc.getroot() + else: + raise ValueError, u"Element is not in this tree" + _assertValidNode(root) + if element._doc is not root._doc: + raise ValueError, u"Element is not in this tree" + + path = [] + c_element = element._c_node + while c_element is not root._c_node: + c_name = c_element.name + c_href = _getNs(c_element) + tag = _namespacedNameFromNsName(c_href, c_name) + if c_href is NULL: + c_href = b'' # no namespace (NULL is wildcard) + # use tag[N] if there are preceding siblings with the same tag + count = 0 + c_node = c_element.prev + while c_node is not NULL: + if c_node.type == tree.XML_ELEMENT_NODE: + if _tagMatches(c_node, c_href, c_name): + count += 1 + c_node = c_node.prev + if count: + tag = f'{tag}[{count+1}]' + else: + # use tag[1] if there are following siblings with the same tag + c_node = c_element.next + while c_node is not NULL: + if c_node.type == tree.XML_ELEMENT_NODE: + if _tagMatches(c_node, c_href, c_name): + tag += '[1]' + break + c_node = c_node.next + + path.append(tag) + c_element = c_element.parent + if c_element is NULL or c_element.type != tree.XML_ELEMENT_NODE: + raise ValueError, u"Element is not in this tree." + if not path: + return '.' + path.reverse() + return '/'.join(path) + + def getiterator(self, tag=None, *tags): + u"""getiterator(self, *tags, tag=None) + + Returns a sequence or iterator of all elements in document order + (depth first pre-order), starting with the root element. + + Can be restricted to find only elements with specific tags, + see `_Element.iter`. + + :deprecated: Note that this method is deprecated as of + ElementTree 1.3 and lxml 2.0. It returns an iterator in + lxml, which diverges from the original ElementTree + behaviour. If you want an efficient iterator, use the + ``tree.iter()`` method instead. You should only use this + method in new code if you require backwards compatibility + with older versions of lxml or ElementTree. + """ + root = self.getroot() + if root is None: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return root.getiterator(*tags) + + def iter(self, tag=None, *tags): + u"""iter(self, tag=None, *tags) + + Creates an iterator for the root element. The iterator loops over + all elements in this tree, in document order. Note that siblings + of the root element (comments or processing instructions) are not + returned by the iterator. + + Can be restricted to find only elements with specific tags, + see `_Element.iter`. + """ + root = self.getroot() + if root is None: + return ITER_EMPTY + if tag is not None: + tags += (tag,) + return root.iter(*tags) + + def find(self, path, namespaces=None): + u"""find(self, path, namespaces=None) + + Finds the first toplevel element with given tag. Same as + ``tree.getroot().find(path)``. + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + self._assertHasRoot() + root = self.getroot() + if _isString(path): + if path[:1] == "/": + path = "." + path + return root.find(path, namespaces) + + def findtext(self, path, default=None, namespaces=None): + u"""findtext(self, path, default=None, namespaces=None) + + Finds the text for the first element matching the ElementPath + expression. Same as getroot().findtext(path) + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + self._assertHasRoot() + root = self.getroot() + if _isString(path): + if path[:1] == "/": + path = "." + path + return root.findtext(path, default, namespaces) + + def findall(self, path, namespaces=None): + u"""findall(self, path, namespaces=None) + + Finds all elements matching the ElementPath expression. Same as + getroot().findall(path). + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + self._assertHasRoot() + root = self.getroot() + if _isString(path): + if path[:1] == "/": + path = "." + path + return root.findall(path, namespaces) + + def iterfind(self, path, namespaces=None): + u"""iterfind(self, path, namespaces=None) + + Iterates over all elements matching the ElementPath expression. + Same as getroot().iterfind(path). + + The optional ``namespaces`` argument accepts a + prefix-to-namespace mapping that allows the usage of XPath + prefixes in the path expression. + """ + self._assertHasRoot() + root = self.getroot() + if _isString(path): + if path[:1] == "/": + path = "." + path + return root.iterfind(path, namespaces) + + def xpath(self, _path, *, namespaces=None, extensions=None, + smart_strings=True, **_variables): + u"""xpath(self, _path, namespaces=None, extensions=None, smart_strings=True, **_variables) + + XPath evaluate in context of document. + + ``namespaces`` is an optional dictionary with prefix to namespace URI + mappings, used by XPath. ``extensions`` defines additional extension + functions. + + Returns a list (nodeset), or bool, float or string. + + In case of a list result, return Element for element nodes, + string for text and attribute values. + + Note: if you are going to apply multiple XPath expressions + against the same document, it is more efficient to use + XPathEvaluator directly. + """ + self._assertHasRoot() + evaluator = XPathDocumentEvaluator(self, namespaces=namespaces, + extensions=extensions, + smart_strings=smart_strings) + return evaluator(_path, **_variables) + + def xslt(self, _xslt, extensions=None, access_control=None, **_kw): + u"""xslt(self, _xslt, extensions=None, access_control=None, **_kw) + + Transform this document using other document. + + xslt is a tree that should be XSLT + keyword parameters are XSLT transformation parameters. + + Returns the transformed tree. + + Note: if you are going to apply the same XSLT stylesheet against + multiple documents, it is more efficient to use the XSLT + class directly. + """ + self._assertHasRoot() + style = XSLT(_xslt, extensions=extensions, + access_control=access_control) + return style(self, **_kw) + + def relaxng(self, relaxng): + u"""relaxng(self, relaxng) + + Validate this document using other document. + + The relaxng argument is a tree that should contain a Relax NG schema. + + Returns True or False, depending on whether validation + succeeded. + + Note: if you are going to apply the same Relax NG schema against + multiple documents, it is more efficient to use the RelaxNG + class directly. + """ + self._assertHasRoot() + schema = RelaxNG(relaxng) + return schema.validate(self) + + def xmlschema(self, xmlschema): + u"""xmlschema(self, xmlschema) + + Validate this document using other document. + + The xmlschema argument is a tree that should contain an XML Schema. + + Returns True or False, depending on whether validation + succeeded. + + Note: If you are going to apply the same XML Schema against + multiple documents, it is more efficient to use the XMLSchema + class directly. + """ + self._assertHasRoot() + schema = XMLSchema(xmlschema) + return schema.validate(self) + + def xinclude(self): + u"""xinclude(self) + + Process the XInclude nodes in this document and include the + referenced XML fragments. + + There is support for loading files through the file system, HTTP and + FTP. + + Note that XInclude does not support custom resolvers in Python space + due to restrictions of libxml2 <= 2.6.29. + """ + self._assertHasRoot() + XInclude()(self._context_node) + + def write_c14n(self, file, *, bint exclusive=False, bint with_comments=True, + compression=0, inclusive_ns_prefixes=None): + u"""write_c14n(self, file, exclusive=False, with_comments=True, + compression=0, inclusive_ns_prefixes=None) + + C14N write of document. Always writes UTF-8. + + The ``compression`` option enables GZip compression level 1-9. + + The ``inclusive_ns_prefixes`` should be a list of namespace strings + (i.e. ['xs', 'xsi']) that will be promoted to the top-level element + during exclusive C14N serialisation. This parameter is ignored if + exclusive mode=False. + + If exclusive=True and no list is provided, a namespace will only be + rendered if it is used by the immediate parent or one of its attributes + and its prefix and values have not already been rendered by an ancestor + of the namespace node's parent element. + + NOTE: This method is deprecated as of lxml 4.4 and will be removed in a + future release. Use ``.write(f, method="c14n")`` instead. + """ + self._assertHasRoot() + _assertValidNode(self._context_node) + if compression is None or compression < 0: + compression = 0 + + _tofilelikeC14N(file, self._context_node, exclusive, with_comments, + compression, inclusive_ns_prefixes) + +cdef _ElementTree _elementTreeFactory(_Document doc, _Element context_node): + return _newElementTree(doc, context_node, _ElementTree) + +cdef _ElementTree _newElementTree(_Document doc, _Element context_node, + object baseclass): + cdef _ElementTree result + result = baseclass() + if context_node is None and doc is not None: + context_node = doc.getroot() + if context_node is None: + _assertValidDoc(doc) + result._doc = doc + else: + _assertValidNode(context_node) + result._context_node = context_node + return result + + +@cython.final +@cython.freelist(16) +cdef class _Attrib: + u"""A dict-like proxy for the ``Element.attrib`` property. + """ + cdef _Element _element + def __cinit__(self, _Element element not None): + _assertValidNode(element) + self._element = element + + # MANIPULATORS + def __setitem__(self, key, value): + _assertValidNode(self._element) + _setAttributeValue(self._element, key, value) + + def __delitem__(self, key): + _assertValidNode(self._element) + _delAttribute(self._element, key) + + def update(self, sequence_or_dict): + _assertValidNode(self._element) + if isinstance(sequence_or_dict, (dict, _Attrib)): + sequence_or_dict = sequence_or_dict.items() + for key, value in sequence_or_dict: + _setAttributeValue(self._element, key, value) + + def pop(self, key, *default): + if len(default) > 1: + raise TypeError, f"pop expected at most 2 arguments, got {len(default)+1}" + _assertValidNode(self._element) + result = _getAttributeValue(self._element, key, None) + if result is None: + if not default: + raise KeyError, key + result = default[0] + else: + _delAttribute(self._element, key) + return result + + def clear(self): + _assertValidNode(self._element) + c_attrs = self._element._c_node.properties + if c_attrs: + self._element._c_node.properties = NULL + tree.xmlFreePropList(c_attrs) + + # ACCESSORS + def __repr__(self): + _assertValidNode(self._element) + return repr(dict( _collectAttributes(self._element._c_node, 3) )) + + def __copy__(self): + _assertValidNode(self._element) + return dict(_collectAttributes(self._element._c_node, 3)) + + def __deepcopy__(self, memo): + _assertValidNode(self._element) + return dict(_collectAttributes(self._element._c_node, 3)) + + def __getitem__(self, key): + _assertValidNode(self._element) + result = _getAttributeValue(self._element, key, None) + if result is None: + raise KeyError, key + return result + + def __bool__(self): + _assertValidNode(self._element) + cdef xmlAttr* c_attr = self._element._c_node.properties + while c_attr is not NULL: + if c_attr.type == tree.XML_ATTRIBUTE_NODE: + return 1 + c_attr = c_attr.next + return 0 + + def __len__(self): + _assertValidNode(self._element) + cdef xmlAttr* c_attr = self._element._c_node.properties + cdef Py_ssize_t c = 0 + while c_attr is not NULL: + if c_attr.type == tree.XML_ATTRIBUTE_NODE: + c += 1 + c_attr = c_attr.next + return c + + def get(self, key, default=None): + _assertValidNode(self._element) + return _getAttributeValue(self._element, key, default) + + def keys(self): + _assertValidNode(self._element) + return _collectAttributes(self._element._c_node, 1) + + def __iter__(self): + _assertValidNode(self._element) + return iter(_collectAttributes(self._element._c_node, 1)) + + def iterkeys(self): + _assertValidNode(self._element) + return iter(_collectAttributes(self._element._c_node, 1)) + + def values(self): + _assertValidNode(self._element) + return _collectAttributes(self._element._c_node, 2) + + def itervalues(self): + _assertValidNode(self._element) + return iter(_collectAttributes(self._element._c_node, 2)) + + def items(self): + _assertValidNode(self._element) + return _collectAttributes(self._element._c_node, 3) + + def iteritems(self): + _assertValidNode(self._element) + return iter(_collectAttributes(self._element._c_node, 3)) + + def has_key(self, key): + _assertValidNode(self._element) + return key in self + + def __contains__(self, key): + _assertValidNode(self._element) + cdef xmlNode* c_node + ns, tag = _getNsTag(key) + c_node = self._element._c_node + c_href = NULL if ns is None else _xcstr(ns) + return 1 if tree.xmlHasNsProp(c_node, _xcstr(tag), c_href) else 0 + + def __richcmp__(self, other, int op): + try: + one = dict(self.items()) + if not isinstance(other, dict): + other = dict(other) + except (TypeError, ValueError): + return NotImplemented + return python.PyObject_RichCompare(one, other, op) + +MutableMapping.register(_Attrib) + + +@cython.final +@cython.internal +cdef class _AttribIterator: + u"""Attribute iterator - for internal use only! + """ + # XML attributes must not be removed while running! + cdef _Element _node + cdef xmlAttr* _c_attr + cdef int _keysvalues # 1 - keys, 2 - values, 3 - items (key, value) + def __iter__(self): + return self + + def __next__(self): + cdef xmlAttr* c_attr + if self._node is None: + raise StopIteration + c_attr = self._c_attr + while c_attr is not NULL and c_attr.type != tree.XML_ATTRIBUTE_NODE: + c_attr = c_attr.next + if c_attr is NULL: + self._node = None + raise StopIteration + + self._c_attr = c_attr.next + if self._keysvalues == 1: + return _namespacedName(c_attr) + elif self._keysvalues == 2: + return _attributeValue(self._node._c_node, c_attr) + else: + return (_namespacedName(c_attr), + _attributeValue(self._node._c_node, c_attr)) + +cdef object _attributeIteratorFactory(_Element element, int keysvalues): + cdef _AttribIterator attribs + if element._c_node.properties is NULL: + return ITER_EMPTY + attribs = _AttribIterator() + attribs._node = element + attribs._c_attr = element._c_node.properties + attribs._keysvalues = keysvalues + return attribs + + +cdef public class _ElementTagMatcher [ object LxmlElementTagMatcher, + type LxmlElementTagMatcherType ]: + """ + Dead but public. :) + """ + cdef object _pystrings + cdef int _node_type + cdef char* _href + cdef char* _name + cdef _initTagMatch(self, tag): + self._href = NULL + self._name = NULL + if tag is None: + self._node_type = 0 + elif tag is Comment: + self._node_type = tree.XML_COMMENT_NODE + elif tag is ProcessingInstruction: + self._node_type = tree.XML_PI_NODE + elif tag is Entity: + self._node_type = tree.XML_ENTITY_REF_NODE + elif tag is Element: + self._node_type = tree.XML_ELEMENT_NODE + else: + self._node_type = tree.XML_ELEMENT_NODE + self._pystrings = _getNsTag(tag) + if self._pystrings[0] is not None: + self._href = _cstr(self._pystrings[0]) + self._name = _cstr(self._pystrings[1]) + if self._name[0] == c'*' and self._name[1] == c'\0': + self._name = NULL + +cdef public class _ElementIterator(_ElementTagMatcher) [ + object LxmlElementIterator, type LxmlElementIteratorType ]: + """ + Dead but public. :) + """ + # we keep Python references here to control GC + cdef _Element _node + cdef _node_to_node_function _next_element + def __iter__(self): + return self + + cdef void _storeNext(self, _Element node): + cdef xmlNode* c_node + c_node = self._next_element(node._c_node) + while c_node is not NULL and \ + self._node_type != 0 and \ + (self._node_type != c_node.type or + not _tagMatches(c_node, self._href, self._name)): + c_node = self._next_element(c_node) + if c_node is NULL: + self._node = None + else: + # Python ref: + self._node = _elementFactory(node._doc, c_node) + + def __next__(self): + cdef xmlNode* c_node + cdef _Element current_node + if self._node is None: + raise StopIteration + # Python ref: + current_node = self._node + self._storeNext(current_node) + return current_node + +@cython.final +@cython.internal +cdef class _MultiTagMatcher: + """ + Match an xmlNode against a list of tags. + """ + cdef list _py_tags + cdef qname* _cached_tags + cdef size_t _tag_count + cdef size_t _cached_size + cdef _Document _cached_doc + cdef int _node_types + + def __cinit__(self, tags): + self._py_tags = [] + self.initTagMatch(tags) + + def __dealloc__(self): + self._clear() + + cdef bint rejectsAll(self): + return not self._tag_count and not self._node_types + + cdef bint rejectsAllAttributes(self): + return not self._tag_count + + cdef bint matchesType(self, int node_type): + if node_type == tree.XML_ELEMENT_NODE and self._tag_count: + return True + return self._node_types & (1 << node_type) + + cdef void _clear(self): + cdef size_t i, count + count = self._tag_count + self._tag_count = 0 + if self._cached_tags: + for i in xrange(count): + cpython.ref.Py_XDECREF(self._cached_tags[i].href) + python.lxml_free(self._cached_tags) + self._cached_tags = NULL + + cdef initTagMatch(self, tags): + self._cached_doc = None + del self._py_tags[:] + self._clear() + if tags is None or tags == (): + # no selection in tags argument => match anything + self._node_types = ( + 1 << tree.XML_COMMENT_NODE | + 1 << tree.XML_PI_NODE | + 1 << tree.XML_ENTITY_REF_NODE | + 1 << tree.XML_ELEMENT_NODE) + else: + self._node_types = 0 + self._storeTags(tags, set()) + + cdef _storeTags(self, tag, set seen): + if tag is Comment: + self._node_types |= 1 << tree.XML_COMMENT_NODE + elif tag is ProcessingInstruction: + self._node_types |= 1 << tree.XML_PI_NODE + elif tag is Entity: + self._node_types |= 1 << tree.XML_ENTITY_REF_NODE + elif tag is Element: + self._node_types |= 1 << tree.XML_ELEMENT_NODE + elif python._isString(tag): + if tag in seen: + return + seen.add(tag) + if tag in ('*', '{*}*'): + self._node_types |= 1 << tree.XML_ELEMENT_NODE + else: + href, name = _getNsTag(tag) + if name == b'*': + name = None + if href is None: + href = b'' # no namespace + elif href == b'*': + href = None # wildcard: any namespace, including none + self._py_tags.append((href, name)) + elif isinstance(tag, QName): + self._storeTags(tag.text, seen) + else: + # support a sequence of tags + for item in tag: + self._storeTags(item, seen) + + cdef inline int cacheTags(self, _Document doc, bint force_into_dict=False) except -1: + """ + Look up the tag names in the doc dict to enable string pointer comparisons. + """ + cdef size_t dict_size = tree.xmlDictSize(doc._c_doc.dict) + if doc is self._cached_doc and dict_size == self._cached_size: + # doc and dict didn't change => names already cached + return 0 + self._tag_count = 0 + if not self._py_tags: + self._cached_doc = doc + self._cached_size = dict_size + return 0 + if not self._cached_tags: + self._cached_tags = python.lxml_malloc(len(self._py_tags), sizeof(qname)) + if not self._cached_tags: + self._cached_doc = None + raise MemoryError() + self._tag_count = _mapTagsToQnameMatchArray( + doc._c_doc, self._py_tags, self._cached_tags, force_into_dict) + self._cached_doc = doc + self._cached_size = dict_size + return 0 + + cdef inline bint matches(self, xmlNode* c_node): + cdef qname* c_qname + if self._node_types & (1 << c_node.type): + return True + elif c_node.type == tree.XML_ELEMENT_NODE: + for c_qname in self._cached_tags[:self._tag_count]: + if _tagMatchesExactly(c_node, c_qname): + return True + return False + + cdef inline bint matchesNsTag(self, const_xmlChar* c_href, + const_xmlChar* c_name): + cdef qname* c_qname + if self._node_types & (1 << tree.XML_ELEMENT_NODE): + return True + for c_qname in self._cached_tags[:self._tag_count]: + if _nsTagMatchesExactly(c_href, c_name, c_qname): + return True + return False + + cdef inline bint matchesAttribute(self, xmlAttr* c_attr): + """Attribute matches differ from Element matches in that they do + not care about node types. + """ + cdef qname* c_qname + for c_qname in self._cached_tags[:self._tag_count]: + if _tagMatchesExactly(c_attr, c_qname): + return True + return False + +cdef class _ElementMatchIterator: + cdef _Element _node + cdef _node_to_node_function _next_element + cdef _MultiTagMatcher _matcher + + @cython.final + cdef _initTagMatcher(self, tags): + self._matcher = _MultiTagMatcher.__new__(_MultiTagMatcher, tags) + + def __iter__(self): + return self + + @cython.final + cdef int _storeNext(self, _Element node) except -1: + self._matcher.cacheTags(node._doc) + c_node = self._next_element(node._c_node) + while c_node is not NULL and not self._matcher.matches(c_node): + c_node = self._next_element(c_node) + # store Python ref to next node to make sure it's kept alive + self._node = _elementFactory(node._doc, c_node) if c_node is not NULL else None + return 0 + + def __next__(self): + cdef _Element current_node = self._node + if current_node is None: + raise StopIteration + self._storeNext(current_node) + return current_node + +cdef class ElementChildIterator(_ElementMatchIterator): + u"""ElementChildIterator(self, node, tag=None, reversed=False) + Iterates over the children of an element. + """ + def __cinit__(self, _Element node not None, tag=None, *, bint reversed=False): + cdef xmlNode* c_node + _assertValidNode(node) + self._initTagMatcher(tag) + if reversed: + c_node = _findChildBackwards(node._c_node, 0) + self._next_element = _previousElement + else: + c_node = _findChildForwards(node._c_node, 0) + self._next_element = _nextElement + self._matcher.cacheTags(node._doc) + while c_node is not NULL and not self._matcher.matches(c_node): + c_node = self._next_element(c_node) + # store Python ref to next node to make sure it's kept alive + self._node = _elementFactory(node._doc, c_node) if c_node is not NULL else None + +cdef class SiblingsIterator(_ElementMatchIterator): + u"""SiblingsIterator(self, node, tag=None, preceding=False) + Iterates over the siblings of an element. + + You can pass the boolean keyword ``preceding`` to specify the direction. + """ + def __cinit__(self, _Element node not None, tag=None, *, bint preceding=False): + _assertValidNode(node) + self._initTagMatcher(tag) + if preceding: + self._next_element = _previousElement + else: + self._next_element = _nextElement + self._storeNext(node) + +cdef class AncestorsIterator(_ElementMatchIterator): + u"""AncestorsIterator(self, node, tag=None) + Iterates over the ancestors of an element (from parent to parent). + """ + def __cinit__(self, _Element node not None, tag=None): + _assertValidNode(node) + self._initTagMatcher(tag) + self._next_element = _parentElement + self._storeNext(node) + +cdef class ElementDepthFirstIterator: + u"""ElementDepthFirstIterator(self, node, tag=None, inclusive=True) + Iterates over an element and its sub-elements in document order (depth + first pre-order). + + Note that this also includes comments, entities and processing + instructions. To filter them out, check if the ``tag`` property + of the returned element is a string (i.e. not None and not a + factory function), or pass the ``Element`` factory for the ``tag`` + argument to receive only Elements. + + If the optional ``tag`` argument is not None, the iterator returns only + the elements that match the respective name and namespace. + + The optional boolean argument 'inclusive' defaults to True and can be set + to False to exclude the start element itself. + + Note that the behaviour of this iterator is completely undefined if the + tree it traverses is modified during iteration. + """ + # we keep Python references here to control GC + # keep the next Element after the one we return, and the (s)top node + cdef _Element _next_node + cdef _Element _top_node + cdef _MultiTagMatcher _matcher + def __cinit__(self, _Element node not None, tag=None, *, bint inclusive=True): + _assertValidNode(node) + self._top_node = node + self._next_node = node + self._matcher = _MultiTagMatcher.__new__(_MultiTagMatcher, tag) + self._matcher.cacheTags(node._doc) + if not inclusive or not self._matcher.matches(node._c_node): + # find start node (this cannot raise StopIteration, self._next_node != None) + next(self) + + def __iter__(self): + return self + + def __next__(self): + cdef xmlNode* c_node + cdef _Element current_node = self._next_node + if current_node is None: + raise StopIteration + c_node = current_node._c_node + self._matcher.cacheTags(current_node._doc) + if not self._matcher._tag_count: + # no tag name was found in the dict => not in document either + # try to match by node type + c_node = self._nextNodeAnyTag(c_node) + else: + c_node = self._nextNodeMatchTag(c_node) + if c_node is NULL: + self._next_node = None + else: + self._next_node = _elementFactory(current_node._doc, c_node) + return current_node + + @cython.final + cdef xmlNode* _nextNodeAnyTag(self, xmlNode* c_node): + cdef int node_types = self._matcher._node_types + if not node_types: + return NULL + tree.BEGIN_FOR_EACH_ELEMENT_FROM(self._top_node._c_node, c_node, 0) + if node_types & (1 << c_node.type): + return c_node + tree.END_FOR_EACH_ELEMENT_FROM(c_node) + return NULL + + @cython.final + cdef xmlNode* _nextNodeMatchTag(self, xmlNode* c_node): + tree.BEGIN_FOR_EACH_ELEMENT_FROM(self._top_node._c_node, c_node, 0) + if self._matcher.matches(c_node): + return c_node + tree.END_FOR_EACH_ELEMENT_FROM(c_node) + return NULL + +cdef class ElementTextIterator: + u"""ElementTextIterator(self, element, tag=None, with_tail=True) + Iterates over the text content of a subtree. + + You can pass the ``tag`` keyword argument to restrict text content to a + specific tag name. + + You can set the ``with_tail`` keyword argument to ``False`` to skip over + tail text (e.g. if you know that it's only whitespace from pretty-printing). + """ + cdef object _events + cdef _Element _start_element + def __cinit__(self, _Element element not None, tag=None, *, bint with_tail=True): + _assertValidNode(element) + if with_tail: + events = (u"start", u"comment", u"pi", u"end") + else: + events = (u"start", u"comment", u"pi") + self._start_element = element + self._events = iterwalk(element, events=events, tag=tag) + + def __iter__(self): + return self + + def __next__(self): + cdef _Element element + result = None + while result is None: + event, element = next(self._events) # raises StopIteration + if event == u"start": + result = element.text + elif element is not self._start_element: + result = element.tail + return result + +cdef xmlNode* _createElement(xmlDoc* c_doc, object name_utf) except NULL: + cdef xmlNode* c_node + c_node = tree.xmlNewDocNode(c_doc, NULL, _xcstr(name_utf), NULL) + return c_node + +cdef xmlNode* _createComment(xmlDoc* c_doc, const_xmlChar* text): + cdef xmlNode* c_node + c_node = tree.xmlNewDocComment(c_doc, text) + return c_node + +cdef xmlNode* _createPI(xmlDoc* c_doc, const_xmlChar* target, const_xmlChar* text): + cdef xmlNode* c_node + c_node = tree.xmlNewDocPI(c_doc, target, text) + return c_node + +cdef xmlNode* _createEntity(xmlDoc* c_doc, const_xmlChar* name): + cdef xmlNode* c_node + c_node = tree.xmlNewReference(c_doc, name) + return c_node + +# module-level API for ElementTree + +def Element(_tag, attrib=None, nsmap=None, **_extra): + u"""Element(_tag, attrib=None, nsmap=None, **_extra) + + Element factory. This function returns an object implementing the + Element interface. + + Also look at the `_Element.makeelement()` and + `_BaseParser.makeelement()` methods, which provide a faster way to + create an Element within a specific document or parser context. + """ + return _makeElement(_tag, NULL, None, None, None, None, + attrib, nsmap, _extra) + + +def Comment(text=None): + u"""Comment(text=None) + + Comment element factory. This factory function creates a special element that will + be serialized as an XML comment. + """ + cdef _Document doc + cdef xmlNode* c_node + cdef xmlDoc* c_doc + + if text is None: + text = b'' + else: + text = _utf8(text) + if b'--' in text or text.endswith(b'-'): + raise ValueError("Comment may not contain '--' or end with '-'") + + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + c_node = _createComment(c_doc, _xcstr(text)) + tree.xmlAddChild(c_doc, c_node) + return _elementFactory(doc, c_node) + + +def ProcessingInstruction(target, text=None): + u"""ProcessingInstruction(target, text=None) + + ProcessingInstruction element factory. This factory function creates a + special element that will be serialized as an XML processing instruction. + """ + cdef _Document doc + cdef xmlNode* c_node + cdef xmlDoc* c_doc + + target = _utf8(target) + _tagValidOrRaise(target) + if target.lower() == b'xml': + raise ValueError, f"Invalid PI name '{target}'" + + if text is None: + text = b'' + else: + text = _utf8(text) + if b'?>' in text: + raise ValueError, "PI text must not contain '?>'" + + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + c_node = _createPI(c_doc, _xcstr(target), _xcstr(text)) + tree.xmlAddChild(c_doc, c_node) + return _elementFactory(doc, c_node) + +PI = ProcessingInstruction + + +cdef class CDATA: + u"""CDATA(data) + + CDATA factory. This factory creates an opaque data object that + can be used to set Element text. The usual way to use it is:: + + >>> el = Element('content') + >>> el.text = CDATA('a string') + + >>> print(el.text) + a string + >>> print(tostring(el, encoding="unicode")) + + """ + cdef bytes _utf8_data + def __cinit__(self, data): + _utf8_data = _utf8(data) + if b']]>' in _utf8_data: + raise ValueError, "']]>' not allowed inside CDATA" + self._utf8_data = _utf8_data + + +def Entity(name): + u"""Entity(name) + + Entity factory. This factory function creates a special element + that will be serialized as an XML entity reference or character + reference. Note, however, that entities will not be automatically + declared in the document. A document that uses entity references + requires a DTD to define the entities. + """ + cdef _Document doc + cdef xmlNode* c_node + cdef xmlDoc* c_doc + name_utf = _utf8(name) + c_name = _xcstr(name_utf) + if c_name[0] == c'#': + if not _characterReferenceIsValid(c_name + 1): + raise ValueError, f"Invalid character reference: '{name}'" + elif not _xmlNameIsValid(c_name): + raise ValueError, f"Invalid entity reference: '{name}'" + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, None) + c_node = _createEntity(c_doc, c_name) + tree.xmlAddChild(c_doc, c_node) + return _elementFactory(doc, c_node) + + +def SubElement(_Element _parent not None, _tag, + attrib=None, nsmap=None, **_extra): + u"""SubElement(_parent, _tag, attrib=None, nsmap=None, **_extra) + + Subelement factory. This function creates an element instance, and + appends it to an existing element. + """ + return _makeSubElement(_parent, _tag, None, None, attrib, nsmap, _extra) + + +def ElementTree(_Element element=None, *, file=None, _BaseParser parser=None): + u"""ElementTree(element=None, file=None, parser=None) + + ElementTree wrapper class. + """ + cdef xmlNode* c_next + cdef xmlNode* c_node + cdef xmlNode* c_node_copy + cdef xmlDoc* c_doc + cdef _ElementTree etree + cdef _Document doc + + if element is not None: + doc = element._doc + elif file is not None: + try: + doc = _parseDocument(file, parser, None) + except _TargetParserResult as result_container: + return result_container.result + else: + c_doc = _newXMLDoc() + doc = _documentFactory(c_doc, parser) + + return _elementTreeFactory(doc, element) + + +def HTML(text, _BaseParser parser=None, *, base_url=None): + u"""HTML(text, parser=None, base_url=None) + + Parses an HTML document from a string constant. Returns the root + node (or the result returned by a parser target). This function + can be used to embed "HTML literals" in Python code. + + To override the parser with a different ``HTMLParser`` you can pass it to + the ``parser`` keyword argument. + + The ``base_url`` keyword argument allows to set the original base URL of + the document to support relative Paths when looking up external entities + (DTD, XInclude, ...). + """ + cdef _Document doc + if parser is None: + parser = __GLOBAL_PARSER_CONTEXT.getDefaultParser() + if not isinstance(parser, HTMLParser): + parser = __DEFAULT_HTML_PARSER + try: + doc = _parseMemoryDocument(text, base_url, parser) + return doc.getroot() + except _TargetParserResult as result_container: + return result_container.result + + +def XML(text, _BaseParser parser=None, *, base_url=None): + u"""XML(text, parser=None, base_url=None) + + Parses an XML document or fragment from a string constant. + Returns the root node (or the result returned by a parser target). + This function can be used to embed "XML literals" in Python code, + like in + + >>> root = XML("") + >>> print(root.tag) + root + + To override the parser with a different ``XMLParser`` you can pass it to + the ``parser`` keyword argument. + + The ``base_url`` keyword argument allows to set the original base URL of + the document to support relative Paths when looking up external entities + (DTD, XInclude, ...). + """ + cdef _Document doc + if parser is None: + parser = __GLOBAL_PARSER_CONTEXT.getDefaultParser() + if not isinstance(parser, XMLParser): + parser = __DEFAULT_XML_PARSER + try: + doc = _parseMemoryDocument(text, base_url, parser) + return doc.getroot() + except _TargetParserResult as result_container: + return result_container.result + + +def fromstring(text, _BaseParser parser=None, *, base_url=None): + u"""fromstring(text, parser=None, base_url=None) + + Parses an XML document or fragment from a string. Returns the + root node (or the result returned by a parser target). + + To override the default parser with a different parser you can pass it to + the ``parser`` keyword argument. + + The ``base_url`` keyword argument allows to set the original base URL of + the document to support relative Paths when looking up external entities + (DTD, XInclude, ...). + """ + cdef _Document doc + try: + doc = _parseMemoryDocument(text, base_url, parser) + return doc.getroot() + except _TargetParserResult as result_container: + return result_container.result + + +def fromstringlist(strings, _BaseParser parser=None): + u"""fromstringlist(strings, parser=None) + + Parses an XML document from a sequence of strings. Returns the + root node (or the result returned by a parser target). + + To override the default parser with a different parser you can pass it to + the ``parser`` keyword argument. + """ + cdef _Document doc + if isinstance(strings, (bytes, unicode)): + raise ValueError("passing a single string into fromstringlist() is not" + " efficient, use fromstring() instead") + if parser is None: + parser = __GLOBAL_PARSER_CONTEXT.getDefaultParser() + feed = parser.feed + for data in strings: + feed(data) + return parser.close() + + +def iselement(element): + u"""iselement(element) + + Checks if an object appears to be a valid element object. + """ + return isinstance(element, _Element) and (<_Element>element)._c_node is not NULL + + +def indent(tree, space=" ", *, Py_ssize_t level=0): + """indent(tree, space=" ", level=0) + + Indent an XML document by inserting newlines and indentation space + after elements. + + *tree* is the ElementTree or Element to modify. The (root) element + itself will not be changed, but the tail text of all elements in its + subtree will be adapted. + + *space* is the whitespace to insert for each indentation level, two + space characters by default. + + *level* is the initial indentation level. Setting this to a higher + value than 0 can be used for indenting subtrees that are more deeply + nested inside of a document. + """ + root = _rootNodeOrRaise(tree) + if level < 0: + raise ValueError(f"Initial indentation level must be >= 0, got {level}") + if _hasChild(root._c_node): + space = _utf8(space) + indent = b"\n" + level * space + _indent_children(root._c_node, 1, space, [indent, indent + space]) + + +cdef int _indent_children(xmlNode* c_node, Py_ssize_t level, bytes one_space, list indentations) except -1: + # Reuse indentation strings for speed. + if len(indentations) <= level: + indentations.append(indentations[-1] + one_space) + + # Start a new indentation level for the first child. + child_indentation = indentations[level] + if not _hasNonWhitespaceText(c_node): + _setNodeText(c_node, child_indentation) + + # Recursively indent all children. + cdef xmlNode* c_child = _findChildForwards(c_node, 0) + while c_child is not NULL: + if _hasChild(c_child): + _indent_children(c_child, level+1, one_space, indentations) + c_next_child = _nextElement(c_child) + if not _hasNonWhitespaceTail(c_child): + if c_next_child is NULL: + # Dedent after the last child. + child_indentation = indentations[level-1] + _setTailText(c_child, child_indentation) + c_child = c_next_child + return 0 + + +def dump(_Element elem not None, *, bint pretty_print=True, with_tail=True): + u"""dump(elem, pretty_print=True, with_tail=True) + + Writes an element tree or element structure to sys.stdout. This function + should be used for debugging only. + """ + xml = tostring(elem, pretty_print=pretty_print, with_tail=with_tail, + encoding=None if python.IS_PYTHON2 else 'unicode') + if not pretty_print: + xml += '\n' + sys.stdout.write(xml) + + +def tostring(element_or_tree, *, encoding=None, method="xml", + xml_declaration=None, bint pretty_print=False, bint with_tail=True, + standalone=None, doctype=None, + # method='c14n' + bint exclusive=False, inclusive_ns_prefixes=None, + # method='c14n2' + bint with_comments=True, bint strip_text=False, + ): + u"""tostring(element_or_tree, encoding=None, method="xml", + xml_declaration=None, pretty_print=False, with_tail=True, + standalone=None, doctype=None, + exclusive=False, inclusive_ns_prefixes=None, + with_comments=True, strip_text=False, + ) + + Serialize an element to an encoded string representation of its XML + tree. + + Defaults to ASCII encoding without XML declaration. This + behaviour can be configured with the keyword arguments 'encoding' + (string) and 'xml_declaration' (bool). Note that changing the + encoding to a non UTF-8 compatible encoding will enable a + declaration by default. + + You can also serialise to a Unicode string without declaration by + passing the name ``'unicode'`` as encoding (or the ``str`` function + in Py3 or ``unicode`` in Py2). This changes the return value from + a byte string to an unencoded unicode string. + + The keyword argument 'pretty_print' (bool) enables formatted XML. + + The keyword argument 'method' selects the output method: 'xml', + 'html', plain 'text' (text content without tags), 'c14n' or 'c14n2'. + Default is 'xml'. + + With ``method="c14n"`` (C14N version 1), the options ``exclusive``, + ``with_comments`` and ``inclusive_ns_prefixes`` request exclusive + C14N, include comments, and list the inclusive prefixes respectively. + + With ``method="c14n2"`` (C14N version 2), the ``with_comments`` and + ``strip_text`` options control the output of comments and text space + according to C14N 2.0. + + Passing a boolean value to the ``standalone`` option will output + an XML declaration with the corresponding ``standalone`` flag. + + The ``doctype`` option allows passing in a plain string that will + be serialised before the XML tree. Note that passing in non + well-formed content here will make the XML output non well-formed. + Also, an existing doctype in the document tree will not be removed + when serialising an ElementTree instance. + + You can prevent the tail text of the element from being serialised + by passing the boolean ``with_tail`` option. This has no impact + on the tail text of children, which will always be serialised. + """ + cdef bint write_declaration + cdef int is_standalone + # C14N serialisation + if method in ('c14n', 'c14n2'): + if encoding is not None: + raise ValueError("Cannot specify encoding with C14N") + if xml_declaration: + raise ValueError("Cannot enable XML declaration in C14N") + if method == 'c14n': + return _tostringC14N(element_or_tree, exclusive, with_comments, inclusive_ns_prefixes) + else: + out = BytesIO() + target = C14NWriterTarget( + utf8_writer(out).write, + with_comments=with_comments, strip_text=strip_text) + _tree_to_target(element_or_tree, target) + return out.getvalue() + if not with_comments: + raise ValueError("Can only discard comments in C14N serialisation") + if strip_text: + raise ValueError("Can only strip text in C14N 2.0 serialisation") + if encoding is unicode or (encoding is not None and encoding.lower() == 'unicode'): + if xml_declaration: + raise ValueError, \ + u"Serialisation to unicode must not request an XML declaration" + write_declaration = 0 + encoding = unicode + elif xml_declaration is None: + # by default, write an XML declaration only for non-standard encodings + write_declaration = encoding is not None and encoding.upper() not in \ + (u'ASCII', u'UTF-8', u'UTF8', u'US-ASCII') + else: + write_declaration = xml_declaration + if encoding is None: + encoding = u'ASCII' + if standalone is None: + is_standalone = -1 + elif standalone: + write_declaration = 1 + is_standalone = 1 + else: + write_declaration = 1 + is_standalone = 0 + + if isinstance(element_or_tree, _Element): + return _tostring(<_Element>element_or_tree, encoding, doctype, method, + write_declaration, 0, pretty_print, with_tail, + is_standalone) + elif isinstance(element_or_tree, _ElementTree): + return _tostring((<_ElementTree>element_or_tree)._context_node, + encoding, doctype, method, write_declaration, 1, + pretty_print, with_tail, is_standalone) + else: + raise TypeError, f"Type '{python._fqtypename(element_or_tree).decode('utf8')}' cannot be serialized." + + + +def tostringlist(element_or_tree, *args, **kwargs): + u"""tostringlist(element_or_tree, *args, **kwargs) + + Serialize an element to an encoded string representation of its XML + tree, stored in a list of partial strings. + + This is purely for ElementTree 1.3 compatibility. The result is a + single string wrapped in a list. + """ + return [tostring(element_or_tree, *args, **kwargs)] + + +def tounicode(element_or_tree, *, method=u"xml", bint pretty_print=False, + bint with_tail=True, doctype=None): + u"""tounicode(element_or_tree, method="xml", pretty_print=False, + with_tail=True, doctype=None) + + Serialize an element to the Python unicode representation of its XML + tree. + + :deprecated: use ``tostring(el, encoding='unicode')`` instead. + + Note that the result does not carry an XML encoding declaration and is + therefore not necessarily suited for serialization to byte streams without + further treatment. + + The boolean keyword argument 'pretty_print' enables formatted XML. + + The keyword argument 'method' selects the output method: 'xml', + 'html' or plain 'text'. + + You can prevent the tail text of the element from being serialised + by passing the boolean ``with_tail`` option. This has no impact + on the tail text of children, which will always be serialised. + """ + if isinstance(element_or_tree, _Element): + return _tostring(<_Element>element_or_tree, unicode, doctype, method, + 0, 0, pretty_print, with_tail, -1) + elif isinstance(element_or_tree, _ElementTree): + return _tostring((<_ElementTree>element_or_tree)._context_node, + unicode, doctype, method, 0, 1, pretty_print, + with_tail, -1) + else: + raise TypeError, f"Type '{type(element_or_tree)}' cannot be serialized." + + +def parse(source, _BaseParser parser=None, *, base_url=None): + u"""parse(source, parser=None, base_url=None) + + Return an ElementTree object loaded with source elements. If no parser + is provided as second argument, the default parser is used. + + The ``source`` can be any of the following: + + - a file name/path + - a file object + - a file-like object + - a URL using the HTTP or FTP protocol + + To parse from a string, use the ``fromstring()`` function instead. + + Note that it is generally faster to parse from a file path or URL + than from an open file object or file-like object. Transparent + decompression from gzip compressed sources is supported (unless + explicitly disabled in libxml2). + + The ``base_url`` keyword allows setting a URL for the document + when parsing from a file-like object. This is needed when looking + up external entities (DTD, XInclude, ...) with relative paths. + """ + cdef _Document doc + try: + doc = _parseDocument(source, parser, base_url) + return _elementTreeFactory(doc, None) + except _TargetParserResult as result_container: + return result_container.result + + +def adopt_external_document(capsule, _BaseParser parser=None): + """adopt_external_document(capsule, parser=None) + + Unpack a libxml2 document pointer from a PyCapsule and wrap it in an + lxml ElementTree object. + + This allows external libraries to build XML/HTML trees using libxml2 + and then pass them efficiently into lxml for further processing. + + If a ``parser`` is provided, it will be used for configuring the + lxml document. No parsing will be done. + + The capsule must have the name ``"libxml2:xmlDoc"`` and its pointer + value must reference a correct libxml2 document of type ``xmlDoc*``. + The creator of the capsule must take care to correctly clean up the + document using an appropriate capsule destructor. By default, the + libxml2 document will be copied to let lxml safely own the memory + of the internal tree that it uses. + + If the capsule context is non-NULL, it must point to a C string that + can be compared using ``strcmp()``. If the context string equals + ``"destructor:xmlFreeDoc"``, the libxml2 document will not be copied + but the capsule invalidated instead by clearing its destructor and + name. That way, lxml takes ownership of the libxml2 document in memory + without creating a copy first, and the capsule destructor will not be + called. The document will then eventually be cleaned up by lxml using + the libxml2 API function ``xmlFreeDoc()`` once it is no longer used. + + If no copy is made, later modifications of the tree outside of lxml + should not be attempted after transferring the ownership. + """ + cdef xmlDoc* c_doc + cdef bint is_owned = False + c_doc = python.lxml_unpack_xmldoc_capsule(capsule, &is_owned) + doc = _adoptForeignDoc(c_doc, parser, is_owned) + return _elementTreeFactory(doc, None) + + +################################################################################ +# Include submodules + +include "readonlytree.pxi" # Read-only implementation of Element proxies +include "classlookup.pxi" # Element class lookup mechanisms +include "nsclasses.pxi" # Namespace implementation and registry +include "docloader.pxi" # Support for custom document loaders +include "parser.pxi" # XML and HTML parsers +include "saxparser.pxi" # SAX-like Parser interface and tree builder +include "parsertarget.pxi" # ET Parser target +include "serializer.pxi" # XML output functions +include "iterparse.pxi" # incremental XML parsing +include "xmlid.pxi" # XMLID and IDDict +include "xinclude.pxi" # XInclude +include "cleanup.pxi" # Cleanup and recursive element removal functions + + +################################################################################ +# Include submodules for XPath and XSLT + +include "extensions.pxi" # XPath/XSLT extension functions +include "xpath.pxi" # XPath evaluation +include "xslt.pxi" # XSL transformations +include "xsltext.pxi" # XSL extension elements + + +################################################################################ +# Validation + +cdef class DocumentInvalid(LxmlError): + """Validation error. + + Raised by all document validators when their ``assertValid(tree)`` + method fails. + """ + + +cdef class _Validator: + u"Base class for XML validators." + cdef _ErrorLog _error_log + def __cinit__(self): + self._error_log = _ErrorLog() + + def validate(self, etree): + u"""validate(self, etree) + + Validate the document using this schema. + + Returns true if document is valid, false if not. + """ + return self(etree) + + def assertValid(self, etree): + u"""assertValid(self, etree) + + Raises `DocumentInvalid` if the document does not comply with the schema. + """ + if not self(etree): + raise DocumentInvalid(self._error_log._buildExceptionMessage( + u"Document does not comply with schema"), + self._error_log) + + def assert_(self, etree): + u"""assert_(self, etree) + + Raises `AssertionError` if the document does not comply with the schema. + """ + if not self(etree): + raise AssertionError, self._error_log._buildExceptionMessage( + u"Document does not comply with schema") + + cpdef _append_log_message(self, int domain, int type, int level, int line, + message, filename): + self._error_log._receiveGeneric(domain, type, level, line, message, + filename) + + cpdef _clear_error_log(self): + self._error_log.clear() + + @property + def error_log(self): + """The log of validation errors and warnings.""" + assert self._error_log is not None, "XPath evaluator not initialised" + return self._error_log.copy() + +include "dtd.pxi" # DTD +include "relaxng.pxi" # RelaxNG +include "xmlschema.pxi" # XMLSchema +include "schematron.pxi" # Schematron (requires libxml2 2.6.21+) + +################################################################################ +# Public C API + +include "public-api.pxi" + +################################################################################ +# Other stuff + +include "debug.pxi" diff --git a/.venv/lib/python3.7/site-packages/lxml/etree_api.h b/.venv/lib/python3.7/site-packages/lxml/etree_api.h new file mode 100644 index 0000000..9372f62 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/etree_api.h @@ -0,0 +1,219 @@ +/* Generated by Cython 0.29.36 */ + +#ifndef __PYX_HAVE_API__lxml__etree +#define __PYX_HAVE_API__lxml__etree +#ifdef __MINGW64__ +#define MS_WIN64 +#endif +#include "Python.h" +#include "etree.h" + +static struct LxmlElement *(*__pyx_api_f_4lxml_5etree_deepcopyNodeToDocument)(struct LxmlDocument *, xmlNode *) = 0; +#define deepcopyNodeToDocument __pyx_api_f_4lxml_5etree_deepcopyNodeToDocument +static struct LxmlElementTree *(*__pyx_api_f_4lxml_5etree_elementTreeFactory)(struct LxmlElement *) = 0; +#define elementTreeFactory __pyx_api_f_4lxml_5etree_elementTreeFactory +static struct LxmlElementTree *(*__pyx_api_f_4lxml_5etree_newElementTree)(struct LxmlElement *, PyObject *) = 0; +#define newElementTree __pyx_api_f_4lxml_5etree_newElementTree +static struct LxmlElementTree *(*__pyx_api_f_4lxml_5etree_adoptExternalDocument)(xmlDoc *, PyObject *, int) = 0; +#define adoptExternalDocument __pyx_api_f_4lxml_5etree_adoptExternalDocument +static struct LxmlElement *(*__pyx_api_f_4lxml_5etree_elementFactory)(struct LxmlDocument *, xmlNode *) = 0; +#define elementFactory __pyx_api_f_4lxml_5etree_elementFactory +static struct LxmlElement *(*__pyx_api_f_4lxml_5etree_makeElement)(PyObject *, struct LxmlDocument *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *) = 0; +#define makeElement __pyx_api_f_4lxml_5etree_makeElement +static struct LxmlElement *(*__pyx_api_f_4lxml_5etree_makeSubElement)(struct LxmlElement *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *) = 0; +#define makeSubElement __pyx_api_f_4lxml_5etree_makeSubElement +static void (*__pyx_api_f_4lxml_5etree_setElementClassLookupFunction)(_element_class_lookup_function, PyObject *) = 0; +#define setElementClassLookupFunction __pyx_api_f_4lxml_5etree_setElementClassLookupFunction +static PyObject *(*__pyx_api_f_4lxml_5etree_lookupDefaultElementClass)(PyObject *, PyObject *, xmlNode *) = 0; +#define lookupDefaultElementClass __pyx_api_f_4lxml_5etree_lookupDefaultElementClass +static PyObject *(*__pyx_api_f_4lxml_5etree_lookupNamespaceElementClass)(PyObject *, PyObject *, xmlNode *) = 0; +#define lookupNamespaceElementClass __pyx_api_f_4lxml_5etree_lookupNamespaceElementClass +static PyObject *(*__pyx_api_f_4lxml_5etree_callLookupFallback)(struct LxmlFallbackElementClassLookup *, struct LxmlDocument *, xmlNode *) = 0; +#define callLookupFallback __pyx_api_f_4lxml_5etree_callLookupFallback +static int (*__pyx_api_f_4lxml_5etree_tagMatches)(xmlNode *, const xmlChar *, const xmlChar *) = 0; +#define tagMatches __pyx_api_f_4lxml_5etree_tagMatches +static struct LxmlDocument *(*__pyx_api_f_4lxml_5etree_documentOrRaise)(PyObject *) = 0; +#define documentOrRaise __pyx_api_f_4lxml_5etree_documentOrRaise +static struct LxmlElement *(*__pyx_api_f_4lxml_5etree_rootNodeOrRaise)(PyObject *) = 0; +#define rootNodeOrRaise __pyx_api_f_4lxml_5etree_rootNodeOrRaise +static int (*__pyx_api_f_4lxml_5etree_hasText)(xmlNode *) = 0; +#define hasText __pyx_api_f_4lxml_5etree_hasText +static int (*__pyx_api_f_4lxml_5etree_hasTail)(xmlNode *) = 0; +#define hasTail __pyx_api_f_4lxml_5etree_hasTail +static PyObject *(*__pyx_api_f_4lxml_5etree_textOf)(xmlNode *) = 0; +#define textOf __pyx_api_f_4lxml_5etree_textOf +static PyObject *(*__pyx_api_f_4lxml_5etree_tailOf)(xmlNode *) = 0; +#define tailOf __pyx_api_f_4lxml_5etree_tailOf +static int (*__pyx_api_f_4lxml_5etree_setNodeText)(xmlNode *, PyObject *) = 0; +#define setNodeText __pyx_api_f_4lxml_5etree_setNodeText +static int (*__pyx_api_f_4lxml_5etree_setTailText)(xmlNode *, PyObject *) = 0; +#define setTailText __pyx_api_f_4lxml_5etree_setTailText +static PyObject *(*__pyx_api_f_4lxml_5etree_attributeValue)(xmlNode *, xmlAttr *) = 0; +#define attributeValue __pyx_api_f_4lxml_5etree_attributeValue +static PyObject *(*__pyx_api_f_4lxml_5etree_attributeValueFromNsName)(xmlNode *, const xmlChar *, const xmlChar *) = 0; +#define attributeValueFromNsName __pyx_api_f_4lxml_5etree_attributeValueFromNsName +static PyObject *(*__pyx_api_f_4lxml_5etree_getAttributeValue)(struct LxmlElement *, PyObject *, PyObject *) = 0; +#define getAttributeValue __pyx_api_f_4lxml_5etree_getAttributeValue +static PyObject *(*__pyx_api_f_4lxml_5etree_iterattributes)(struct LxmlElement *, int) = 0; +#define iterattributes __pyx_api_f_4lxml_5etree_iterattributes +static PyObject *(*__pyx_api_f_4lxml_5etree_collectAttributes)(xmlNode *, int) = 0; +#define collectAttributes __pyx_api_f_4lxml_5etree_collectAttributes +static int (*__pyx_api_f_4lxml_5etree_setAttributeValue)(struct LxmlElement *, PyObject *, PyObject *) = 0; +#define setAttributeValue __pyx_api_f_4lxml_5etree_setAttributeValue +static int (*__pyx_api_f_4lxml_5etree_delAttribute)(struct LxmlElement *, PyObject *) = 0; +#define delAttribute __pyx_api_f_4lxml_5etree_delAttribute +static int (*__pyx_api_f_4lxml_5etree_delAttributeFromNsName)(xmlNode *, const xmlChar *, const xmlChar *) = 0; +#define delAttributeFromNsName __pyx_api_f_4lxml_5etree_delAttributeFromNsName +static int (*__pyx_api_f_4lxml_5etree_hasChild)(xmlNode *) = 0; +#define hasChild __pyx_api_f_4lxml_5etree_hasChild +static xmlNode *(*__pyx_api_f_4lxml_5etree_findChild)(xmlNode *, Py_ssize_t) = 0; +#define findChild __pyx_api_f_4lxml_5etree_findChild +static xmlNode *(*__pyx_api_f_4lxml_5etree_findChildForwards)(xmlNode *, Py_ssize_t) = 0; +#define findChildForwards __pyx_api_f_4lxml_5etree_findChildForwards +static xmlNode *(*__pyx_api_f_4lxml_5etree_findChildBackwards)(xmlNode *, Py_ssize_t) = 0; +#define findChildBackwards __pyx_api_f_4lxml_5etree_findChildBackwards +static xmlNode *(*__pyx_api_f_4lxml_5etree_nextElement)(xmlNode *) = 0; +#define nextElement __pyx_api_f_4lxml_5etree_nextElement +static xmlNode *(*__pyx_api_f_4lxml_5etree_previousElement)(xmlNode *) = 0; +#define previousElement __pyx_api_f_4lxml_5etree_previousElement +static void (*__pyx_api_f_4lxml_5etree_appendChild)(struct LxmlElement *, struct LxmlElement *) = 0; +#define appendChild __pyx_api_f_4lxml_5etree_appendChild +static int (*__pyx_api_f_4lxml_5etree_appendChildToElement)(struct LxmlElement *, struct LxmlElement *) = 0; +#define appendChildToElement __pyx_api_f_4lxml_5etree_appendChildToElement +static PyObject *(*__pyx_api_f_4lxml_5etree_pyunicode)(const xmlChar *) = 0; +#define pyunicode __pyx_api_f_4lxml_5etree_pyunicode +static PyObject *(*__pyx_api_f_4lxml_5etree_utf8)(PyObject *) = 0; +#define utf8 __pyx_api_f_4lxml_5etree_utf8 +static PyObject *(*__pyx_api_f_4lxml_5etree_getNsTag)(PyObject *) = 0; +#define getNsTag __pyx_api_f_4lxml_5etree_getNsTag +static PyObject *(*__pyx_api_f_4lxml_5etree_getNsTagWithEmptyNs)(PyObject *) = 0; +#define getNsTagWithEmptyNs __pyx_api_f_4lxml_5etree_getNsTagWithEmptyNs +static PyObject *(*__pyx_api_f_4lxml_5etree_namespacedName)(xmlNode *) = 0; +#define namespacedName __pyx_api_f_4lxml_5etree_namespacedName +static PyObject *(*__pyx_api_f_4lxml_5etree_namespacedNameFromNsName)(const xmlChar *, const xmlChar *) = 0; +#define namespacedNameFromNsName __pyx_api_f_4lxml_5etree_namespacedNameFromNsName +static void (*__pyx_api_f_4lxml_5etree_iteratorStoreNext)(struct LxmlElementIterator *, struct LxmlElement *) = 0; +#define iteratorStoreNext __pyx_api_f_4lxml_5etree_iteratorStoreNext +static void (*__pyx_api_f_4lxml_5etree_initTagMatch)(struct LxmlElementTagMatcher *, PyObject *) = 0; +#define initTagMatch __pyx_api_f_4lxml_5etree_initTagMatch +static xmlNs *(*__pyx_api_f_4lxml_5etree_findOrBuildNodeNsPrefix)(struct LxmlDocument *, xmlNode *, const xmlChar *, const xmlChar *) = 0; +#define findOrBuildNodeNsPrefix __pyx_api_f_4lxml_5etree_findOrBuildNodeNsPrefix +#if !defined(__Pyx_PyIdentifier_FromString) +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) +#else + #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) +#endif +#endif + +#ifndef __PYX_HAVE_RT_ImportFunction_0_29_36 +#define __PYX_HAVE_RT_ImportFunction_0_29_36 +static int __Pyx_ImportFunction_0_29_36(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { + PyObject *d = 0; + PyObject *cobj = 0; + union { + void (*fp)(void); + void *p; + } tmp; + d = PyObject_GetAttrString(module, (char *)"__pyx_capi__"); + if (!d) + goto bad; + cobj = PyDict_GetItemString(d, funcname); + if (!cobj) { + PyErr_Format(PyExc_ImportError, + "%.200s does not export expected C function %.200s", + PyModule_GetName(module), funcname); + goto bad; + } +#if PY_VERSION_HEX >= 0x02070000 + if (!PyCapsule_IsValid(cobj, sig)) { + PyErr_Format(PyExc_TypeError, + "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", + PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj)); + goto bad; + } + tmp.p = PyCapsule_GetPointer(cobj, sig); +#else + {const char *desc, *s1, *s2; + desc = (const char *)PyCObject_GetDesc(cobj); + if (!desc) + goto bad; + s1 = desc; s2 = sig; + while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } + if (*s1 != *s2) { + PyErr_Format(PyExc_TypeError, + "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", + PyModule_GetName(module), funcname, sig, desc); + goto bad; + } + tmp.p = PyCObject_AsVoidPtr(cobj);} +#endif + *f = tmp.fp; + if (!(*f)) + goto bad; + Py_DECREF(d); + return 0; +bad: + Py_XDECREF(d); + return -1; +} +#endif + + +static int import_lxml__etree(void) { + PyObject *module = 0; + module = PyImport_ImportModule("lxml.etree"); + if (!module) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "deepcopyNodeToDocument", (void (**)(void))&__pyx_api_f_4lxml_5etree_deepcopyNodeToDocument, "struct LxmlElement *(struct LxmlDocument *, xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "elementTreeFactory", (void (**)(void))&__pyx_api_f_4lxml_5etree_elementTreeFactory, "struct LxmlElementTree *(struct LxmlElement *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "newElementTree", (void (**)(void))&__pyx_api_f_4lxml_5etree_newElementTree, "struct LxmlElementTree *(struct LxmlElement *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "adoptExternalDocument", (void (**)(void))&__pyx_api_f_4lxml_5etree_adoptExternalDocument, "struct LxmlElementTree *(xmlDoc *, PyObject *, int)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "elementFactory", (void (**)(void))&__pyx_api_f_4lxml_5etree_elementFactory, "struct LxmlElement *(struct LxmlDocument *, xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "makeElement", (void (**)(void))&__pyx_api_f_4lxml_5etree_makeElement, "struct LxmlElement *(PyObject *, struct LxmlDocument *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "makeSubElement", (void (**)(void))&__pyx_api_f_4lxml_5etree_makeSubElement, "struct LxmlElement *(struct LxmlElement *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "setElementClassLookupFunction", (void (**)(void))&__pyx_api_f_4lxml_5etree_setElementClassLookupFunction, "void (_element_class_lookup_function, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "lookupDefaultElementClass", (void (**)(void))&__pyx_api_f_4lxml_5etree_lookupDefaultElementClass, "PyObject *(PyObject *, PyObject *, xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "lookupNamespaceElementClass", (void (**)(void))&__pyx_api_f_4lxml_5etree_lookupNamespaceElementClass, "PyObject *(PyObject *, PyObject *, xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "callLookupFallback", (void (**)(void))&__pyx_api_f_4lxml_5etree_callLookupFallback, "PyObject *(struct LxmlFallbackElementClassLookup *, struct LxmlDocument *, xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "tagMatches", (void (**)(void))&__pyx_api_f_4lxml_5etree_tagMatches, "int (xmlNode *, const xmlChar *, const xmlChar *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "documentOrRaise", (void (**)(void))&__pyx_api_f_4lxml_5etree_documentOrRaise, "struct LxmlDocument *(PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "rootNodeOrRaise", (void (**)(void))&__pyx_api_f_4lxml_5etree_rootNodeOrRaise, "struct LxmlElement *(PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "hasText", (void (**)(void))&__pyx_api_f_4lxml_5etree_hasText, "int (xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "hasTail", (void (**)(void))&__pyx_api_f_4lxml_5etree_hasTail, "int (xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "textOf", (void (**)(void))&__pyx_api_f_4lxml_5etree_textOf, "PyObject *(xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "tailOf", (void (**)(void))&__pyx_api_f_4lxml_5etree_tailOf, "PyObject *(xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "setNodeText", (void (**)(void))&__pyx_api_f_4lxml_5etree_setNodeText, "int (xmlNode *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "setTailText", (void (**)(void))&__pyx_api_f_4lxml_5etree_setTailText, "int (xmlNode *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "attributeValue", (void (**)(void))&__pyx_api_f_4lxml_5etree_attributeValue, "PyObject *(xmlNode *, xmlAttr *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "attributeValueFromNsName", (void (**)(void))&__pyx_api_f_4lxml_5etree_attributeValueFromNsName, "PyObject *(xmlNode *, const xmlChar *, const xmlChar *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "getAttributeValue", (void (**)(void))&__pyx_api_f_4lxml_5etree_getAttributeValue, "PyObject *(struct LxmlElement *, PyObject *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "iterattributes", (void (**)(void))&__pyx_api_f_4lxml_5etree_iterattributes, "PyObject *(struct LxmlElement *, int)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "collectAttributes", (void (**)(void))&__pyx_api_f_4lxml_5etree_collectAttributes, "PyObject *(xmlNode *, int)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "setAttributeValue", (void (**)(void))&__pyx_api_f_4lxml_5etree_setAttributeValue, "int (struct LxmlElement *, PyObject *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "delAttribute", (void (**)(void))&__pyx_api_f_4lxml_5etree_delAttribute, "int (struct LxmlElement *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "delAttributeFromNsName", (void (**)(void))&__pyx_api_f_4lxml_5etree_delAttributeFromNsName, "int (xmlNode *, const xmlChar *, const xmlChar *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "hasChild", (void (**)(void))&__pyx_api_f_4lxml_5etree_hasChild, "int (xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "findChild", (void (**)(void))&__pyx_api_f_4lxml_5etree_findChild, "xmlNode *(xmlNode *, Py_ssize_t)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "findChildForwards", (void (**)(void))&__pyx_api_f_4lxml_5etree_findChildForwards, "xmlNode *(xmlNode *, Py_ssize_t)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "findChildBackwards", (void (**)(void))&__pyx_api_f_4lxml_5etree_findChildBackwards, "xmlNode *(xmlNode *, Py_ssize_t)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "nextElement", (void (**)(void))&__pyx_api_f_4lxml_5etree_nextElement, "xmlNode *(xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "previousElement", (void (**)(void))&__pyx_api_f_4lxml_5etree_previousElement, "xmlNode *(xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "appendChild", (void (**)(void))&__pyx_api_f_4lxml_5etree_appendChild, "void (struct LxmlElement *, struct LxmlElement *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "appendChildToElement", (void (**)(void))&__pyx_api_f_4lxml_5etree_appendChildToElement, "int (struct LxmlElement *, struct LxmlElement *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "pyunicode", (void (**)(void))&__pyx_api_f_4lxml_5etree_pyunicode, "PyObject *(const xmlChar *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "utf8", (void (**)(void))&__pyx_api_f_4lxml_5etree_utf8, "PyObject *(PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "getNsTag", (void (**)(void))&__pyx_api_f_4lxml_5etree_getNsTag, "PyObject *(PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "getNsTagWithEmptyNs", (void (**)(void))&__pyx_api_f_4lxml_5etree_getNsTagWithEmptyNs, "PyObject *(PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "namespacedName", (void (**)(void))&__pyx_api_f_4lxml_5etree_namespacedName, "PyObject *(xmlNode *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "namespacedNameFromNsName", (void (**)(void))&__pyx_api_f_4lxml_5etree_namespacedNameFromNsName, "PyObject *(const xmlChar *, const xmlChar *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "iteratorStoreNext", (void (**)(void))&__pyx_api_f_4lxml_5etree_iteratorStoreNext, "void (struct LxmlElementIterator *, struct LxmlElement *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "initTagMatch", (void (**)(void))&__pyx_api_f_4lxml_5etree_initTagMatch, "void (struct LxmlElementTagMatcher *, PyObject *)") < 0) goto bad; + if (__Pyx_ImportFunction_0_29_36(module, "findOrBuildNodeNsPrefix", (void (**)(void))&__pyx_api_f_4lxml_5etree_findOrBuildNodeNsPrefix, "xmlNs *(struct LxmlDocument *, xmlNode *, const xmlChar *, const xmlChar *)") < 0) goto bad; + Py_DECREF(module); module = 0; + return 0; + bad: + Py_XDECREF(module); + return -1; +} + +#endif /* !__PYX_HAVE_API__lxml__etree */ diff --git a/.venv/lib/python3.7/site-packages/lxml/extensions.pxi b/.venv/lib/python3.7/site-packages/lxml/extensions.pxi new file mode 100644 index 0000000..35a321b --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/extensions.pxi @@ -0,0 +1,871 @@ +# support for extension functions in XPath and XSLT + +cdef class XPathError(LxmlError): + """Base class of all XPath errors. + """ + +cdef class XPathEvalError(XPathError): + """Error during XPath evaluation. + """ + +cdef class XPathFunctionError(XPathEvalError): + """Internal error looking up an XPath extension function. + """ + +cdef class XPathResultError(XPathEvalError): + """Error handling an XPath result. + """ + + +# forward declarations + +ctypedef int (*_register_function)(void* ctxt, name_utf, ns_uri_utf) +cdef class _ExsltRegExp + +################################################################################ +# Base class for XSLT and XPath evaluation contexts: functions, namespaces, ... + +@cython.internal +cdef class _BaseContext: + cdef xpath.xmlXPathContext* _xpathCtxt + cdef _Document _doc + cdef dict _extensions + cdef list _namespaces + cdef list _global_namespaces + cdef dict _utf_refs + cdef dict _function_cache + cdef dict _eval_context_dict + cdef bint _build_smart_strings + # for exception handling and temporary reference keeping: + cdef _TempStore _temp_refs + cdef set _temp_documents + cdef _ExceptionContext _exc + cdef _ErrorLog _error_log + + def __cinit__(self): + self._xpathCtxt = NULL + + def __init__(self, namespaces, extensions, error_log, enable_regexp, + build_smart_strings): + cdef _ExsltRegExp _regexp + cdef dict new_extensions + cdef list ns + self._utf_refs = {} + self._global_namespaces = [] + self._function_cache = {} + self._eval_context_dict = None + self._error_log = error_log + + if extensions is not None: + # convert extensions to UTF-8 + if isinstance(extensions, dict): + extensions = (extensions,) + # format: [ {(ns, name):function} ] -> {(ns_utf, name_utf):function} + new_extensions = {} + for extension in extensions: + for (ns_uri, name), function in extension.items(): + if name is None: + raise ValueError, u"extensions must have non empty names" + ns_utf = self._to_utf(ns_uri) + name_utf = self._to_utf(name) + new_extensions[(ns_utf, name_utf)] = function + extensions = new_extensions or None + + if namespaces is not None: + if isinstance(namespaces, dict): + namespaces = namespaces.items() + if namespaces: + ns = [] + for prefix, ns_uri in namespaces: + if prefix is None or not prefix: + raise TypeError, \ + u"empty namespace prefix is not supported in XPath" + if ns_uri is None or not ns_uri: + raise TypeError, \ + u"setting default namespace is not supported in XPath" + prefix_utf = self._to_utf(prefix) + ns_uri_utf = self._to_utf(ns_uri) + ns.append( (prefix_utf, ns_uri_utf) ) + namespaces = ns + else: + namespaces = None + + self._doc = None + self._exc = _ExceptionContext() + self._extensions = extensions + self._namespaces = namespaces + self._temp_refs = _TempStore() + self._temp_documents = set() + self._build_smart_strings = build_smart_strings + + if enable_regexp: + _regexp = _ExsltRegExp() + _regexp._register_in_context(self) + + cdef _BaseContext _copy(self): + cdef _BaseContext context + if self._namespaces is not None: + namespaces = self._namespaces[:] + else: + namespaces = None + context = self.__class__(namespaces, None, self._error_log, False, + self._build_smart_strings) + if self._extensions is not None: + context._extensions = self._extensions.copy() + return context + + cdef bytes _to_utf(self, s): + u"Convert to UTF-8 and keep a reference to the encoded string" + cdef python.PyObject* dict_result + if s is None: + return None + dict_result = python.PyDict_GetItem(self._utf_refs, s) + if dict_result is not NULL: + return dict_result + utf = _utf8(s) + self._utf_refs[s] = utf + if python.IS_PYPY: + # use C level refs, PyPy refs are not enough! + python.Py_INCREF(utf) + return utf + + cdef void _set_xpath_context(self, xpath.xmlXPathContext* xpathCtxt): + self._xpathCtxt = xpathCtxt + xpathCtxt.userData = self + xpathCtxt.error = _receiveXPathError + + @cython.final + cdef _register_context(self, _Document doc): + self._doc = doc + self._exc.clear() + + @cython.final + cdef _cleanup_context(self): + #xpath.xmlXPathRegisteredNsCleanup(self._xpathCtxt) + #self.unregisterGlobalNamespaces() + if python.IS_PYPY: + # clean up double refs in PyPy (see "_to_utf()" method) + for ref in self._utf_refs.itervalues(): + python.Py_DECREF(ref) + self._utf_refs.clear() + self._eval_context_dict = None + self._doc = None + + @cython.final + cdef _release_context(self): + if self._xpathCtxt is not NULL: + self._xpathCtxt.userData = NULL + self._xpathCtxt = NULL + + # namespaces (internal UTF-8 methods with leading '_') + + cdef addNamespace(self, prefix, ns_uri): + cdef list namespaces + if prefix is None: + raise TypeError, u"empty prefix is not supported in XPath" + prefix_utf = self._to_utf(prefix) + ns_uri_utf = self._to_utf(ns_uri) + new_item = (prefix_utf, ns_uri_utf) + if self._namespaces is None: + self._namespaces = [new_item] + else: + namespaces = [] + for item in self._namespaces: + if item[0] == prefix_utf: + item = new_item + new_item = None + namespaces.append(item) + if new_item is not None: + namespaces.append(new_item) + self._namespaces = namespaces + if self._xpathCtxt is not NULL: + xpath.xmlXPathRegisterNs( + self._xpathCtxt, _xcstr(prefix_utf), _xcstr(ns_uri_utf)) + + cdef registerNamespace(self, prefix, ns_uri): + if prefix is None: + raise TypeError, u"empty prefix is not supported in XPath" + prefix_utf = self._to_utf(prefix) + ns_uri_utf = self._to_utf(ns_uri) + self._global_namespaces.append(prefix_utf) + xpath.xmlXPathRegisterNs(self._xpathCtxt, + _xcstr(prefix_utf), _xcstr(ns_uri_utf)) + + cdef registerLocalNamespaces(self): + if self._namespaces is None: + return + for prefix_utf, ns_uri_utf in self._namespaces: + xpath.xmlXPathRegisterNs( + self._xpathCtxt, _xcstr(prefix_utf), _xcstr(ns_uri_utf)) + + cdef registerGlobalNamespaces(self): + cdef list ns_prefixes = _find_all_extension_prefixes() + if python.PyList_GET_SIZE(ns_prefixes) > 0: + for prefix_utf, ns_uri_utf in ns_prefixes: + self._global_namespaces.append(prefix_utf) + xpath.xmlXPathRegisterNs( + self._xpathCtxt, _xcstr(prefix_utf), _xcstr(ns_uri_utf)) + + cdef unregisterGlobalNamespaces(self): + if python.PyList_GET_SIZE(self._global_namespaces) > 0: + for prefix_utf in self._global_namespaces: + xpath.xmlXPathRegisterNs(self._xpathCtxt, + _xcstr(prefix_utf), NULL) + del self._global_namespaces[:] + + cdef void _unregisterNamespace(self, prefix_utf): + xpath.xmlXPathRegisterNs(self._xpathCtxt, + _xcstr(prefix_utf), NULL) + + # extension functions + + cdef int _addLocalExtensionFunction(self, ns_utf, name_utf, function) except -1: + if self._extensions is None: + self._extensions = {} + self._extensions[(ns_utf, name_utf)] = function + return 0 + + cdef registerGlobalFunctions(self, void* ctxt, + _register_function reg_func): + cdef python.PyObject* dict_result + cdef dict d + for ns_utf, ns_functions in __FUNCTION_NAMESPACE_REGISTRIES.iteritems(): + dict_result = python.PyDict_GetItem( + self._function_cache, ns_utf) + if dict_result is not NULL: + d = dict_result + else: + d = {} + self._function_cache[ns_utf] = d + for name_utf, function in ns_functions.iteritems(): + d[name_utf] = function + reg_func(ctxt, name_utf, ns_utf) + + cdef registerLocalFunctions(self, void* ctxt, + _register_function reg_func): + cdef python.PyObject* dict_result + cdef dict d + if self._extensions is None: + return # done + last_ns = None + d = None + for (ns_utf, name_utf), function in self._extensions.iteritems(): + if ns_utf is not last_ns or d is None: + last_ns = ns_utf + dict_result = python.PyDict_GetItem( + self._function_cache, ns_utf) + if dict_result is not NULL: + d = dict_result + else: + d = {} + self._function_cache[ns_utf] = d + d[name_utf] = function + reg_func(ctxt, name_utf, ns_utf) + + cdef unregisterAllFunctions(self, void* ctxt, + _register_function unreg_func): + for ns_utf, functions in self._function_cache.iteritems(): + for name_utf in functions: + unreg_func(ctxt, name_utf, ns_utf) + + cdef unregisterGlobalFunctions(self, void* ctxt, + _register_function unreg_func): + for ns_utf, functions in self._function_cache.items(): + for name_utf in functions: + if self._extensions is None or \ + (ns_utf, name_utf) not in self._extensions: + unreg_func(ctxt, name_utf, ns_utf) + + @cython.final + cdef _find_cached_function(self, const_xmlChar* c_ns_uri, const_xmlChar* c_name): + u"""Lookup an extension function in the cache and return it. + + Parameters: c_ns_uri may be NULL, c_name must not be NULL + """ + cdef python.PyObject* c_dict + cdef python.PyObject* dict_result + c_dict = python.PyDict_GetItem( + self._function_cache, None if c_ns_uri is NULL else c_ns_uri) + if c_dict is not NULL: + dict_result = python.PyDict_GetItem( + c_dict, c_name) + if dict_result is not NULL: + return dict_result + return None + + # Python access to the XPath context for extension functions + + @property + def context_node(self): + cdef xmlNode* c_node + if self._xpathCtxt is NULL: + raise XPathError, \ + u"XPath context is only usable during the evaluation" + c_node = self._xpathCtxt.node + if c_node is NULL: + raise XPathError, u"no context node" + if c_node.doc != self._xpathCtxt.doc: + raise XPathError, \ + u"document-external context nodes are not supported" + if self._doc is None: + raise XPathError, u"document context is missing" + return _elementFactory(self._doc, c_node) + + @property + def eval_context(self): + if self._eval_context_dict is None: + self._eval_context_dict = {} + return self._eval_context_dict + + # Python reference keeping during XPath function evaluation + + @cython.final + cdef _release_temp_refs(self): + u"Free temporarily referenced objects from this context." + self._temp_refs.clear() + self._temp_documents.clear() + + @cython.final + cdef _hold(self, obj): + u"""A way to temporarily hold references to nodes in the evaluator. + + This is needed because otherwise nodes created in XPath extension + functions would be reference counted too soon, during the XPath + evaluation. This is most important in the case of exceptions. + """ + cdef _Element element + if isinstance(obj, _Element): + self._temp_refs.add(obj) + self._temp_documents.add((<_Element>obj)._doc) + return + elif _isString(obj) or not python.PySequence_Check(obj): + return + for o in obj: + if isinstance(o, _Element): + #print "Holding element:", element._c_node + self._temp_refs.add(o) + #print "Holding document:", element._doc._c_doc + self._temp_documents.add((<_Element>o)._doc) + + @cython.final + cdef _Document _findDocumentForNode(self, xmlNode* c_node): + u"""If an XPath expression returns an element from a different + document than the current context document, we call this to + see if it was possibly created by an extension and is a known + document instance. + """ + cdef _Document doc + for doc in self._temp_documents: + if doc is not None and doc._c_doc is c_node.doc: + return doc + return None + + +# libxml2 keeps these error messages in a static array in its code +# and doesn't give us access to them ... + +cdef tuple LIBXML2_XPATH_ERROR_MESSAGES = ( + b"Ok", + b"Number encoding", + b"Unfinished literal", + b"Start of literal", + b"Expected $ for variable reference", + b"Undefined variable", + b"Invalid predicate", + b"Invalid expression", + b"Missing closing curly brace", + b"Unregistered function", + b"Invalid operand", + b"Invalid type", + b"Invalid number of arguments", + b"Invalid context size", + b"Invalid context position", + b"Memory allocation error", + b"Syntax error", + b"Resource error", + b"Sub resource error", + b"Undefined namespace prefix", + b"Encoding error", + b"Char out of XML range", + b"Invalid or incomplete context", + b"Stack usage error", + b"Forbidden variable\n", + b"?? Unknown error ??\n", +) + +cdef void _forwardXPathError(void* c_ctxt, xmlerror.xmlError* c_error) with gil: + cdef xmlerror.xmlError error + cdef int xpath_code + if c_error.message is not NULL: + error.message = c_error.message + else: + xpath_code = c_error.code - xmlerror.XML_XPATH_EXPRESSION_OK + if 0 <= xpath_code < len(LIBXML2_XPATH_ERROR_MESSAGES): + error.message = _cstr(LIBXML2_XPATH_ERROR_MESSAGES[xpath_code]) + else: + error.message = b"unknown error" + error.domain = c_error.domain + error.code = c_error.code + error.level = c_error.level + error.line = c_error.line + error.int2 = c_error.int1 # column + error.file = c_error.file + error.node = NULL + + (<_BaseContext>c_ctxt)._error_log._receive(&error) + +cdef void _receiveXPathError(void* c_context, xmlerror.xmlError* error) nogil: + if not __DEBUG: + return + if c_context is NULL: + _forwardError(NULL, error) + else: + _forwardXPathError(c_context, error) + + +def Extension(module, function_mapping=None, *, ns=None): + u"""Extension(module, function_mapping=None, ns=None) + + Build a dictionary of extension functions from the functions + defined in a module or the methods of an object. + + As second argument, you can pass an additional mapping of + attribute names to XPath function names, or a list of function + names that should be taken. + + The ``ns`` keyword argument accepts a namespace URI for the XPath + functions. + """ + cdef dict functions = {} + if isinstance(function_mapping, dict): + for function_name, xpath_name in function_mapping.items(): + functions[(ns, xpath_name)] = getattr(module, function_name) + else: + if function_mapping is None: + function_mapping = [ name for name in dir(module) + if not name.startswith(u'_') ] + for function_name in function_mapping: + functions[(ns, function_name)] = getattr(module, function_name) + return functions + +################################################################################ +# EXSLT regexp implementation + +@cython.final +@cython.internal +cdef class _ExsltRegExp: + cdef dict _compile_map + def __cinit__(self): + self._compile_map = {} + + cdef _make_string(self, value): + if _isString(value): + return value + elif isinstance(value, list): + # node set: take recursive text concatenation of first element + if python.PyList_GET_SIZE(value) == 0: + return u'' + firstnode = value[0] + if _isString(firstnode): + return firstnode + elif isinstance(firstnode, _Element): + c_text = tree.xmlNodeGetContent((<_Element>firstnode)._c_node) + if c_text is NULL: + raise MemoryError() + try: + return funicode(c_text) + finally: + tree.xmlFree(c_text) + else: + return unicode(firstnode) + else: + return unicode(value) + + cdef _compile(self, rexp, ignore_case): + cdef python.PyObject* c_result + rexp = self._make_string(rexp) + key = (rexp, ignore_case) + c_result = python.PyDict_GetItem(self._compile_map, key) + if c_result is not NULL: + return c_result + py_flags = re.UNICODE + if ignore_case: + py_flags = py_flags | re.IGNORECASE + rexp_compiled = re.compile(rexp, py_flags) + self._compile_map[key] = rexp_compiled + return rexp_compiled + + def test(self, ctxt, s, rexp, flags=u''): + flags = self._make_string(flags) + s = self._make_string(s) + rexpc = self._compile(rexp, u'i' in flags) + if rexpc.search(s) is None: + return False + else: + return True + + def match(self, ctxt, s, rexp, flags=u''): + cdef list result_list + flags = self._make_string(flags) + s = self._make_string(s) + rexpc = self._compile(rexp, u'i' in flags) + if u'g' in flags: + results = rexpc.findall(s) + if not results: + return () + else: + result = rexpc.search(s) + if not result: + return () + results = [ result.group() ] + results.extend( result.groups(u'') ) + result_list = [] + root = Element(u'matches') + join_groups = u''.join + for s_match in results: + if python.PyTuple_CheckExact(s_match): + s_match = join_groups(s_match) + elem = SubElement(root, u'match') + elem.text = s_match + result_list.append(elem) + return result_list + + def replace(self, ctxt, s, rexp, flags, replacement): + replacement = self._make_string(replacement) + flags = self._make_string(flags) + s = self._make_string(s) + rexpc = self._compile(rexp, u'i' in flags) + if u'g' in flags: + count = 0 + else: + count = 1 + return rexpc.sub(replacement, s, count) + + cdef _register_in_context(self, _BaseContext context): + ns = b"http://exslt.org/regular-expressions" + context._addLocalExtensionFunction(ns, b"test", self.test) + context._addLocalExtensionFunction(ns, b"match", self.match) + context._addLocalExtensionFunction(ns, b"replace", self.replace) + + +################################################################################ +# helper functions + +cdef xpath.xmlXPathObject* _wrapXPathObject(object obj, _Document doc, + _BaseContext context) except NULL: + cdef xpath.xmlNodeSet* resultSet + cdef _Element fake_node = None + cdef xmlNode* c_node + + if isinstance(obj, unicode): + obj = _utf8(obj) + if isinstance(obj, bytes): + # libxml2 copies the string value + return xpath.xmlXPathNewCString(_cstr(obj)) + if isinstance(obj, bool): + return xpath.xmlXPathNewBoolean(obj) + if python.PyNumber_Check(obj): + return xpath.xmlXPathNewFloat(obj) + if obj is None: + resultSet = xpath.xmlXPathNodeSetCreate(NULL) + elif isinstance(obj, _Element): + resultSet = xpath.xmlXPathNodeSetCreate((<_Element>obj)._c_node) + elif python.PySequence_Check(obj): + resultSet = xpath.xmlXPathNodeSetCreate(NULL) + try: + for value in obj: + if isinstance(value, _Element): + if context is not None: + context._hold(value) + xpath.xmlXPathNodeSetAdd(resultSet, (<_Element>value)._c_node) + else: + if context is None or doc is None: + raise XPathResultError, \ + f"Non-Element values not supported at this point - got {value!r}" + # support strings by appending text nodes to an Element + if isinstance(value, unicode): + value = _utf8(value) + if isinstance(value, bytes): + if fake_node is None: + fake_node = _makeElement("text-root", NULL, doc, None, + None, None, None, None, None) + context._hold(fake_node) + else: + # append a comment node to keep the text nodes separate + c_node = tree.xmlNewDocComment(doc._c_doc, "") + if c_node is NULL: + raise MemoryError() + tree.xmlAddChild(fake_node._c_node, c_node) + context._hold(value) + c_node = tree.xmlNewDocText(doc._c_doc, _xcstr(value)) + if c_node is NULL: + raise MemoryError() + tree.xmlAddChild(fake_node._c_node, c_node) + xpath.xmlXPathNodeSetAdd(resultSet, c_node) + else: + raise XPathResultError, \ + f"This is not a supported node-set result: {value!r}" + except: + xpath.xmlXPathFreeNodeSet(resultSet) + raise + else: + raise XPathResultError, f"Unknown return type: {python._fqtypename(obj).decode('utf8')}" + return xpath.xmlXPathWrapNodeSet(resultSet) + +cdef object _unwrapXPathObject(xpath.xmlXPathObject* xpathObj, + _Document doc, _BaseContext context): + if xpathObj.type == xpath.XPATH_UNDEFINED: + raise XPathResultError, u"Undefined xpath result" + elif xpathObj.type == xpath.XPATH_NODESET: + return _createNodeSetResult(xpathObj, doc, context) + elif xpathObj.type == xpath.XPATH_BOOLEAN: + return xpathObj.boolval + elif xpathObj.type == xpath.XPATH_NUMBER: + return xpathObj.floatval + elif xpathObj.type == xpath.XPATH_STRING: + stringval = funicode(xpathObj.stringval) + if context._build_smart_strings: + stringval = _elementStringResultFactory( + stringval, None, None, 0) + return stringval + elif xpathObj.type == xpath.XPATH_POINT: + raise NotImplementedError, u"XPATH_POINT" + elif xpathObj.type == xpath.XPATH_RANGE: + raise NotImplementedError, u"XPATH_RANGE" + elif xpathObj.type == xpath.XPATH_LOCATIONSET: + raise NotImplementedError, u"XPATH_LOCATIONSET" + elif xpathObj.type == xpath.XPATH_USERS: + raise NotImplementedError, u"XPATH_USERS" + elif xpathObj.type == xpath.XPATH_XSLT_TREE: + return _createNodeSetResult(xpathObj, doc, context) + else: + raise XPathResultError, f"Unknown xpath result {xpathObj.type}" + +cdef object _createNodeSetResult(xpath.xmlXPathObject* xpathObj, _Document doc, + _BaseContext context): + cdef xmlNode* c_node + cdef int i + cdef list result + result = [] + if xpathObj.nodesetval is NULL: + return result + for i in range(xpathObj.nodesetval.nodeNr): + c_node = xpathObj.nodesetval.nodeTab[i] + _unpackNodeSetEntry(result, c_node, doc, context, + xpathObj.type == xpath.XPATH_XSLT_TREE) + return result + +cdef _unpackNodeSetEntry(list results, xmlNode* c_node, _Document doc, + _BaseContext context, bint is_fragment): + cdef xmlNode* c_child + if _isElement(c_node): + if c_node.doc != doc._c_doc and c_node.doc._private is NULL: + # XXX: works, but maybe not always the right thing to do? + # XPath: only runs when extensions create or copy trees + # -> we store Python refs to these, so that is OK + # XSLT: can it leak when merging trees from multiple sources? + c_node = tree.xmlDocCopyNode(c_node, doc._c_doc, 1) + # FIXME: call _instantiateElementFromXPath() instead? + results.append( + _fakeDocElementFactory(doc, c_node)) + elif c_node.type == tree.XML_TEXT_NODE or \ + c_node.type == tree.XML_CDATA_SECTION_NODE or \ + c_node.type == tree.XML_ATTRIBUTE_NODE: + results.append( + _buildElementStringResult(doc, c_node, context)) + elif c_node.type == tree.XML_NAMESPACE_DECL: + results.append( (funicodeOrNone((c_node).prefix), + funicodeOrNone((c_node).href)) ) + elif c_node.type == tree.XML_DOCUMENT_NODE or \ + c_node.type == tree.XML_HTML_DOCUMENT_NODE: + # ignored for everything but result tree fragments + if is_fragment: + c_child = c_node.children + while c_child is not NULL: + _unpackNodeSetEntry(results, c_child, doc, context, 0) + c_child = c_child.next + elif c_node.type == tree.XML_XINCLUDE_START or \ + c_node.type == tree.XML_XINCLUDE_END: + pass + else: + raise NotImplementedError, \ + f"Not yet implemented result node type: {c_node.type}" + +cdef void _freeXPathObject(xpath.xmlXPathObject* xpathObj): + u"""Free the XPath object, but *never* free the *content* of node sets. + Python dealloc will do that for us. + """ + if xpathObj.nodesetval is not NULL: + xpath.xmlXPathFreeNodeSet(xpathObj.nodesetval) + xpathObj.nodesetval = NULL + xpath.xmlXPathFreeObject(xpathObj) + +cdef _Element _instantiateElementFromXPath(xmlNode* c_node, _Document doc, + _BaseContext context): + # NOTE: this may copy the element - only call this when it can't leak + if c_node.doc != doc._c_doc and c_node.doc._private is NULL: + # not from the context document and not from a fake document + # either => may still be from a known document, e.g. one + # created by an extension function + node_doc = context._findDocumentForNode(c_node) + if node_doc is None: + # not from a known document at all! => can only make a + # safety copy here + c_node = tree.xmlDocCopyNode(c_node, doc._c_doc, 1) + else: + doc = node_doc + return _fakeDocElementFactory(doc, c_node) + +################################################################################ +# special str/unicode subclasses + +@cython.final +cdef class _ElementUnicodeResult(unicode): + cdef _Element _parent + cdef readonly object attrname + cdef readonly bint is_tail + cdef readonly bint is_text + cdef readonly bint is_attribute + + def getparent(self): + return self._parent + +cdef object _PyElementUnicodeResult +if python.IS_PYPY: + class _PyElementUnicodeResult(unicode): + # we need to use a Python class here, or PyPy will crash on creation + # https://bitbucket.org/pypy/pypy/issues/2021/pypy3-pytype_ready-crashes-for-extension + def getparent(self): + return self._parent + +class _ElementStringResult(bytes): + # we need to use a Python class here, bytes cannot be C-subclassed + # in Pyrex/Cython + def getparent(self): + return self._parent + +cdef object _elementStringResultFactory(string_value, _Element parent, + attrname, bint is_tail): + cdef _ElementUnicodeResult uresult + cdef bint is_text + cdef bint is_attribute = attrname is not None + if parent is None: + is_text = 0 + else: + is_text = not (is_tail or is_attribute) + + if type(string_value) is bytes: + result = _ElementStringResult(string_value) + result._parent = parent + result.is_attribute = is_attribute + result.is_tail = is_tail + result.is_text = is_text + result.attrname = attrname + return result + elif python.IS_PYPY: + result = _PyElementUnicodeResult(string_value) + result._parent = parent + result.is_attribute = is_attribute + result.is_tail = is_tail + result.is_text = is_text + result.attrname = attrname + return result + else: + uresult = _ElementUnicodeResult(string_value) + uresult._parent = parent + uresult.is_attribute = is_attribute + uresult.is_tail = is_tail + uresult.is_text = is_text + uresult.attrname = attrname + return uresult + +cdef object _buildElementStringResult(_Document doc, xmlNode* c_node, + _BaseContext context): + cdef _Element parent = None + cdef object attrname = None + cdef xmlNode* c_element + cdef bint is_tail + + if c_node.type == tree.XML_ATTRIBUTE_NODE: + attrname = _namespacedName(c_node) + is_tail = 0 + s = tree.xmlNodeGetContent(c_node) + try: + value = funicode(s) + finally: + tree.xmlFree(s) + c_element = NULL + else: + #assert c_node.type == tree.XML_TEXT_NODE or c_node.type == tree.XML_CDATA_SECTION_NODE, "invalid node type" + # may be tail text or normal text + value = funicode(c_node.content) + c_element = _previousElement(c_node) + is_tail = c_element is not NULL + + if not context._build_smart_strings: + return value + + if c_element is NULL: + # non-tail text or attribute text + c_element = c_node.parent + while c_element is not NULL and not _isElement(c_element): + c_element = c_element.parent + + if c_element is not NULL: + parent = _instantiateElementFromXPath(c_element, doc, context) + + return _elementStringResultFactory( + value, parent, attrname, is_tail) + +################################################################################ +# callbacks for XPath/XSLT extension functions + +cdef void _extension_function_call(_BaseContext context, function, + xpath.xmlXPathParserContext* ctxt, int nargs): + cdef _Document doc + cdef xpath.xmlXPathObject* obj + cdef list args + cdef int i + doc = context._doc + try: + args = [] + for i in range(nargs): + obj = xpath.valuePop(ctxt) + o = _unwrapXPathObject(obj, doc, context) + _freeXPathObject(obj) + args.append(o) + args.reverse() + + res = function(context, *args) + # wrap result for XPath consumption + obj = _wrapXPathObject(res, doc, context) + # prevent Python from deallocating elements handed to libxml2 + context._hold(res) + xpath.valuePush(ctxt, obj) + except: + xpath.xmlXPathErr(ctxt, xpath.XPATH_EXPR_ERROR) + context._exc._store_raised() + finally: + return # swallow any further exceptions + +# lookup the function by name and call it + +cdef void _xpath_function_call(xpath.xmlXPathParserContext* ctxt, + int nargs) with gil: + cdef _BaseContext context + cdef xpath.xmlXPathContext* rctxt = ctxt.context + context = <_BaseContext> rctxt.userData + try: + function = context._find_cached_function(rctxt.functionURI, rctxt.function) + if function is not None: + _extension_function_call(context, function, ctxt, nargs) + else: + xpath.xmlXPathErr(ctxt, xpath.XPATH_UNKNOWN_FUNC_ERROR) + context._exc._store_exception(XPathFunctionError( + f"XPath function '{_namespacedNameFromNsName(rctxt.functionURI, rctxt.function)}' not found")) + except: + # may not be the right error, but we need to tell libxml2 *something* + xpath.xmlXPathErr(ctxt, xpath.XPATH_UNKNOWN_FUNC_ERROR) + context._exc._store_raised() + finally: + return # swallow any further exceptions diff --git a/.venv/lib/python3.7/site-packages/lxml/html/ElementSoup.py b/.venv/lib/python3.7/site-packages/lxml/html/ElementSoup.py new file mode 100644 index 0000000..c35365d --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/html/ElementSoup.py @@ -0,0 +1,10 @@ +__doc__ = """Legacy interface to the BeautifulSoup HTML parser. +""" + +__all__ = ["parse", "convert_tree"] + +from .soupparser import convert_tree, parse as _parse + +def parse(file, beautifulsoup=None, makeelement=None): + root = _parse(file, beautifulsoup=beautifulsoup, makeelement=makeelement) + return root.getroot() diff --git a/.venv/lib/python3.7/site-packages/lxml/html/__init__.py b/.venv/lib/python3.7/site-packages/lxml/html/__init__.py new file mode 100644 index 0000000..ef06a40 --- /dev/null +++ b/.venv/lib/python3.7/site-packages/lxml/html/__init__.py @@ -0,0 +1,1946 @@ +# Copyright (c) 2004 Ian Bicking. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. Neither the name of Ian Bicking nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IAN BICKING OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""The ``lxml.html`` tool set for HTML handling. +""" + +from __future__ import absolute_import + +__all__ = [ + 'document_fromstring', 'fragment_fromstring', 'fragments_fromstring', 'fromstring', + 'tostring', 'Element', 'defs', 'open_in_browser', 'submit_form', + 'find_rel_links', 'find_class', 'make_links_absolute', + 'resolve_base_href', 'iterlinks', 'rewrite_links', 'parse'] + + +import copy +import sys +import re +from functools import partial + +try: + from collections.abc import MutableMapping, MutableSet +except ImportError: + from collections import MutableMapping, MutableSet + +from .. import etree +from . import defs +from ._setmixin import SetMixin + +try: + from urlparse import urljoin +except ImportError: + # Python 3 + from urllib.parse import urljoin + +try: + unicode +except NameError: + # Python 3 + unicode = str +try: + basestring +except NameError: + # Python 3 + basestring = (str, bytes) + + +def __fix_docstring(s): + if not s: + return s + if sys.version_info[0] >= 3: + sub = re.compile(r"^(\s*)u'", re.M).sub + else: + sub = re.compile(r"^(\s*)b'", re.M).sub + return sub(r"\1'", s) + + +XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" + +_rel_links_xpath = etree.XPath("descendant-or-self::a[@rel]|descendant-or-self::x:a[@rel]", + namespaces={'x':XHTML_NAMESPACE}) +_options_xpath = etree.XPath("descendant-or-self::option|descendant-or-self::x:option", + namespaces={'x':XHTML_NAMESPACE}) +_forms_xpath = etree.XPath("descendant-or-self::form|descendant-or-self::x:form", + namespaces={'x':XHTML_NAMESPACE}) +#_class_xpath = etree.XPath(r"descendant-or-self::*[regexp:match(@class, concat('\b', $class_name, '\b'))]", {'regexp': 'http://exslt.org/regular-expressions'}) +_class_xpath = etree.XPath("descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), concat(' ', $class_name, ' '))]") +_id_xpath = etree.XPath("descendant-or-self::*[@id=$id]") +_collect_string_content = etree.XPath("string()") +_iter_css_urls = re.compile(r'url\(('+'["][^"]*["]|'+"['][^']*[']|"+r'[^)]*)\)', re.I).finditer +_iter_css_imports = re.compile(r'@import "(.*?)"').finditer +_label_xpath = etree.XPath("//label[@for=$id]|//x:label[@for=$id]", + namespaces={'x':XHTML_NAMESPACE}) +_archive_re = re.compile(r'[^ ]+') +_parse_meta_refresh_url = re.compile( + r'[^;=]*;\s*(?:url\s*=\s*)?(?P.*)$', re.I).search + + +def _unquote_match(s, pos): + if s[:1] == '"' and s[-1:] == '"' or s[:1] == "'" and s[-1:] == "'": + return s[1:-1], pos+1 + else: + return s,pos + + +def _transform_result(typ, result): + """Convert the result back into the input type. + """ + if issubclass(typ, bytes): + return tostring(result, encoding='utf-8') + elif issubclass(typ, unicode): + return tostring(result, encoding='unicode') + else: + return result + + +def _nons(tag): + if isinstance(tag, basestring): + if tag[0] == '{' and tag[1:len(XHTML_NAMESPACE)+1] == XHTML_NAMESPACE: + return tag.split('}')[-1] + return tag + + +class Classes(MutableSet): + """Provides access to an element's class attribute as a set-like collection. + Usage:: + + >>> el = fromstring('') + >>> classes = el.classes # or: classes = Classes(el.attrib) + >>> classes |= ['block', 'paragraph'] + >>> el.get('class') + 'hidden large block paragraph' + >>> classes.toggle('hidden') + False + >>> el.get('class') + 'large block paragraph' + >>> classes -= ('some', 'classes', 'block') + >>> el.get('class') + 'large paragraph' + """ + def __init__(self, attributes): + self._attributes = attributes + self._get_class_value = partial(attributes.get, 'class', '') + + def add(self, value): + """ + Add a class. + + This has no effect if the class is already present. + """ + if not value or re.search(r'\s', value): + raise ValueError("Invalid class name: %r" % value) + classes = self._get_class_value().split() + if value in classes: + return + classes.append(value) + self._attributes['class'] = ' '.join(classes) + + def discard(self, value): + """ + Remove a class if it is currently present. + + If the class is not present, do nothing. + """ + if not value or re.search(r'\s', value): + raise ValueError("Invalid class name: %r" % value) + classes = [name for name in self._get_class_value().split() + if name != value] + if classes: + self._attributes['class'] = ' '.join(classes) + elif 'class' in self._attributes: + del self._attributes['class'] + + def remove(self, value): + """ + Remove a class; it must currently be present. + + If the class is not present, raise a KeyError. + """ + if not value or re.search(r'\s', value): + raise ValueError("Invalid class name: %r" % value) + super(Classes, self).remove(value) + + def __contains__(self, name): + classes = self._get_class_value() + return name in classes and name in classes.split() + + def __iter__(self): + return iter(self._get_class_value().split()) + + def __len__(self): + return len(self._get_class_value().split()) + + # non-standard methods + + def update(self, values): + """ + Add all names from 'values'. + """ + classes = self._get_class_value().split() + extended = False + for value in values: + if value not in classes: + classes.append(value) + extended = True + if extended: + self._attributes['class'] = ' '.join(classes) + + def toggle(self, value): + """ + Add a class name if it isn't there yet, or remove it if it exists. + + Returns true if the class was added (and is now enabled) and + false if it was removed (and is now disabled). + """ + if not value or re.search(r'\s', value): + raise ValueError("Invalid class name: %r" % value) + classes = self._get_class_value().split() + try: + classes.remove(value) + enabled = False + except ValueError: + classes.append(value) + enabled = True + if classes: + self._attributes['class'] = ' '.join(classes) + else: + del self._attributes['class'] + return enabled + + +class HtmlMixin(object): + + def set(self, key, value=None): + """set(self, key, value=None) + + Sets an element attribute. If no value is provided, or if the value is None, + creates a 'boolean' attribute without value, e.g. "
    " + for ``form.set('novalidate')``. + """ + super(HtmlMixin, self).set(key, value) + + @property + def classes(self): + """ + A set-like wrapper around the 'class' attribute. + """ + return Classes(self.attrib) + + @classes.setter + def classes(self, classes): + assert isinstance(classes, Classes) # only allow "el.classes |= ..." etc. + value = classes._get_class_value() + if value: + self.set('class', value) + elif self.get('class') is not None: + del self.attrib['class'] + + @property + def base_url(self): + """ + Returns the base URL, given when the page was parsed. + + Use with ``urlparse.urljoin(el.base_url, href)`` to get + absolute URLs. + """ + return self.getroottree().docinfo.URL + + @property + def forms(self): + """ + Return a list of all the forms + """ + return _forms_xpath(self) + + @property + def body(self): + """ + Return the element. Can be called from a child element + to get the document's head. + """ + return self.xpath('//body|//x:body', namespaces={'x':XHTML_NAMESPACE})[0] + + @property + def head(self): + """ + Returns the element. Can be called from a child + element to get the document's head. + """ + return self.xpath('//head|//x:head', namespaces={'x':XHTML_NAMESPACE})[0] + + @property + def label(self): + """ + Get or set any

    ho~XoX0yu9E84& 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

    This is another paragraph, with link.

  • {name}
  • MoCqSyGzf78e}nI(vYs-d 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/streams.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/streams.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..269cc01e7e7a859d27122c9f6ce3b9625ef9b43e GIT binary patch literal 18519 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/test_utils.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/test_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae499314c61557dbfc5ed964bfb193b76d9713ee GIT binary patch literal 21643 zcmd^ndvILWdEeg0KCxIl2!an$)QWm>Eee#Vr)gOx2!bLd5o8EZvajW=7JDy%1@-}* zdm$3rMV***CAU@Lq@K8~=@zKl#&-Hj>!yt}ok^o)(!|r5v`NM@chc6W+qBM1o3ztE zTK6&i{l0Ve36PRKnf_Cd_uPBWJ&*5v=R4o)d}q%N4`*Wd`{Iv(d-!u6)P5VV@}L9T(fF8hTKiZl)L3vad(uhDJ>{h2o_5l>Th&Z$ z$Qi0-ovguj?dotX=j7x$ULC28I-|8QXRJ2vjMw%#`)U);L~Xybzc%Si)($uaY6qQz zQZ`XNR6Fb(mgi*kp4t)Th&-pN_tuU&M{D;v_sM&@ny=mO+%L~&^_X)EeP*f;)E;ym ztUcsBg!~~lTYb3pi1SG8xN}_IhXG^3DadoK`k~sR&ZF`?Qaw?7%y~?nN2^n{lg`Q7 z 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/tracing.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/tracing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8335d86084f65bb487dd1ee2ecfa3ce8b4e4665f GIT binary patch literal 15001 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/typedefs.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/typedefs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aeee2569b2315774b5d8fe1fa57d63871808c7fb GIT binary patch literal 1469 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_app.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_app.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b562741a7dbd0554da1b4fc55f442b5cb030d70b GIT binary patch literal 15105 zcmbVTTWlQHd7hb_y>Pi)Q6xo?y4Y*ku}xc|WLb86k!8sgWyzLkMUpLh;$*ViGo+T< z*`>}5Eo!~W#dPYlXxgH;q>WNgO>aprPi=v;MG+vqq-fC=D9{4amjZptLksk+2nw{{ z_s`67mm*`KOUyrK&i(x7zn{ZbhK7m;eqa02zbuZ-7{$tn3m&X8Yr%Ki># zhd=BL`#YVT{)jW;k2<6Nm^0?@a(4OS&bYtZ*)4t9jR}9!nUr+4vB%%*>_s}K@{N7| zerLa=3ylZ-2b~A~ic|3)avt&zI0qzupz*N(i1Ub~i;YkCk2;S^da&`B|G4wGq)Uw{ z{|V;_Ne?xi^ba}*C0%YD@~53?N$+SJ_K!G6Bt6`C%0KEHmGsWW)BZ8%n50J<&-l+e z&q{i<@k#$V=Q&A_HJh?mnqE}3U;eB&F8MRe_m0K&+1`tD zX5t+7;+*mJdS~!{)f@3fy)o~McQ)=FdFQ+xYB%1mHTQXw9L<^a2H7I69oKMPd(}`A zYWIf*`rqlj?iJX6E#sU={-oN2{5{?Ue9vK3mcEGb2EFrG$w1Fa-e}tB^$oPxtM;MA zKJN{*xTws_#?<~FlK$qVtSG-+)nUEbh{`L=sv3IkOv$Hd= zpPPF%%A9K6iiS=Fx0h}41 z5Jve67@^)=jLH{Qq;2|Lcw;%Nx0;wt;j(vQ#cS5QD0^jP8NJ(AZY|^E%_hntyH*Xt zDKpAlt}miCQpGd6)%Kd~{)Z-3hAjJ<(!rD+jh&hgLS3zer)o7X2+p?_7d;*AOmi<( z!`iiT&4pG}PO~nxRWwH2+sX6OPvC@Uv@pRG1kLt5vP92TY> z2g|Kyz=4PRrhnR7Kwj>$r{6=mO3n_}&ju!TN{Q5qv%1J?IT# zF3fpK9Ys#Xdx*1^oTt^X4{fadK)Mq2^bC4>R(%pRA4bgysrQ_EUg|xP%;g33BFaC} zEkCYalJZBB@)PQ1lt0!jKdDYh`QuPQqv{omFr!YR#uVmmcu%NVtmce*6**6O2N#h; z3`@ybl$=wqq2y3f_jTl)R~L{oja@km>>u%-LhU*9`i8oQ{G%B6X_@z@)Fm1B7;>JG zoXhHpK$q2s837I^Qbc*Iq#~^NX`q$c~Npct6a%B zu139=)aUM4DNZ5GPmo5umsRzSt>#tj!<=*SV`?eoq1LGcp9^Xc>v|>mx~A&*nn}Kv z)OCEF_GTAMsEk*=v)(x{{-`&LF=v&3C$E~S^LbH8oJ&v*?+ZglxmbopIahh} zD~nOy)v;L2Lb|nUJRm=>(>=#d$X#&AllXYl~xR*VOOs-dyCL}5JKso z_XQE)(V)Amz4W8t1}pOrhCwvuwwe%=v9MzmXe|$wk&6y=xU!5H@Z;J_s9HChaZxRn zI2gCqs8g`|)m1mBw>?x&%G_GGI`?g(ZWzPH^i*CSh3tuP$x;V<*Hr3T?~ctq+Jcp= zAZw~1{peYArq2+(N^q9o9KmY<7{v=$bhAc%mB&-Slf?rI(Fh92?ZEE4UeLp#v1Z)1 zn!};FWGOSuPz-)GV;Z5|vBK<{6&ww79c#_}!0hDEVnDwpHSLX>oxI8-e_rx)z4;x( z&37!oLMI0}(6IrF9TRXcEOjz#Oo6ol%K~@QnI2Yoz?}j|7MU{|j&%&Fy{nrV@1}Nl zQxoCj8td=r7)#^pdja<>jo&p*(>4-pdWyrv7w$pKR1N#b>7W>uK~D6+q5SSSmqeGZl@T zPKJa+yBZfo#d=V0Vq6$2dM_K5PX&Poo2u0mRi~durangS48gMmBr`ou@JWK_2%aZ+ zf#5}g;{-1e>>@Zp@G`+kf>QudIZ>%It!C)0hMJTU<-jmrQ|VXmF;$4{z-uhr2RZ7~ z?3Un1#}0@7^5NzB@*!DRqj9Kl^yy&nnWyT9tM%5kFkJ4wY3yLU>E&Bd!FB7+dI*R< z0#4T$ESLq$HcQrsRWR|+2()r$@@Ew@ISYUBw^cObzk)f8zxG&<^)Q`w4yz(lYXtgr zbT6F4amYbk&e?~L&{#5+xemHs%G@0Gr_)7`aF7{GW7+%vU(0L{RTjkTWD#&3ai(3n^oU)U41dG`8KO` zajV~A<(X_ z*XLm^|2Q<|qwJ|GS1w)Nz?OaolM)0)*#j6L8& zU}KwrSHUIGs6Pkr9Xvr9zyR?Obv95}u-d!(k+;#g6=ho?Ha|ug_d2OZIBZY7iGaGE8e}F!a2#dQyh1Ub>lAN302~f*)fmD++e~}){7{Q_ah-t*^g_? z-89{pn&VCR3zP>ofMFKQEyyyiRTH{FCBFH{jK+}Y&Pe9-(w6f{XjA5M?^Kl6hzI!r zy4!Xt-CBK8wL2A}J0x|QYm6TdAyKB`HDiRBF>`DhJMX%v;ktjvab;|Qg3YpA!gr$Npl|dikJxCkS&-%EXRN1vV@wl(2&Eu z$fUUgDi!-uSX?lU`Xq2R5t33!bl_0OcICQx*SJmPKudE#A7l!04=LD)*lAdlwExHq z(4lB^rem&W?}83odv$^+Icv^ga)3`BrH73yvwCp{)G_jK^G!zhXf+emh zH|ycGimERxc#M5ixQuBS&@D_fDno9$u;yU8GheV1l`gF`!@BQnSXa>i>xo4t78BG3 z1imy$l?l-jx33+5QKNG_Ahz#z$#%=WHcM0fk{BO%%#f?)=9 zftjuZryaNTjz+}|U*|tiE9McaJ>EOoMwRYx+*od^4EJkDa5!D0j8@z(VbgU>lERfUQ^T=AOLG^-lJ>l|7aPT5*m5bGt=lZTIz;|PQ+Kb&af}US@vOvZ zrkR{#lRc*zbA{dZOC{Y#-hbf<$m<47EgJ@CYI?@+a(>t}9IhOSiPFcuQeP{u0|cgg8^?9qS|GBXdD?!iOaa zJcVc*?F5xg-Z{R-PRdJMJz#9wPYezc34iRCvX~*xfL>o{dZX8j}v!9W%U!cZ6p zfldr$q8vNBW{Hdiqfy4nAlW&I(@+gpmzVD~>NwIba1;u)ubAt`SB$&nIkY`XYDuLN z-NU8=5^tjx=zs_jF^Sp7j6+L1$|tdpN|#{G_G~Xg5t~^|f;9-RFeo2PA8)j3c%PVN zS<=BqW|D#V=OMgl`Rgm3Lq>P-(q9B{=*ptEUi!pTzrb>t)?iQ1IHig$cQ^vpI0Se5 z*#BpOQL!haG}s$aVnGr#fi!xlrhyPcZ_h9MkADM^SN%+4~t2Uc0De(N|@D_CTr!cVo z34myT$2Fp$5#~a>`f^l!i}rV{v?xMHUq9 zK77SdHxuzWU~kESV~uzNV_EBn&BdvuEL`h24J#>8lLfK2=3zHM$u1S7CIup_rXw>k zUNPqi?3F%mDr_-G0nO2y+uq;P;@;w^qJEzU)daHu&Q7om4$5FArfm&V=JDmog4Jl!18zt|nu>X(OG)V;q6Fk-s(1oRq;uJjDp zCow4ba#!N(}DXNgD%L{i;}aNYdvH1EvDx% z2>c@s<#1K*6!5%1j!!~ViUa;D7$eGE$DzSuPpq08mBT|(Ms*W>9spv@5=}ipF$N6+ zT_HM#Iz;R}h^uU(H*y{5@Z$_mWmE=lV=1raS0CVey>QonS zi7kl}NWXgBgA9=y7;)qz7YpL<9_U|X6Z3jxzPCxvrOgvNw834kpt4aY!uPk$0!+vP zjwGnS#&CpzcmQ)ZM;c`cNgqOf++(V#?jApikFDIF1z2cwBl`E^Os^H#+xg?u)6-M^ zp{9eCmB6c@0RkdTPghP|Jcq~%6nnM*oFWMd$(G#XMBT;oQU%|Sw#^7D^-kxfh%fO8 z3yioU<_=}wp4e{oeVj>U^?f|SH~@%}$|`nFOmR*~mR8%JsbYCSWkV8IV$Y&jtR%n7 z*IFwLMbi|HMgy^=db5Jqenlci5=p958!ZH@CC0>(gjg!6JJRin0bVKuO_tnRIz;(I zBi!jqh-`m6b1RK;e~Z1)v)Du(eEe$XJsdjm{7UZCJU-R87;2p#x0phzcD~iKn!ZSB zT4C$GlXE5P-IA&I$sWRu6$exHusMRf3C zrrL{5T<)D5g39secDtC2`W>#D(%8r%-k0g$$)rwuBnj0{U%{=YPtUcQ-e+)`D(}bF zy?A-9-Bm;LU>;y~E*F^Jj284o`-i;$)X*f&LP~#*vgL zBnjLfKtW7VY{>%%=gWA~PJu8-U`(kN0V%X0+Ws?BxmrP15i zzojw#->X;fwF|KfG=^A0(fH`nP{XCA`Yu9k^V4(%+kSc@JI_X~R z6s^d!{(}`pEJz+d{9pXQTwerYrzYjJLEk`H2Lv=jxg$ZV0qT&j203-ZN^$b^TB``W z(Nb{+VTz;^L9k42dj?Skfh|o(*vZYleQ|c?ic|Jhm%Un;M#F?>ovhNhcqucHJ0OmY zeuFr~P3gsuwHQuH-=9Ahbl_ z(KPBv^szm@xYDfGTDn=OwR~I}t-T&c)g-NW<_eA0feWMeL zGkAnOakPgSK+;&>Kn(1gNf>&^@gCEqa%43!SAS%lK%md6GdwEpeZNTMRS(=l!&xIe z@YGxG)1YaEzRC2VBG!p>S7cMRA7{SR!lE3KlwJK+PhXCrkIPjCQW<2Ja5Ti&=UY~GPu;c{O$ zr))a3`Uoll5u!-RZT#`go@VgKkw|ESFj*#PZQ-aJ|6IXXpfx9k1^l5g)Dv=vhF+-# z-t214lmAVKY`XN@aB9&@s|AHFui`G!OwY~t>5V#bxNk~+)qhIBTP^x8(qZ-AF!i?t zr~83yEti<*5L^?@3|aI&ctfEPyaJHo4F;NZ$CNwka=_$dJR5o0I~MQM;~sFf`;Ghc z_|D0_VA`TZi5t-%y$7+Fh(sV0#NslUoJq>PP~0p)V?-e{+C?>y5V-d1t=7X7jVaN} zLS=arBV+0Ec(bdE!{n-CdLItAs^sV@o)hQ6ACbc6`*`G(ZS`n}cE}U7n`lSyk`HXB z4CmRkW_sfHH*(3DDduhS@)`cgg||v1*~C>#@Z8^_^Z3XrIkup(jjY-{R7TjdX|f=O zAt$&XN+m7`jAFL;B!tmj)P}Fyy%3Z|eF{Wb3r+q-+y!1;?XkU=Zf9+(7fjH;X}n|H7)Fkb90bvB+osVjdHZdt`8Fa<>pU6C ze8W=aH*w0rS~rGahgtg9VW}fWto*Mdf&m-v1G8BS3ko6iHR}WT0A$0t_8z#|LB*$! z8p0-kC+}4ryH)oZ>M>z6O{Q#DF03@dI!^j4xZ2awbof)3mUqkWPc;LY0xU-O-y;=` zTn<~yJ^zTre=iy6vZ!oIeB5!J?L-_T5qjC9Ts)BeNA{HgKW^TwQz&?VyR`=iLku5? zyu<|BXH6gn=NZ`_|O4fp-Ne0jvX6C|M{1+=tHV{p%*^j0#5o^W)rl{Uybt{@t zbbFb3VgU>@CCW%N`Y1ms7o7pb0^?YW+)Z|hu~pH)p^{u`jtnt-aWXw$i`5|!DYv6V z&Cx_|K(7a4AUK1(QtUzpS7Q|d|WKBha6IsLk@Gve#s%JuG~^N@Q_2QGD*g%Wb*&NMgt8E zsmvR)`a}P^`|JPP-}fGHxxc?BfxmD6;y=u*1Bt{x6QaK~PKI%KpQjQDkq}ljQQ~K^ zYSogZWGz)n)$Ed8OPA8MOes^#ma-P_r>ePHzLdwgEz;GVT5qYh)>rD&oT>KL21)}s z&z9C*ONgAvf0__^IUolg+okom(j$6trB|+hoGJ~0`$RvuU-Jg=fLI4!r+FiIP^<^9 zmmBf?Ch(Bh0N$W^GkBxe1m2{13wX2G0^Xu|D|oBe2HvK58~7!$9lTxhOW+-1CwQmk z?ckTiF7Ph70eU;Y1+g2vTkZhw1n&`h!Fx5o4BjX9gZFFR1%5>w03Xm?03Q@Za8bW+ zH~3ZY8u&GRe-HSOI1E0lc`x{gI0`ZSdQgPk_h81b9O8N${k&3BIZM z6!?~S2mFra)8N};3OuFxb?~&90ncbY1HL2P1;4BL4e)#7eenC5&w@+h1Mml$&w)P_ zUjTnW^Lg+WMHyVyd;$ECsDLY)FM{uiS@5jpOJE@+SZaO~JSXPC^SZuEPxj@Uj|o24P4Va3a$$m>}tLOZitV;A8Q^1E8&4X%~!#`SOhO>z6O3E9)cfg zz7BpQmcUDzZ-AG@C*V&sza^}xM6tQT5n-~J2~s2VrNF-8%=$s@hA&m+ZdC^MxZ{Cu zHhjmeSE@m3O8P}BNX^_HU$Nj=Oa^`9uItI`vLdANg4~p^ZYtcyQ@PvHYq)h!7S9I# z*Qcj%jXj!``b|Mzqf)L4*75YV6poU!R0#%nVQO)9R(jstVl~K+Z!QGA{2W!X;!6?q z5k~M#gS3k@>DEUU{d=x*{EF{9kT>dcuBzb_@6_^>?xFoiYa4iNVzKHwjj9~I=Q>DHuu)%hA4qXa;_Y?3uDTTF=c>C{Z>4NX%A5W@*~;Cd z>rc4CnRB9q&v^2davv=PoA|bAS!=keqL!jk2rswa-@dGiYP9M=b4-_=E~?8Faa(@8 zC{a;5Uo-VeSPaXM(|Nd6S*pQ@Pob1WSQ=Mdb=N@yu7_obG=}L9GbmAz0@p^WRreuW z)-$1GUF5oL=t9@oV6o%<&a5u%wu~;*R??=OnsgWaPzwb-SJe%TZ@uQ$WuTuOm-Tu7 zUfX{&@7_YQaO=WhHD0YaRitGbueaVi23db;+I7b(YF>r~*Sa-x`v$MO_4!~cJ!b0O zVgm(@1~Y-?R+(OE$l&GJyKYzN^AdTSLN>fPM`u!3(Ac8}+NRE2D+xMj6OI?QTG_6E zEum0Dxoo|BLzuv@*@VtlWJA_b?z2l_?aVah6*^Bl+d8rFY`5>|%0!+fDs{9KUFBZb z_FEM8!mEy~3a?!zI*Vu&4^Vnc5h{LM&R43pWyM493_IYIR1c&ITb0hl4fGU+E+4<4 zD+vX3qlON_7KO@)n&35b%ZHVvK$i@i&|6}nVFkAyiW-9!x`SZ@b<1*(swb@BI~CS%$UJ1OT~^h_W9ua!7&ac<6;Wlxy$(RWbwx^v(yV~^0q1yZ(~bulUZhpt*!y@k$l z?2G<#I2p#_eF!5HB}*hqNnw>zB3ZIUs+2~=6aA;3q-92CwN?F0nzv})h6&*8FRJ=1$7P0h860^Wqc}VP(@crPLSAk36HhH+ z`N?NVE8(Z^+s#BXaX;O(n#pFWX*bg%`Kt)_{LItvPL|K%i5$Fh>LZ-xJ=&hn5Dwxq z`&r_<_$>E|1Ttq&E}vxT3+RuFY$FB7D+t*@H|D@yz?fXP=lhMqLwUC#qY1&o1eEd6 z#TLCaGq{{QS19%cxrY^1ck1(AVDl^(LVwaPMIll&qMPrki~V^b*tra1LP%P5~~P? zj}-g)c)e1SDBYfNx#o(+D$o1M<&PID)$oqGjd!SNn9@+W%wp(dy8PLz*1!h+L|5NtVGPq{5T?6tqsgY! z04^_&T&{SsFk7v7o^GX`YAQT*{CkD45f#{oyn<6NV9qO?I(Ez}RO+H|8Yf34i?(_n zuTmwN4`709xh&jSpRUiaNv~Fybow%ms4mGyszY#C`AZlRRXTl& zBT^+BscwM7%3r~lsM6_|aYU+QBUSd?mA{5DQKi$b;D}VotE=)(cQ5A*&dEt_!mX9R zf#JmaTxac!SF3gbx_%Xh#}Spow0@a!3O2)g0k|%emGR)wg$7!geDiCJq|0Lq2l(c0Uv63w_u-Vq9COngRlKo0z z&f>1prvs(jR}yxjlt+p)LB7m5ZUQSV*4SFnPca+hs&2RdS@WTAmgGdk_$b>tQuy>P z!89$e&&OQ(*!m^Qw;m_%C!>g{nL$jHX0+tnP27KMA?`_w)CKq;^2tPz&k-iIfF+h* z%zA~oM8s1mLqEw7j730=0$MZNV zX2Z#y=WCV&*5>(gSlh9cj?p=Z`ak8S0wOe_Q$vX+P1mC*@4dYXgjk?01-wKA2p4cHd(u-sx(4|KHrc6%NiJJY~}2 z>GWqfq83j!Qr$+?!-lGK`tz77*+}&zsva>^rPB{%s$?V8?NmK#s7fc!c2NnFS66+( zXugBW$DnLJmeQ4@a5$DC+*Z7@dJ5JUOLtQJxM9BO^!L8z&AS8Y&Ug`?>Cu9Z{tJ#McjVP| z)~LzdaB#kAm^(VH;D}VoMyh+L`ZYsUI{j-*m29NCm#SYkRHf6u#Z<{gs{5$=4MSBr z{V1kNHd5VB)o&WA(&@)BRdScA{#K0-a2?QTwcIIc|ECb~Al{L--XjWkig=#GPEmLb z7Ejwx5bGfBNsA2Pp1h8GdeHu}>J_})`Ib)m3&NgUkg4gt+F%{_9k^9n4tec;lrRcP z;q_@84BZ$Bk-e)h!g`wUu^05%dS-no=O+;drNVuoW~P}96MUJ&4v(t2yTm=Emxu2aYEkKUP8_mPA!y19lkYz;_X)p?f2 z?jQo68qSOPFv#J#zPV85QKIw^#@hZL93J-su(-%Z8yW{K-4ePQAkv)} z=EG|YX9sZ4`E|o)Pp7Rckt9yA89_EuJxJAW8>-T2M@*G$q*|ovZy2i5sSr~o8>zlZ z)!#H!rPIEcD%nW&HL8BcP?b&xW2$5$)k9SM%utn147#J%L^e`AOw}ibs&ryF7^#xG zR5{}D&trPxLpKI%4A&TtQ%~&nLbR`x(F1ap3sH3hF3xwu6a~3jXNaX3$Ac`6UK}1fdNcJD!>mX?wYcg2EZm6K1MM8{{hGyJT0k;2skfn* z&rMVwIkm+a){go+pMu_Br+DF$FX=sWiSIiO6~csc-7VTd4@OWS=PLLfGsuMBh;{~9 z?1;=DLCU9Dqx`7S)kex7Jy&%r z{?9fzvg8?iM*AK~T^C&yi@Prz5|84(^IKu%t(Kn7upEmk=`>8;){saxQawi1-!@dG z)0LPi*+}&`Ri7HF(&>6km29MXf~wC9Rp~SyQzaXzo}}vc4OQuME2c^|Qawf09~i3A zX*#A#Hc~xJ)!#K#rPF&cRkD%l>s0-HLsdF`7*i!1sh*+g9~i3A>7$q`*+}&bs{Wy& zDxE}3m29MXma2bbs7j}MF;#MxDg%4|dADHVQ(b$F!pSaNrEo_!T&rYTpPKagB;1z` z*C(BQ*{nK;*E&DcseZxwBpcXOr@pXefc}ClS&sUC0?Uu~7t`2=wYUu{l1*zfmKyhw zgVq)-zS`D{ju)&rmN#G6?_D~NS+sg_&t2@vE=Y0s?$RFq$f>@7neaXYJ4+9>42-r@ zdA?>IR-Z0iR?Z;&5^pN3+K{4oOD_a$~URbN#E5k>*rxMMcV_3PF#dUs$?Toe*fV7hoLH+7$QfiWFyr#srsLWs&ry>5vh`m zREMehUxuo5`d&1c6nS~{m7w-3PnOExL4}DbY_pjmak?>OxY)0WLuPMH%pN6Bc z;!i0Qhd{NSW{743%|@C{G@EI*(9F?nrP)UF5)HpP(cfO^FB25^_7%6yT@?2~6t^T4cL)?0$cpP{z1C7(`lw?xTo@?E>55^qVic{=($DD8G0~R92ONvDaAoU4bzO!u!XBp8rHvJb*#1`3vw62pBi04-6gzV zfXP{fWM6X7>Py)pL&ZV6>pwl19?TDJ)z>nx8L*8j@u#+Tkv-V=97oUYTkZP)0SRDR A9RL6T literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_fileresponse.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_fileresponse.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d33f352ccdb6e37399dbcd3ae7852368a7284d71 GIT binary patch literal 5928 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%0Dy}gC8#r* ppOreYa4R#J+f-e}lmP1x{N(wtR)Mij<5{#SFiVqFjE1pd{2%sf)!6_5 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_log.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_log.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0816e6cfaf24f20a6bc6f3422476df315c5eba96 GIT binary patch literal 7205 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_request.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32957f940aed31167cb319f729ceb0b754efc5cf GIT binary patch literal 23952 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_runner.cpython-37.pyc b/.venv/lib/python3.7/site-packages/aiohttp/__pycache__/web_runner.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6640c4bbcafd5fd6a7d8524395e1f733f78b9f39 GIT binary patch literal 11641 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