From b9e1d3695a0a2aa236a0ae8f1b4fb2dc8d7cd090 Mon Sep 17 00:00:00 2001 From: Khalouf Date: Tue, 22 Oct 2019 14:14:50 +0200 Subject: [PATCH] Init --- AOA_-2(6m).txt | 557 ++ AOA_-3(6m).txt | 564 ++ AOA_-4(6m).txt | 559 ++ AOA_-5(6m).txt | 560 ++ AOA_1(6m).txt | 561 ++ AOA_2(6m).txt | 561 ++ AOA_3(6m).txt | 558 ++ AOA_4(6m).txt | 562 ++ AOA_5(6m).txt | 558 ++ Auswertung_AOA.py | 25 + Lib/site-packages/easy-install.pth | 2 + .../pip-19.0.3-py3.7.egg/EGG-INFO/PKG-INFO | 73 + .../pip-19.0.3-py3.7.egg/EGG-INFO/SOURCES.txt | 391 + .../EGG-INFO/dependency_links.txt | 1 + .../EGG-INFO/entry_points.txt | 5 + .../EGG-INFO/not-zip-safe | 1 + .../EGG-INFO/top_level.txt | 1 + .../pip-19.0.3-py3.7.egg/pip/__init__.py | 1 + .../pip-19.0.3-py3.7.egg/pip/__main__.py | 19 + .../pip/_internal/__init__.py | 78 + .../pip/_internal/build_env.py | 215 + .../pip/_internal/cache.py | 224 + .../pip/_internal/cli/__init__.py | 4 + .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 341 + .../pip/_internal/cli/cmdoptions.py | 809 ++ .../pip/_internal/cli/main_parser.py | 104 + .../pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 176 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 566 ++ .../pip/_internal/commands/list.py | 301 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 186 + .../pip/_internal/configuration.py | 387 + .../pip/_internal/download.py | 971 ++ .../pip/_internal/exceptions.py | 274 + .../pip/_internal/index.py | 990 ++ .../pip/_internal/locations.py | 211 + .../pip/_internal/models/__init__.py | 2 + .../pip/_internal/models/candidate.py | 31 + .../pip/_internal/models/format_control.py | 73 + .../pip/_internal/models/index.py | 31 + .../pip/_internal/models/link.py | 163 + .../pip/_internal/operations/__init__.py | 0 .../pip/_internal/operations/check.py | 155 + .../pip/_internal/operations/freeze.py | 247 + .../pip/_internal/operations/prepare.py | 413 + .../pip/_internal/pep425tags.py | 381 + .../pip/_internal/pyproject.py | 171 + .../pip/_internal/req/__init__.py | 77 + .../pip/_internal/req/constructors.py | 339 + .../pip/_internal/req/req_file.py | 382 + .../pip/_internal/req/req_install.py | 1021 ++ .../pip/_internal/req/req_set.py | 197 + .../pip/_internal/req/req_tracker.py | 88 + .../pip/_internal/req/req_uninstall.py | 596 ++ .../pip/_internal/resolve.py | 393 + .../pip/_internal/utils/__init__.py | 0 .../pip/_internal/utils/appdirs.py | 270 + .../pip/_internal/utils/compat.py | 264 + .../pip/_internal/utils/deprecation.py | 90 + .../pip/_internal/utils/encoding.py | 39 + .../pip/_internal/utils/filesystem.py | 30 + .../pip/_internal/utils/glibc.py | 93 + .../pip/_internal/utils/hashes.py | 115 + .../pip/_internal/utils/logging.py | 318 + .../pip/_internal/utils/misc.py | 1040 +++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 164 + .../pip/_internal/utils/packaging.py | 85 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 155 + .../pip/_internal/utils/typing.py | 29 + .../pip/_internal/utils/ui.py | 441 + .../pip/_internal/vcs/__init__.py | 534 ++ .../pip/_internal/vcs/bazaar.py | 114 + .../pip/_internal/vcs/git.py | 369 + .../pip/_internal/vcs/mercurial.py | 103 + .../pip/_internal/vcs/subversion.py | 200 + .../pip/_internal/wheel.py | 1095 +++ .../pip/_vendor/__init__.py | 111 + .../pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 367 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../pip/_vendor/certifi/cacert.pem | 4512 +++++++++ .../pip/_vendor/certifi/core.py | 20 + .../pip/_vendor/chardet/__init__.py | 39 + .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 257 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1339 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1295 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1094 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 417 + .../pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../pip/_vendor/distlib/util.py | 1756 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 988 ++ .../pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../pip/_vendor/idna/codec.py | 118 + .../pip/_vendor/idna/compat.py | 12 + .../pip/_vendor/idna/core.py | 396 + .../pip/_vendor/idna/idnadata.py | 1979 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8205 +++++++++++++++++ .../pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/msgpack/__init__.py | 66 + .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 27 + .../pip/_vendor/packaging/__init__.py | 26 + .../pip/_vendor/packaging/_compat.py | 31 + .../pip/_vendor/packaging/_structures.py | 68 + .../pip/_vendor/packaging/markers.py | 296 + .../pip/_vendor/packaging/requirements.py | 138 + .../pip/_vendor/packaging/specifiers.py | 749 ++ .../pip/_vendor/packaging/utils.py | 57 + .../pip/_vendor/packaging/version.py | 420 + .../pip/_vendor/pep517/__init__.py | 4 + .../pip/_vendor/pep517/_in_process.py | 207 + .../pip/_vendor/pep517/build.py | 108 + .../pip/_vendor/pep517/check.py | 202 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 158 + .../pip/_vendor/pep517/wrappers.py | 163 + .../pip/_vendor/pkg_resources/__init__.py | 3171 +++++++ .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 127 + .../pip/_vendor/progress/bar.py | 94 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + .../pip/_vendor/pyparsing.py | 6452 +++++++++++++ .../pip/_vendor/pytoml/__init__.py | 4 + .../pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 341 + .../pip/_vendor/pytoml/test.py | 30 + .../pip/_vendor/pytoml/utils.py | 67 + .../pip/_vendor/pytoml/writer.py | 106 + .../pip/_vendor/requests/__init__.py | 133 + .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 533 ++ .../pip/_vendor/requests/api.py | 158 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 74 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 119 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 953 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 770 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 977 ++ .../pip/_vendor/retrying.py | 267 + .../pip-19.0.3-py3.7.egg/pip/_vendor/six.py | 952 ++ .../pip/_vendor/urllib3/__init__.py | 92 + .../pip/_vendor/urllib3/_collections.py | 329 + .../pip/_vendor/urllib3/connection.py | 391 + .../pip/_vendor/urllib3/connectionpool.py | 896 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../urllib3/contrib/_appengine_environ.py | 30 + .../contrib/_securetransport/__init__.py | 0 .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 289 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 111 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 466 + .../urllib3/contrib/securetransport.py | 804 ++ .../pip/_vendor/urllib3/contrib/socks.py | 192 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../urllib3/packages/backports/__init__.py | 0 .../urllib3/packages/backports/makefile.py | 53 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../ssl_match_hostname/_implementation.py | 156 + .../pip/_vendor/urllib3/poolmanager.py | 450 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 705 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../pip/_vendor/urllib3/util/connection.py | 134 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 87 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 381 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 150 + .../pip/_vendor/webencodings/__init__.py | 342 + .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + Lib/site-packages/setuptools-40.8.0-py3.7.egg | Bin 0 -> 571910 bytes Lib/site-packages/setuptools.pth | 1 + Scripts/Activate.ps1 | 51 + Scripts/activate | 76 + Scripts/activate.bat | 45 + Scripts/deactivate.bat | 21 + Scripts/easy_install-3.7-script.py | 12 + Scripts/easy_install-3.7.exe | Bin 0 -> 65536 bytes Scripts/easy_install-3.7.exe.manifest | 15 + Scripts/easy_install-script.py | 12 + Scripts/easy_install.exe | Bin 0 -> 65536 bytes Scripts/easy_install.exe.manifest | 15 + Scripts/pip-script.py | 12 + Scripts/pip.exe | Bin 0 -> 65536 bytes Scripts/pip.exe.manifest | 15 + Scripts/pip3-script.py | 12 + Scripts/pip3.7-script.py | 12 + Scripts/pip3.7.exe | Bin 0 -> 65536 bytes Scripts/pip3.7.exe.manifest | 15 + Scripts/pip3.exe | Bin 0 -> 65536 bytes Scripts/pip3.exe.manifest | 15 + Scripts/python.exe | Bin 0 -> 415248 bytes Scripts/pythonw.exe | Bin 0 -> 414736 bytes example1.py | 29 + example2.py | 9 + example_test.py | 14 + new 1.py | 14 + pyvenv.cfg | 3 + test2.txt | 531 ++ 354 files changed, 112199 insertions(+) create mode 100755 AOA_-2(6m).txt create mode 100755 AOA_-3(6m).txt create mode 100755 AOA_-4(6m).txt create mode 100755 AOA_-5(6m).txt create mode 100755 AOA_1(6m).txt create mode 100755 AOA_2(6m).txt create mode 100755 AOA_3(6m).txt create mode 100755 AOA_4(6m).txt create mode 100755 AOA_5(6m).txt create mode 100755 Auswertung_AOA.py create mode 100755 Lib/site-packages/easy-install.pth create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/PKG-INFO create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/SOURCES.txt create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/dependency_links.txt create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/entry_points.txt create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/not-zip-safe create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/top_level.txt create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__main__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/build_env.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cache.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/autocompletion.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/base_command.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/cmdoptions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/main_parser.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/parser.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/status_codes.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/check.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/completion.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/configuration.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/download.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/freeze.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/hash.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/help.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/install.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/list.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/search.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/show.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/uninstall.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/wheel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/configuration.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/download.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/exceptions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/index.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/locations.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/candidate.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/format_control.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/index.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/link.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/check.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/freeze.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/prepare.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pep425tags.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pyproject.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/constructors.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_file.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_install.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_set.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_tracker.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_uninstall.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/resolve.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/appdirs.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/deprecation.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/encoding.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/filesystem.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/glibc.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/hashes.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/logging.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/misc.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/models.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/outdated.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/packaging.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/setuptools_build.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/temp_dir.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/typing.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/ui.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/bazaar.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/git.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/mercurial.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/subversion.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/wheel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/appdirs.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/adapter.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/cache.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/controller.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/serialize.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__main__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/cacert.pem create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/core.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5freq.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5prober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/chardistribution.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cp949prober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/enums.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escsm.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/eucjpprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrfreq.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwfreq.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312freq.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312prober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/hebrewprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jisfreq.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jpcntx.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langthaimodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/latin1prober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcssm.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sjisprober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/universaldetector.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/utf8prober.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/version.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansi.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansitowin32.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/initialise.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/win32.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/winterm.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/misc.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/database.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/index.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/locators.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/manifest.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/markers.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/metadata.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/resources.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/scripts.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t32.exe create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t64.exe create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/util.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/version.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w32.exe create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w64.exe create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/wheel.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distro.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_inputstream.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/py.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_utils.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/constants.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/base.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/lint.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/html5parser.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/serializer.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/codec.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/core.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/idnadata.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/intranges.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/package_data.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/uts46data.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/ipaddress.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/linklockfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/_version.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/exceptions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/fallback.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__about__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_structures.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/markers.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/requirements.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/specifiers.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/utils.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/version.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/_in_process.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/build.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/check.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/colorlog.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/envbuild.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/wrappers.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/bar.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/counter.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/helpers.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/spinner.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pyparsing.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/core.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/parser.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/test.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/utils.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/writer.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__version__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/_internal_utils.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/adapters.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/api.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/auth.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/certs.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/compat.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/cookies.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/exceptions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/help.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/hooks.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/models.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/packages.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/sessions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/status_codes.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/structures.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/utils.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/retrying.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/six.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/_collections.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connection.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connectionpool.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/exceptions.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/fields.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/filepost.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/six.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/poolmanager.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/request.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/response.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/connection.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/queue.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/request.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/response.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/retry.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/timeout.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/url.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/wait.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/__init__.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/labels.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/mklabels.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/tests.py create mode 100755 Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py create mode 100755 Lib/site-packages/setuptools-40.8.0-py3.7.egg create mode 100755 Lib/site-packages/setuptools.pth create mode 100755 Scripts/Activate.ps1 create mode 100755 Scripts/activate create mode 100755 Scripts/activate.bat create mode 100755 Scripts/deactivate.bat create mode 100755 Scripts/easy_install-3.7-script.py create mode 100755 Scripts/easy_install-3.7.exe create mode 100755 Scripts/easy_install-3.7.exe.manifest create mode 100755 Scripts/easy_install-script.py create mode 100755 Scripts/easy_install.exe create mode 100755 Scripts/easy_install.exe.manifest create mode 100755 Scripts/pip-script.py create mode 100755 Scripts/pip.exe create mode 100755 Scripts/pip.exe.manifest create mode 100755 Scripts/pip3-script.py create mode 100755 Scripts/pip3.7-script.py create mode 100755 Scripts/pip3.7.exe create mode 100755 Scripts/pip3.7.exe.manifest create mode 100755 Scripts/pip3.exe create mode 100755 Scripts/pip3.exe.manifest create mode 100755 Scripts/python.exe create mode 100755 Scripts/pythonw.exe create mode 100755 example1.py create mode 100755 example2.py create mode 100755 example_test.py create mode 100755 new 1.py create mode 100755 pyvenv.cfg create mode 100755 test2.txt diff --git a/AOA_-2(6m).txt b/AOA_-2(6m).txt new file mode 100755 index 0000000..e5d0f5b --- /dev/null +++ b/AOA_-2(6m).txt @@ -0,0 +1,557 @@ +$ORIEN,54:6C:0E:A0:42:58,0,60474,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60475,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60476,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60477,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60478,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60479,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60480,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60481,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60482,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60483,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60484,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60485,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60486,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60487,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60488,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60489,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60490,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60491,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60492,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60493,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60494,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60495,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60496,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60497,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60498,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60499,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60500,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60501,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60502,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60503,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60504,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60505,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60506,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60507,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60508,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60509,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60510,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60511,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60512,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60513,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60514,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60515,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60516,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60517,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60518,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60519,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60520,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60521,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60522,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60523,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60524,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60525,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60526,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60527,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60528,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60529,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60530,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60531,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60532,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60533,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60534,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60535,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60536,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60537,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60538,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60539,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60540,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60541,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60542,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60543,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60544,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60545,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60546,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60547,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60548,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60549,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60550,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60551,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60552,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60553,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60554,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60555,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60556,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60557,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60558,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60559,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60560,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60561,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60562,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60563,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60564,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60565,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60566,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60567,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60568,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60569,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60570,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60571,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60572,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60573,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60574,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60575,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60576,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60577,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60578,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60579,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60580,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60581,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60582,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60583,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60584,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60585,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60586,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60587,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60588,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60589,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60590,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60591,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60592,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60593,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60594,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60595,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60596,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60597,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60598,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60599,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60600,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60601,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60602,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60603,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60604,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60605,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60606,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60607,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60608,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60609,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60610,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60611,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60612,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60613,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60614,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60615,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60616,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60617,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60618,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60619,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60620,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60621,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60622,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60623,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60624,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60625,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60626,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60627,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60628,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60629,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60630,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60631,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60632,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60633,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60634,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60635,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60636,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60637,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60638,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60639,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60640,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60641,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60642,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60643,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60644,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60645,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60646,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60647,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60648,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60649,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60650,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60651,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60652,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60653,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60654,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60655,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60656,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60657,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60658,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60659,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60660,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60661,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60662,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60663,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60664,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60665,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60666,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60667,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60668,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60669,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60670,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60671,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60672,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60673,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60674,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60675,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60676,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60677,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60678,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60679,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60680,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60681,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60682,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60683,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60684,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60685,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60686,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60687,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60688,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60689,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60690,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60691,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60692,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60693,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60694,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60695,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60696,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60697,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60698,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60699,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60700,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60701,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60704,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60705,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60706,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60707,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60708,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60709,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60710,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60711,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60712,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60713,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60714,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60715,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60716,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60717,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60718,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60719,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60720,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60721,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60722,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60723,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60724,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60725,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60726,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60727,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60728,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60729,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60730,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60731,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60732,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60733,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60734,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60735,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60736,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60737,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60738,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60739,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60740,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60741,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60742,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60743,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60744,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60745,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60746,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60747,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60748,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60749,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60750,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60751,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60752,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60753,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60754,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60755,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60756,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60757,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60758,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60759,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60760,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60761,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60762,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60763,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60764,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60765,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60766,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60767,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60768,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60769,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60770,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60771,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60772,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60773,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60774,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60775,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60776,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60777,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60778,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60779,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60780,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60781,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60782,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60783,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60784,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60785,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60786,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60787,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60788,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60789,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60790,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60791,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60792,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60793,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60794,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60795,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60796,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60797,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60798,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60799,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60800,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60801,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60802,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60803,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60804,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60805,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60806,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60807,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60808,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60809,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60810,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60811,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60812,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60813,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60814,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60815,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60816,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60817,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60818,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60819,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60820,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60821,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60822,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60823,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60824,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60825,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60826,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60827,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60828,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60829,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60830,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60831,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60832,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60833,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60834,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60835,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60836,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60837,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60838,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60839,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60840,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60841,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60842,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60843,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60844,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60845,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60846,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60847,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60848,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60849,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60850,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60851,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60852,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60853,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60854,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60855,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60856,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60857,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60858,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60859,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60860,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60861,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60862,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60863,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60864,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60865,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60866,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60867,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60868,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60869,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60870,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60871,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60872,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60873,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60874,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60875,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60876,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60877,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60878,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60879,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60880,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60881,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60882,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60883,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60884,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60885,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60886,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60887,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60888,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60889,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60890,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60891,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60892,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60893,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60894,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60895,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60896,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60897,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60898,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60899,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60900,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60901,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60902,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60903,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60904,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60905,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60906,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60907,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60908,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60909,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60910,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60911,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60912,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60913,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60914,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60915,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60916,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60917,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60918,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60919,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60920,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60921,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60922,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60923,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60924,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60925,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60926,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60927,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60928,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60929,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60930,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60931,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60932,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60933,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60934,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60935,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60936,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60937,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60938,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60939,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60940,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60941,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60942,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60943,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60944,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60945,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60946,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60947,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60948,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60949,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60950,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60951,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60952,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60953,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60954,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60955,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60956,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60957,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60958,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60959,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60960,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60961,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60962,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60963,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60964,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60965,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60966,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60967,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60968,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60969,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60970,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60971,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60972,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60973,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60974,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60975,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60976,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60977,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60978,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60979,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60980,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60981,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60982,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60983,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60984,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60985,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60986,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60987,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60988,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60989,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60990,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60991,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60992,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60993,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60994,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60995,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60996,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,60997,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60998,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,60999,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61000,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61001,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61002,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61003,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61004,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61005,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61006,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61007,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61008,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61009,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61010,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61011,-28,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61012,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61013,-28,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61014,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61015,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61016,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61017,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61018,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61019,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61020,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61021,-28,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61022,-29,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,61023,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61024,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61025,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61026,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61027,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61028,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61029,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61030,-29,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,61031,-28,-59,0,0,0,0,1 + diff --git a/AOA_-3(6m).txt b/AOA_-3(6m).txt new file mode 100755 index 0000000..7a84175 --- /dev/null +++ b/AOA_-3(6m).txt @@ -0,0 +1,564 @@ +$ORIEN,54:6C:0E:A0:42:58,0,59405,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59406,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59407,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59408,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59409,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59410,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59411,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59412,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59413,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59414,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59415,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59416,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59417,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59418,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59419,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59420,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59421,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59422,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59423,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59424,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59425,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59426,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59427,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59428,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59429,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59430,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59431,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59432,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59433,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59434,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59435,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59436,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59437,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59438,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59439,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59440,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59441,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59442,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59443,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59444,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59445,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59446,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59447,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59448,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59449,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59450,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59451,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59452,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59453,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59454,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59455,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59456,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59457,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59458,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59459,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59460,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59461,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59462,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59463,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59464,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59465,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59466,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59467,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59468,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59469,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59470,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59471,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59472,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59473,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59474,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59475,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59476,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59477,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59478,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59479,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59480,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59481,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59482,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59483,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59484,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59485,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59486,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59487,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59488,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59489,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59490,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59491,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59492,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59493,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59494,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59495,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59496,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59497,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59498,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59499,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59500,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59501,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59502,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59503,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59504,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59505,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59506,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59507,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59508,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59509,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59510,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59511,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59512,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59513,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59514,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59515,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59516,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59517,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59518,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59519,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59520,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59521,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59522,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59523,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59524,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59525,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59526,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59527,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59528,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59529,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59530,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59531,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59532,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59533,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59534,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59535,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59536,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59537,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59538,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59539,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59540,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59541,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59542,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59543,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59544,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59545,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59546,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59547,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59548,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59549,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59550,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59551,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59552,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59553,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59554,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59555,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59556,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59557,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59558,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59559,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59560,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59561,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59562,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59563,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59564,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59565,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59566,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59567,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59568,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59569,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59570,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59571,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59572,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59573,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59574,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59575,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59576,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59577,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59578,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59579,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59580,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59581,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59582,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59583,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59584,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59585,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59586,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59587,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59588,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59589,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59590,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59591,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59592,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59593,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59594,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59595,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59596,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59597,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59598,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59599,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59600,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59601,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59602,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59603,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59604,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59605,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59606,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59607,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59608,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59609,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59610,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59611,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59612,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59613,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59614,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59615,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59616,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59617,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59618,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59619,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59620,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59621,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59622,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59623,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59624,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59625,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59626,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59627,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59628,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59629,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59630,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59631,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59632,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59633,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59634,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59635,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59636,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59637,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59638,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59639,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59640,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59641,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59642,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59643,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59644,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59645,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59646,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59647,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59648,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59649,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59650,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59651,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59652,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59653,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59654,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59655,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59656,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59657,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59658,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59659,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59660,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59661,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59662,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59663,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59664,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59665,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59666,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59667,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59668,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59669,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59670,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59671,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59672,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59673,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59674,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59675,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59676,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59677,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59678,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59679,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59680,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59681,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59682,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59683,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59684,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59685,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59686,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59687,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59688,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59689,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59690,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59691,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59692,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59693,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59694,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59695,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59696,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59697,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59698,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59699,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59700,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59701,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59702,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59703,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59704,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59705,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59706,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59707,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59708,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59709,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59710,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59711,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59712,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59713,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59714,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59715,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59716,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59717,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59718,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59719,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59720,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59721,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59722,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59723,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59724,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59725,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59726,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59727,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59728,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59729,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59730,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59731,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59732,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59733,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59734,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59735,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59736,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59737,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59738,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59739,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59740,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59741,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59742,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59743,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59744,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59745,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59746,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59747,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59748,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59749,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59750,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59751,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59752,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59753,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59754,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59755,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59756,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59757,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59758,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59759,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59760,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59761,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59762,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59763,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59764,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59765,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59766,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59767,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59768,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59769,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59770,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59771,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59772,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59773,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59774,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59775,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59776,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59777,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59778,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59779,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59780,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59781,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59782,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59783,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59784,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59785,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59786,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59787,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59788,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59789,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59790,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59791,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59792,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59793,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59794,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59795,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59796,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59797,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59798,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59799,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59800,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59801,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59802,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59803,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59804,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59805,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59806,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59807,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59808,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59809,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59810,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59811,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59812,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59813,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59814,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59815,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59816,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59817,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59818,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59819,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59820,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59821,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59822,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59823,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59824,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59825,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59826,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59827,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59828,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59829,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59830,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59831,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59832,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59833,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59834,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59835,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59836,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59837,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59838,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59839,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59840,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59841,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59842,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59843,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59844,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59845,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59846,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59847,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59848,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59849,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59850,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59851,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59852,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59853,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59854,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59855,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59856,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59857,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59858,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59859,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59860,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59861,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59862,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59863,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59864,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59865,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59866,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59867,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59868,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59869,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59870,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59871,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59872,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59873,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59874,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59875,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59876,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59877,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59878,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59879,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59880,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59881,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59882,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59883,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59884,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59885,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59886,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59887,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59888,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59889,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59890,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59891,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59892,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59893,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59894,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59895,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59896,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59897,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59898,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59899,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59900,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59901,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59902,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59903,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59904,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59905,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59906,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59907,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59908,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59909,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59910,-48,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59911,-48,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59912,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59913,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59914,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59915,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59916,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59917,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59918,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59919,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59920,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59921,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59922,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59923,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59924,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59925,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59926,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59927,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59928,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59929,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59930,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59931,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59932,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59933,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59934,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59935,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59936,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59937,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59938,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59939,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59940,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59941,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59942,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59943,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59944,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59945,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59946,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59947,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59948,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59949,-50,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59950,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59951,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59952,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59953,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59954,-50,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59955,-49,-58,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,59956,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59957,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59958,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59959,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59960,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59961,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59962,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59963,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59964,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59965,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59966,-49,-58,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,59967,-49,-58,0,0,0,0,0 + diff --git a/AOA_-4(6m).txt b/AOA_-4(6m).txt new file mode 100755 index 0000000..4ea4ebd --- /dev/null +++ b/AOA_-4(6m).txt @@ -0,0 +1,559 @@ +$ORIEN,54:6C:0E:A0:42:58,0,58292,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58293,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58294,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58295,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58296,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58297,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58298,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58299,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58300,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58301,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58302,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58303,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58304,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58305,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58306,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58307,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58308,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58309,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58310,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58311,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58312,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58313,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58314,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58315,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58316,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58317,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58318,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58319,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58320,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58321,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58322,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58323,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58324,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58325,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58326,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58327,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58328,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58329,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58330,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58331,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58332,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58333,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58334,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58335,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58336,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58337,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58338,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58339,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58340,-79,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58341,-79,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58342,-79,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58343,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58344,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58345,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58346,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58347,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58348,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58349,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58350,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58351,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58352,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58353,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58354,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58355,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58356,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58357,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58358,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58359,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58360,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58361,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58362,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58363,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58364,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58365,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58366,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58367,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58368,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58369,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58370,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58371,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58372,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58373,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58374,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58375,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58376,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58377,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58378,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58379,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58380,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58381,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58382,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58383,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58384,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58385,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58386,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58387,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58388,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58389,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58390,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58391,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58392,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58393,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58394,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58395,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58396,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58397,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58398,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58399,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58400,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58401,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58402,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58403,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58404,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58405,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58406,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58407,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58408,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58409,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58410,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58411,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58412,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58413,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58414,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58415,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58416,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58417,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58418,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58419,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58420,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58421,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58422,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58423,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58424,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58425,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58426,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58427,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58428,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58429,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58430,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58431,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58432,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58433,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58434,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58435,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58436,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58437,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58438,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58439,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58440,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58441,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58442,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58443,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58444,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58445,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58446,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58447,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58448,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58449,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58450,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58451,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58452,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58453,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58454,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58455,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58456,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58457,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58458,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58459,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58460,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58461,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58462,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58463,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58464,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58465,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58466,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58467,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58468,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58469,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58470,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58471,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58472,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58473,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58474,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58475,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58476,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58477,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58478,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58479,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58480,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58481,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58482,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58483,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58484,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58485,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58486,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58487,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58488,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58489,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58490,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58491,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58492,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58493,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58494,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58495,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58496,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58497,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58498,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58499,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58500,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58501,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58502,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58503,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58504,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58505,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58506,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58507,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58508,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58509,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58510,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58511,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58512,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58513,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58514,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58515,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58516,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58517,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58518,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58519,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58520,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58521,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58522,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58523,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58524,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58525,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58526,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58527,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58528,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58529,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58530,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58531,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58532,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58533,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58534,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58535,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58536,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58537,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58538,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58539,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58540,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58541,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58542,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58543,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58544,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58545,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58546,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58547,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58548,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58549,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58550,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58551,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58552,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58553,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58554,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58555,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58556,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58557,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58558,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58559,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58560,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58561,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58562,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58563,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58564,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58565,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58566,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58567,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58568,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58569,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58570,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58571,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58572,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58573,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58574,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58575,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58576,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58577,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58578,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58579,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58580,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58581,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58582,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58583,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58584,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58585,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58586,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58587,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58588,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58589,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58590,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58591,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58592,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58593,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58594,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58595,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58596,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58597,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58598,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58599,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58600,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58601,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58602,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58603,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58604,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58605,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58606,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58607,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58608,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58609,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58610,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58611,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58612,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58613,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58614,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58615,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58616,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58617,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58618,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58619,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58620,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58621,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58622,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58623,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58624,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58625,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58626,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58627,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58628,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58629,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58630,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58631,-80,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58632,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58633,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58634,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58635,-79,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58636,-79,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58637,-79,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58638,-79,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58639,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58640,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58641,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58642,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58643,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58644,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58645,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58646,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58647,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58648,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58649,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58650,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58651,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58652,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58653,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58654,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58655,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58656,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58657,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58658,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58659,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58660,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58661,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58662,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58663,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58664,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58665,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58666,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58667,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58668,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58669,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58670,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58671,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58672,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58673,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58674,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58675,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58676,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58677,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58678,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58679,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58680,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58681,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58682,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58683,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58684,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58685,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58686,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58687,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58688,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58689,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58690,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58691,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58692,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58693,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58694,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58695,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58696,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58697,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58698,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58699,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58700,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58701,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58702,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58703,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58704,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58705,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58706,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58707,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58708,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58709,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58710,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58711,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58712,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58713,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58714,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58715,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58716,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58717,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58718,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58719,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58720,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58721,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58722,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58723,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58724,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58725,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58726,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58727,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58728,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58729,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58730,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58731,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58732,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58733,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58734,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58735,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58736,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58737,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58738,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58739,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58740,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58741,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58742,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58743,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58744,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58745,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58746,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58747,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58748,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58749,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58750,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58751,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58752,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58753,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58754,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58755,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58756,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58757,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58758,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58759,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58760,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58761,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58762,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58763,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58764,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58765,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58766,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58767,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58768,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58769,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58770,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58771,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58772,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58773,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58774,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58775,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58776,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58777,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58778,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58779,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58780,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58781,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58782,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58783,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58784,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58785,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58786,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58787,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58788,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58789,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58790,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58791,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58792,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58793,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58794,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58795,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58796,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58797,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58798,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58799,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58800,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58801,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58802,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58803,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58804,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58805,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58806,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58807,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58808,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58809,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58810,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58811,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58812,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58813,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58814,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58815,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58816,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58817,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58818,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58819,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58820,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58821,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58822,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58823,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58824,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58825,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58826,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58827,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58828,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58829,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58830,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58831,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58832,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58833,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58834,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58835,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58836,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58837,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58838,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58839,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58840,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58841,-80,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58842,-80,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58843,-81,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58844,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58845,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58846,-81,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58847,-82,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,58848,-82,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,58849,-81,-61,0,0,0,0,1 + diff --git a/AOA_-5(6m).txt b/AOA_-5(6m).txt new file mode 100755 index 0000000..17215f0 --- /dev/null +++ b/AOA_-5(6m).txt @@ -0,0 +1,560 @@ +$ORIEN,54:6C:0E:A0:42:58,0,57174,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57175,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57176,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57177,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57178,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57179,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57180,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57181,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57182,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57183,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57184,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57185,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57186,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57187,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57188,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57189,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57190,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57191,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57192,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57193,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57194,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57195,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57196,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57197,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57198,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57199,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57200,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57201,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57202,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57203,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57204,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57205,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57206,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57207,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57208,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57209,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57210,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57211,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57212,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57213,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57214,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57215,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57216,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57217,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57218,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57219,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57220,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57221,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57222,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57223,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57224,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57225,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57226,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57227,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57228,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57229,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57230,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57231,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57232,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57233,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57234,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57235,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57236,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57237,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57238,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57239,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57240,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57241,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57242,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57243,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57244,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57245,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57246,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57247,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57248,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57249,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57250,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57251,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57252,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57253,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57254,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57255,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57256,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57257,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57258,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57259,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57260,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57261,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57262,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57263,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57264,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57265,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57266,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57267,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57268,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57269,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57270,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57271,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57272,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57273,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57274,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57275,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57276,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57277,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57278,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57279,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57280,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57281,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57282,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57283,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57284,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57285,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57286,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57287,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57288,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57289,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57290,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57291,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57292,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57293,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57294,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57295,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57296,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57297,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57298,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57299,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57300,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57301,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57302,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57303,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57304,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57305,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57306,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57307,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57308,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57309,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57310,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57311,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57312,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57313,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57314,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57315,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57316,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57317,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57318,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57319,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57320,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57321,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57322,26,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57323,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57324,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57325,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57326,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57327,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57328,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57329,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57330,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57331,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57332,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57334,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57335,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57336,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57337,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57338,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57339,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57340,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57341,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57342,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57343,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57344,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57345,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57346,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57347,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57348,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57349,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57350,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57351,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57352,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57353,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57354,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57355,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57356,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57357,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57358,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57359,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57360,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57361,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57362,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57363,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57364,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57365,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57366,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57367,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57368,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57369,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57370,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57371,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57372,26,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57373,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57374,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57375,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57376,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57377,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57378,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57379,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57380,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57381,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57382,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57383,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57384,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57385,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57386,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57387,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57388,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57389,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57390,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57391,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57392,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57393,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57394,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57395,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57396,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57397,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57398,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57399,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57400,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57401,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57402,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57403,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57404,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57405,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57406,26,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57407,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57408,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57409,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57410,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57411,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57412,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57413,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57414,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57415,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57416,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57417,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57418,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57419,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57420,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57421,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57422,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57423,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57424,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57425,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57426,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57427,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57428,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57429,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57430,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57431,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57432,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57433,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57434,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57435,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57436,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57437,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57438,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57439,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57440,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57441,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57442,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57443,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57444,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57445,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57446,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57447,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57448,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57449,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57450,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57451,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57452,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57453,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57454,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57455,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57456,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57457,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57458,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57459,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57460,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57461,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57462,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57463,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57464,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57465,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57466,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57467,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57468,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57469,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57470,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57471,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57472,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57473,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57474,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57475,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57476,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57477,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57478,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57479,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57480,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57481,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57482,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57483,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57484,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57485,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57486,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57487,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57488,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57489,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57490,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57491,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57492,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57493,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57494,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57495,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57496,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57497,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57498,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57499,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57500,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57501,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57502,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57503,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57504,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57505,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57506,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57507,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57508,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57509,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57510,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57511,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57512,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57513,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57514,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57515,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57516,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57517,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57518,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57519,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57520,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57521,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57522,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57523,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57524,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57525,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57526,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57527,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57528,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57529,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57530,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57531,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57532,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57533,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57534,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57535,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57536,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57537,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57538,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57539,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57540,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57541,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57542,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57543,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57544,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57545,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57546,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57547,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57548,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57549,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57550,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57551,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57552,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57553,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57554,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57555,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57556,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57557,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57558,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57559,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57560,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57561,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57562,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57563,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57564,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57565,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57566,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57567,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57568,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57569,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57570,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57571,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57572,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57573,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57574,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57575,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57576,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57577,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57578,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57579,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57580,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57581,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57582,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57583,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57584,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57585,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57586,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57587,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57588,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57589,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57590,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57591,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57592,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57593,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57594,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57595,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57596,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57597,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57598,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57599,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57600,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57601,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57602,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57603,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57604,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57605,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57606,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57607,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57608,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57609,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57610,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57611,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57612,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57613,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57614,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57615,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57616,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57617,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57618,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57619,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57620,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57621,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57622,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57623,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57624,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57625,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57626,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57627,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57628,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57629,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57630,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57631,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57632,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57633,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57634,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57635,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57636,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57637,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57638,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57639,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57640,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57641,25,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57642,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57643,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57644,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57645,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57646,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57647,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57648,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57649,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57650,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57651,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57652,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57653,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57654,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57655,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57656,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57657,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57658,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57659,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57660,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57661,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57662,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57663,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57664,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57665,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57666,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57667,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57668,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57669,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57670,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57671,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57672,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57673,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57674,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57675,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57676,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57677,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57678,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57679,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57680,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57681,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57682,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57683,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57684,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57685,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57686,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57687,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57688,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57689,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57690,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57691,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57692,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57693,25,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57694,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57695,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57696,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57697,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57698,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57699,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57700,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57701,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57702,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57703,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57704,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57705,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57706,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57707,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57708,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57709,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57710,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57711,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57712,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57713,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57714,25,-65,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57715,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57716,25,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57717,2,-66,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57718,2,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57719,2,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57720,2,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57721,2,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57722,2,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57723,26,-64,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,57724,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57725,26,-65,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57726,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57727,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57728,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57729,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57730,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57731,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57732,26,-64,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,57733,26,-64,0,0,0,0,0 + diff --git a/AOA_1(6m).txt b/AOA_1(6m).txt new file mode 100755 index 0000000..df20736 --- /dev/null +++ b/AOA_1(6m).txt @@ -0,0 +1,561 @@ +$ORIEN,546C0EA04258,0,48423,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48424,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48425,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48426,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48427,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48428,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48429,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48430,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48431,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48432,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48433,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48434,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48435,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48436,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48437,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48438,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48439,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48440,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48441,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48442,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48443,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48444,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48445,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48446,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48447,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48448,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48449,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48450,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48451,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48452,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48453,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48454,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48455,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48456,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48457,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48458,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48459,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48460,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48461,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48462,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48463,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48464,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48465,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48466,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48467,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48468,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48469,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48470,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48471,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48472,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48473,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48474,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48475,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48476,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48477,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48478,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48479,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48480,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48481,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48482,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48483,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48484,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48485,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48486,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48487,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48488,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48489,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48490,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48491,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48492,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48493,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48494,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48495,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48496,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48497,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48498,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48499,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48500,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48501,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48502,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48503,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48504,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48505,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48506,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48507,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48508,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48509,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48510,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48511,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48512,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48513,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48514,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48515,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48516,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48517,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48518,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48519,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48520,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48521,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48522,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48523,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48524,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48525,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48526,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48527,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48528,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48529,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48530,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48531,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48532,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48533,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48534,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48535,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48536,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48537,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48538,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48539,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48540,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48541,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48542,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48543,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48544,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48545,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48546,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48547,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48548,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48549,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48550,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48551,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48552,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48553,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48554,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48555,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48556,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48557,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48558,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48559,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48560,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48561,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48562,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48563,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48564,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48565,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48566,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48567,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48568,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48569,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48570,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48571,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48572,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48573,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48574,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48575,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48576,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48577,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48578,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48579,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48580,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48581,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48582,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48583,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48584,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48585,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48586,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48587,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48588,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48589,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48590,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48591,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48592,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48593,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48594,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48595,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48596,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48597,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48598,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48599,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48600,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48601,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48602,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48603,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48604,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48605,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48606,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48607,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48608,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48609,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48610,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48611,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48612,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48613,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48614,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48615,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48616,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48617,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48618,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48619,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48620,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48621,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48622,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48623,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48624,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48625,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48626,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48627,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48628,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48629,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48630,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48631,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48632,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48633,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48634,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48635,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48636,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48637,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48638,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48639,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48640,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48641,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48642,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48643,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48644,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48645,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48646,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48647,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48648,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48649,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48650,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48651,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48652,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48653,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48654,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48655,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48656,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48657,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48658,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48659,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48660,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48661,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48662,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48663,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48664,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48665,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48666,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48667,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48668,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48669,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48670,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48671,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48672,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48673,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48674,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48675,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48676,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48677,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48678,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48679,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48680,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48681,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48682,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48683,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48684,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48685,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48686,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48687,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48688,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48689,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48690,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48691,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48692,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48693,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48694,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48695,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48696,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48697,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48698,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48699,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48700,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48701,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48702,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48703,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48704,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48705,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48706,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48707,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48708,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48709,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48710,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48711,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48712,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48713,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48714,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48715,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48716,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48717,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48718,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48719,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48720,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48721,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48722,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48723,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48724,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48725,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48726,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48727,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48728,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48729,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48730,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48731,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48732,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48733,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48734,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48735,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48736,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48737,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48738,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48739,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48740,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48741,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48742,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48743,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48744,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48745,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48746,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48747,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48748,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48749,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48750,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48751,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48752,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48753,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48754,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48755,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48756,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48757,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48758,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48759,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48760,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48761,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48762,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48763,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48764,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48765,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48766,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48767,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48768,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48769,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48770,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48771,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48772,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48773,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48774,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48775,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48776,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48777,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48778,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48779,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48780,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48781,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48782,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48783,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48784,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48785,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48786,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48787,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48788,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48789,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48790,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48791,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48792,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48793,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48794,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48795,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48796,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48797,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48798,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48799,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48800,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48801,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48802,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48803,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48804,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48805,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48806,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48807,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48808,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48809,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48810,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48811,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48812,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48813,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48814,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48815,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48816,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48817,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48818,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48819,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48820,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48821,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48822,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48823,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48824,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48825,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48826,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48827,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48828,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48829,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48830,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48831,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48832,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48833,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48834,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48835,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48836,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48837,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48838,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48839,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48840,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48841,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48842,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48843,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48844,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48845,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48846,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48847,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48848,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48849,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48850,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48851,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48852,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48853,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48854,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48855,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48856,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48857,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48858,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48859,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48860,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48861,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48862,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48863,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48864,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48865,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48866,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48867,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48868,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48869,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48870,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48871,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48872,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48873,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48874,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48875,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48876,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48877,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48878,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48879,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48880,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48881,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48882,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48883,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48884,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48885,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48886,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48887,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48888,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48889,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48890,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48891,15,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48892,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48893,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48894,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48895,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48896,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48897,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48898,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48899,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48900,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48901,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48902,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48903,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48904,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48905,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48906,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48907,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48908,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48909,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48910,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48911,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48912,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48913,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48914,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48915,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48916,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48917,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48918,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48919,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48920,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48921,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48922,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48923,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48924,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48925,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48926,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48927,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48928,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48929,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48930,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48931,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48932,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48933,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48934,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48935,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48936,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48937,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48938,13,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48939,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48940,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48941,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48942,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48943,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48944,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48945,13,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48946,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48947,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48948,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48949,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48950,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48951,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48952,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48953,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48954,15,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48955,14,-64,0,0,0,0,1 +$ORIEN,546C0EA04258,0,48956,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48957,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48958,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48959,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48960,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48961,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48962,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48963,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48964,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48965,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48966,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48967,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48968,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48969,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48970,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48971,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48972,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48973,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48974,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48975,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48976,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48977,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48978,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48979,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48980,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48981,14,-64,0,0,0,0,0 +$ORIEN,546C0EA04258,0,48982,14,-64,0,0,0,0,0 + diff --git a/AOA_2(6m).txt b/AOA_2(6m).txt new file mode 100755 index 0000000..9745d00 --- /dev/null +++ b/AOA_2(6m).txt @@ -0,0 +1,561 @@ +$ORIEN,54:6C:0E:A0:42:58,0,49537,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49538,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49539,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49540,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49541,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49542,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49543,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49544,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49545,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49546,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49547,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49548,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49549,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49550,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49551,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49552,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49553,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49554,21,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49555,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49556,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49557,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49558,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49559,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49560,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49561,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49562,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49563,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49564,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49565,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49566,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49567,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49568,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49569,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49570,18,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49571,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49572,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49573,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49574,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49575,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49576,21,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49577,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49578,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49579,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49580,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49581,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49582,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49583,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49584,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49585,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49586,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49587,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49588,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49589,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49590,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49591,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49592,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49593,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49594,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49595,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49596,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49597,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49598,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49599,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49600,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49601,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49602,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49603,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49604,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49605,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49606,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49607,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49608,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49609,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49610,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49611,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49612,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49613,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49614,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49615,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49616,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49617,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49618,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49619,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49620,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49621,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49622,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49623,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49624,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49625,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49626,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49627,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49628,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49629,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49630,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49631,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49632,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49633,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49634,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49635,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49636,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49637,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49638,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49639,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49640,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49641,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49642,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49643,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49644,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49645,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49646,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49647,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49648,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49649,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49650,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49651,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49652,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49653,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49654,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49655,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49656,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49657,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49658,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49659,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49660,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49661,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49662,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49663,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49664,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49665,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49666,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49667,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49668,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49669,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49670,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49671,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49672,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49673,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49674,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49675,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49676,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49677,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49678,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49679,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49680,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49681,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49682,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49683,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49684,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49685,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49686,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49687,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49688,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49689,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49690,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49691,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49692,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49693,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49694,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49695,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49696,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49697,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49698,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49699,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49700,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49701,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49702,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49703,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49704,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49705,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49706,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49707,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49708,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49709,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49710,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49711,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49712,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49713,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49714,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49715,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49716,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49717,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49718,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49719,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49720,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49721,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49722,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49723,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49724,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49725,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49726,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49727,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49728,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49729,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49730,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49731,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49732,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49733,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49734,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49735,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49736,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49737,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49738,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49739,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49740,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49741,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49742,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49743,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49744,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49745,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49746,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49747,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49748,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49749,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49750,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49751,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49752,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49753,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49754,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49755,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49756,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49757,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49758,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49759,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49760,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49761,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49762,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49763,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49764,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49765,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49766,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49767,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49768,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49769,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49770,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49771,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49772,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49773,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49774,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49775,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49776,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49777,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49778,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49779,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49780,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49781,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49782,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49783,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49784,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49785,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49786,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49787,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49788,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49789,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49790,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49791,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49792,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49793,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49794,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49795,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49796,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49797,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49798,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49799,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49800,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49801,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49802,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49803,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49804,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49805,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49806,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49807,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49808,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49809,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49810,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49811,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49812,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49813,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49814,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49815,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49816,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49817,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49818,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49819,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49820,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49821,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49822,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49823,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49824,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49825,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49826,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49827,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49828,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49829,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49830,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49831,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49832,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49833,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49834,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49835,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49836,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49837,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49838,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49839,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49840,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49841,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49842,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49843,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49844,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49845,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49846,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49847,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49848,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49849,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49850,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49851,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49852,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49853,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49854,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49855,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49856,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49857,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49858,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49859,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49860,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49861,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49862,19,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49863,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49864,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49865,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49866,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49867,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49868,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49869,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49870,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49871,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49872,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49873,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49874,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49875,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49876,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49877,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49878,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49879,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49880,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49881,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49882,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49883,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49884,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49885,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49886,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49887,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49888,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49889,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49890,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49891,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49892,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49893,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49894,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49895,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49896,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49897,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49898,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49899,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49900,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49901,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49902,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49903,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49904,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49905,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49906,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49907,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49908,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49909,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49910,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49911,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49912,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49913,19,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49914,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49915,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49916,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49917,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49918,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49919,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49920,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49921,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49922,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49923,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49924,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49925,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49926,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49927,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49928,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49929,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49930,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49931,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49932,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49933,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49934,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49935,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49936,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49937,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49938,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49939,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49940,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49941,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49942,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49943,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49944,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49945,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49946,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49947,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49948,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49949,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49950,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49951,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49952,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49953,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49954,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49955,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49956,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,49957,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49958,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49959,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49960,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49961,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49962,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49963,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49964,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49965,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49966,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49967,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49968,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49969,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49970,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49971,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49972,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49973,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49974,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49975,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49976,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49977,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49978,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49979,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49980,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49981,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49982,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49983,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49984,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49985,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49986,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49987,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49988,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49989,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49990,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49991,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49992,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49993,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49994,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49995,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49996,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49997,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49998,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,49999,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50000,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50001,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50002,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50003,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50004,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50005,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50006,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50007,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50008,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50009,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50010,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50011,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50012,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50013,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50014,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50015,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50016,21,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50017,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50018,20,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50019,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50020,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50021,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50022,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50023,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50024,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50025,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50026,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50027,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50028,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50029,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50030,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50031,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50032,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50033,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50034,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50035,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50036,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50037,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50038,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50039,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50040,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50041,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50042,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50043,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50044,21,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50045,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50046,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50047,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50048,21,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50049,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50050,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50051,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50052,19,-60,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50053,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50054,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50055,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50056,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50057,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50058,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50059,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50060,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50061,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50062,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50063,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50064,21,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50065,21,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50066,20,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50067,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50068,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50069,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50070,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50071,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50072,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50073,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50074,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50075,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50076,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50077,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50078,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50079,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50080,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50081,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50082,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50083,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50084,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50085,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50086,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50087,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50088,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50089,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50090,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50091,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50092,20,-60,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50093,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50094,20,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50095,19,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50096,19,-61,0,0,0,0,0 + diff --git a/AOA_3(6m).txt b/AOA_3(6m).txt new file mode 100755 index 0000000..21a9382 --- /dev/null +++ b/AOA_3(6m).txt @@ -0,0 +1,558 @@ +$ORIEN,54:6C:0E:A0:42:58,0,50600,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50601,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50602,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50603,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50604,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50605,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50606,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50607,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50608,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50609,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50610,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50611,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50612,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50613,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50614,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50615,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50616,43,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50617,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50618,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50619,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50620,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50621,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50622,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50623,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50624,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50625,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50626,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50627,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50628,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50629,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50630,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50631,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50632,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50633,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50634,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50635,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50636,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50637,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50638,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50639,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50640,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50641,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50642,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50643,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50644,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50645,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50646,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50647,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50648,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50649,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50650,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50651,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50652,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50653,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50654,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50655,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50656,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50657,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50658,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50659,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50660,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50661,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50662,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50663,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50664,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50665,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50666,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50667,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50668,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50669,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50670,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50671,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50672,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50673,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50674,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50675,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50676,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50677,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50678,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50679,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50680,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50681,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50682,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50683,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50684,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50685,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50686,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50687,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50688,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50689,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50690,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50691,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50692,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50693,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50694,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50695,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50696,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50697,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50698,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50699,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50700,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50701,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50702,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50703,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50704,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50705,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50706,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50707,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50708,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50709,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50710,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50711,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50712,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50713,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50714,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50715,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50716,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50717,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50718,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50719,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50720,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50721,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50722,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50723,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50724,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50725,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50726,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50727,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50728,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50729,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50730,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50731,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50732,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50733,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50734,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50735,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50736,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50737,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50738,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50739,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50740,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50741,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50742,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50743,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50744,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50745,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50746,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50747,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50748,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50749,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50750,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50751,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50752,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50753,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50754,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50755,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50756,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50757,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50758,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50759,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50760,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50761,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50762,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50763,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50764,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50765,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50766,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50767,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50768,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50769,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50770,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50771,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50772,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50773,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50774,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50775,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50776,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50777,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50778,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50779,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50780,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50781,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50782,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50783,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50784,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50785,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50786,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50787,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50788,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50789,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50790,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50791,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50792,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50793,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50794,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50795,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50796,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50797,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50798,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50799,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50800,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50801,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50802,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50803,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50804,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50805,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50806,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50807,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50808,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50809,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50810,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50811,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50812,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50813,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50814,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50815,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50816,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50817,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50818,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50819,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50820,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50821,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50822,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50823,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50824,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50825,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50826,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50827,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50828,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50829,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50830,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50831,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50832,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50833,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50834,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50835,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50836,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50837,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50838,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50839,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50840,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50841,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50842,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50843,43,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50844,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50845,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50846,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50847,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50848,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50849,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50850,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50851,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50852,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50853,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50854,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50855,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50856,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50857,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50858,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50859,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50860,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50861,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50862,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50863,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50864,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50865,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50866,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50867,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50868,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50869,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50870,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50871,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50872,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50873,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50874,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50875,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50876,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50877,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50878,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50879,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50880,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50881,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50882,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50883,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50884,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50885,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50886,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50887,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50888,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50889,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50890,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50891,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50892,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50893,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50894,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50895,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50896,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50897,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50898,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50899,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50900,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50901,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50902,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50903,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50904,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50905,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50906,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50907,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50908,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50909,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50910,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50911,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50912,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50913,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50914,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50915,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50916,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50917,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50918,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50919,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50920,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50921,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50922,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50923,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50924,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50925,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50926,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50927,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50928,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50929,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50930,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50931,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50932,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50933,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50934,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50935,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50936,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50937,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50938,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50939,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50940,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50941,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50942,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50943,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50944,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50945,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50946,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50947,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50948,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50949,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50950,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50951,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50952,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50953,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50954,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50955,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50956,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50957,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50958,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50959,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50960,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50961,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50962,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50963,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50964,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50965,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50966,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50967,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50968,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50969,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50970,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50971,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50972,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50973,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50974,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50975,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50976,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50977,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50978,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50979,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50980,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50981,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50982,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50983,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50984,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50985,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50986,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50987,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50988,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50989,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50990,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,50991,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50992,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50993,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50994,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50995,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50996,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50997,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50998,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,50999,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51000,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51001,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51002,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51003,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51004,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51005,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51006,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51007,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51008,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51009,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51010,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51011,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51012,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51013,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51014,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51015,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51016,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51017,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51018,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51019,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51020,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51021,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51022,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51023,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51024,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51025,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51026,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51027,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51028,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51029,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51030,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51031,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51032,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51033,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51034,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51035,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51036,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51037,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51038,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51039,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51040,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51041,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51042,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51043,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51044,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51045,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51046,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51047,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51048,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51049,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51050,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51051,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51052,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51053,43,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51054,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51055,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51056,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51057,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51058,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51059,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51060,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51061,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51062,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51063,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51064,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51065,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51066,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51067,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51068,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51069,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51070,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51071,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51072,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51073,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51074,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51075,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51076,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51077,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51078,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51079,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51080,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51081,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51082,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51083,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51084,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51085,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51086,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51087,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51088,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51089,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51090,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51091,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51092,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51093,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51094,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51095,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51096,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51097,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51098,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51099,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51100,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51101,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51102,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51103,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51104,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51105,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51106,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51107,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51108,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51109,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51110,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51111,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51112,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51113,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51114,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51115,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51116,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51117,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51118,41,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51119,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51120,41,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51121,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51122,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51123,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51124,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51125,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51126,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51127,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51128,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51129,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51130,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51131,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51132,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51133,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51134,43,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51135,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51136,43,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51137,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51138,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51139,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51140,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51141,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51142,43,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51143,42,-59,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51144,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51145,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51146,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51147,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51148,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51149,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51150,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51151,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51152,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51153,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51154,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51155,42,-59,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51156,42,-59,0,0,0,0,0 + diff --git a/AOA_4(6m).txt b/AOA_4(6m).txt new file mode 100755 index 0000000..7ebf5c2 --- /dev/null +++ b/AOA_4(6m).txt @@ -0,0 +1,562 @@ +$ORIEN,54:6C:0E:A0:42:58,0,51709,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51710,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51711,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51712,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51713,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51714,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51715,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51716,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51717,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51718,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51719,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51720,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51721,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51722,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51723,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51724,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51725,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51726,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51727,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51728,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51729,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51730,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51731,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51732,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51733,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51734,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51735,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51736,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51737,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51738,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51739,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51740,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51741,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51742,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51743,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51744,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51745,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51746,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51747,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51748,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51749,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51750,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51751,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51752,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51753,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51754,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51755,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51756,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51757,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51758,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51759,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51760,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51761,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51762,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51763,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51764,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51765,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51766,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51767,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51768,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51769,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51770,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51771,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51772,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51773,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51774,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51775,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51776,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51777,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51778,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51779,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51780,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51781,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51782,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51783,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51784,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51785,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51786,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51787,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51788,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51789,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51790,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51791,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51792,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51793,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51794,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51795,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51796,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51797,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51798,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51799,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51800,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51801,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51802,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51803,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51804,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51805,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51806,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51807,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51808,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51809,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51810,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51811,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51812,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51813,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51814,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51815,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51816,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51817,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51818,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51819,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51820,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51821,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51822,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51823,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51824,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51825,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51826,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51827,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51828,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51829,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51830,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51831,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51832,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51833,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51834,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51835,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51836,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51837,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51838,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51839,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51840,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51841,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51842,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51843,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51844,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51845,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51846,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51847,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51848,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51849,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51850,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51851,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51852,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51853,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51854,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51855,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51856,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51857,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51858,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51859,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51860,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51861,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51862,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51863,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51864,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51865,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51866,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51867,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51868,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51869,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51870,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51871,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51872,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51873,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51874,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51875,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51876,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51877,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51878,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51879,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51880,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51881,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51882,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51883,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51884,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51885,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51886,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51887,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51888,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51889,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51890,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51891,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51892,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51893,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51894,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51895,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51896,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51897,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51898,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51899,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51900,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51901,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51902,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51903,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51904,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51905,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51906,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51907,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51908,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51909,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51910,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51911,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51912,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51913,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51914,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51915,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51916,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51917,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51918,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51919,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51920,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51921,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51922,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51923,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51924,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51925,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51926,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51927,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51928,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51929,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51930,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51931,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51932,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51933,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51934,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51935,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51936,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51937,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51938,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51939,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51940,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51941,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51942,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51943,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51944,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51945,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51946,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51947,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51948,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51949,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51950,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51951,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51952,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51953,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51954,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51955,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51956,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51957,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51958,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51959,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51960,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51961,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51962,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51963,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51964,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51965,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51966,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51967,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51968,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51969,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51970,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51971,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51972,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51973,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51974,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51975,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51976,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51977,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51978,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51979,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51980,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51981,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51982,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51983,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51984,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51985,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51986,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51987,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51988,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51989,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51990,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51991,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51992,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51993,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51994,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,51995,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51996,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51997,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51998,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,51999,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52000,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52001,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52002,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52003,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52004,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52005,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52006,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52007,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52008,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52009,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52010,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52011,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52012,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52013,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52014,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52015,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52016,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52017,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52018,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52019,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52020,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52021,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52022,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52023,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52024,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52025,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52026,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52027,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52028,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52029,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52030,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52031,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52032,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52033,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52034,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52035,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52036,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52037,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52038,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52039,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52040,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52041,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52042,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52043,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52044,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52045,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52046,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52047,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52048,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52049,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52050,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52051,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52052,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52053,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52054,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52055,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52056,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52057,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52058,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52059,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52060,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52061,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52062,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52063,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52064,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52065,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52066,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52067,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52068,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52069,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52070,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52071,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52072,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52073,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52074,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52075,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52076,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52077,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52078,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52079,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52080,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52081,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52082,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52083,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52084,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52085,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52086,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52087,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52088,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52089,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52090,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52091,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52092,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52093,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52094,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52095,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52096,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52097,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52098,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52099,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52100,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52101,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52102,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52103,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52104,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52105,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52106,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52107,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52108,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52109,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52110,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52111,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52112,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52113,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52114,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52115,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52116,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52117,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52118,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52119,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52120,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52121,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52122,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52123,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52124,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52125,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52126,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52127,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52128,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52129,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52130,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52131,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52132,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52133,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52134,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52135,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52136,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52137,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52138,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52139,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52140,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52141,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52142,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52143,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52144,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52145,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52146,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52147,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52148,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52149,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52150,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52151,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52152,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52153,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52154,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52155,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52156,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52157,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52158,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52159,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52160,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52161,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52162,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52163,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52164,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52165,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52166,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52167,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52168,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52169,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52170,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52171,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52172,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52173,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52174,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52175,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52176,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52177,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52178,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52179,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52180,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52181,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52182,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52183,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52184,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52185,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52186,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52187,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52188,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52189,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52190,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52191,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52192,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52193,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52194,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52195,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52196,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52197,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52198,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52199,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52200,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52201,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52202,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52203,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52204,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52205,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52206,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52207,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52208,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52209,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52210,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52211,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52212,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52213,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52214,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52215,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52216,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52217,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52218,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52219,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52220,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52221,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52222,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52223,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52224,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52225,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52226,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52227,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52228,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52229,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52230,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52231,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52232,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52233,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52234,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52235,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52236,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52237,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52238,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52239,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52240,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52241,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52242,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52243,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52244,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52245,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52246,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52247,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52248,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52249,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52250,81,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52251,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52252,81,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52253,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52254,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52255,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52256,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52257,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52258,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52259,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52260,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52261,83,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52262,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52263,83,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52264,82,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52265,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52266,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52267,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52268,82,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52269,82,-62,0,0,0,0,0 + diff --git a/AOA_5(6m).txt b/AOA_5(6m).txt new file mode 100755 index 0000000..c382468 --- /dev/null +++ b/AOA_5(6m).txt @@ -0,0 +1,558 @@ +$ORIEN,54:6C:0E:A0:42:58,0,52824,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52825,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52826,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52827,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52828,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52829,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52830,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52831,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52832,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52833,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52834,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52835,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52836,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52837,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52838,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52839,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52840,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52841,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52842,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52843,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52844,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52845,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52846,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52847,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52848,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52849,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52850,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52851,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52852,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52853,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52854,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52855,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52856,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52857,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52858,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52859,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52860,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52861,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52862,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52863,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52864,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52865,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52866,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52867,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52868,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52869,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52870,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52871,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52872,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52873,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52874,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52875,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52876,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52877,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52878,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52879,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52880,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52881,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52882,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52883,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52884,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52885,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52886,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52887,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52888,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52889,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52890,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52891,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52892,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52893,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52894,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52895,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52896,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52897,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52898,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52899,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52900,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52901,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52902,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52903,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52904,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52905,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52906,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52907,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52908,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52909,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52910,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52911,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52912,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52913,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52914,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52915,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52916,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52917,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52918,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52919,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52920,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52921,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52922,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52923,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52924,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52925,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52926,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52927,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52928,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52929,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52930,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52931,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52932,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52933,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52934,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52935,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52936,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52937,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52938,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52939,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52940,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52941,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52942,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52943,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52944,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52945,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52946,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52947,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52948,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52949,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52950,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52951,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52952,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52953,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52954,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52955,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52956,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52957,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52958,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52959,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52960,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52961,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52962,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52963,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52964,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52965,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52966,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52967,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52968,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52969,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52970,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52971,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52972,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52973,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52974,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52975,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52976,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52977,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52978,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52979,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52980,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52981,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52982,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52983,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52984,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52985,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52986,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52987,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52988,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52989,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52990,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52991,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52992,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52993,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52994,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52995,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52996,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,52997,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52998,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,52999,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53000,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53001,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53002,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53003,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53004,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53005,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53006,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53007,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53008,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53009,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53010,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53011,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53012,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53013,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53014,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53015,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53016,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53017,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53018,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53019,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53020,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53021,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53022,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53023,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53024,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53025,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53026,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53027,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53028,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53029,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53030,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53031,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53032,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53033,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53034,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53035,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53036,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53037,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53038,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53039,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53040,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53041,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53042,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53043,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53044,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53045,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53046,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53047,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53048,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53049,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53050,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53051,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53052,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53053,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53054,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53055,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53056,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53057,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53058,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53059,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53060,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53061,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53062,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53063,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53064,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53065,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53066,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53067,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53068,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53069,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53070,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53071,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53072,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53073,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53074,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53075,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53076,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53077,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53078,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53079,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53080,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53081,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53082,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53083,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53084,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53085,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53086,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53087,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53088,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53089,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53090,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53091,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53092,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53093,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53094,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53095,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53096,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53097,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53098,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53099,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53100,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53101,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53102,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53103,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53104,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53105,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53106,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53107,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53108,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53109,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53110,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53111,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53112,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53113,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53114,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53115,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53116,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53117,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53118,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53119,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53120,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53121,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53122,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53123,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53124,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53125,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53126,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53127,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53128,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53129,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53130,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53131,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53132,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53133,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53134,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53135,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53136,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53137,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53138,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53139,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53140,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53141,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53142,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53143,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53144,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53145,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53146,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53147,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53148,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53149,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53150,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53151,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53152,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53153,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53154,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53155,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53156,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53157,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53158,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53159,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53160,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53161,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53162,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53163,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53164,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53165,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53166,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53167,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53168,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53169,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53170,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53171,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53172,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53173,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53174,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53175,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53176,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53177,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53178,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53179,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53180,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53181,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53182,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53183,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53184,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53185,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53186,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53187,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53188,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53189,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53190,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53191,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53192,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53193,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53194,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53195,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53196,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53197,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53198,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53199,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53200,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53201,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53202,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53203,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53204,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53205,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53206,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53207,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53208,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53209,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53210,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53211,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53212,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53213,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53214,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53215,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53216,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53217,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53218,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53219,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53220,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53221,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53222,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53223,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53224,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53225,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53226,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53227,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53228,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53229,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53230,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53231,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53232,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53233,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53234,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53235,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53236,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53237,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53238,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53239,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53240,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53241,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53242,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53243,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53244,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53245,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53246,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53247,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53248,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53249,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53250,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53251,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53252,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53253,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53254,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53255,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53256,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53257,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53258,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53259,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53260,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53261,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53262,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53263,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53264,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53265,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53266,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53267,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53268,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53269,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53270,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53271,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53272,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53273,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53274,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53275,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53276,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53277,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53278,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53279,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53280,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53281,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53282,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53283,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53284,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53285,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53286,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53287,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53288,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53289,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53290,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53291,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53292,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53293,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53294,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53295,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53296,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53297,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53298,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53299,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53300,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53301,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53302,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53303,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53304,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53305,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53306,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53307,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53308,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53309,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53310,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53311,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53312,101,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53313,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53314,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53315,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53316,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53317,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53318,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53319,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53320,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53321,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53322,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53323,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53324,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53325,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53326,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53327,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53328,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53329,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53330,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53331,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53332,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53333,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53334,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53335,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53336,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53337,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53338,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53339,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53340,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53341,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53342,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53343,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53344,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53345,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53346,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53347,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53348,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53349,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53350,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53351,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53352,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53353,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53354,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53355,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53356,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53357,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53358,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53359,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53360,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53361,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53362,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53363,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53364,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53365,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53366,101,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53367,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53368,101,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53369,102,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,53370,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53371,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53372,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53373,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53374,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53375,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53376,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53377,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53378,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53379,102,-61,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,53380,102,-61,0,0,0,0,0 + diff --git a/Auswertung_AOA.py b/Auswertung_AOA.py new file mode 100755 index 0000000..c207d21 --- /dev/null +++ b/Auswertung_AOA.py @@ -0,0 +1,25 @@ +#! /usr/bin/python +import numpy as np +import matplotlib.pyplot as plt + +AoA_point_estimated = 120 + +import csv +with open('AOA_-5(6m).txt','r') as f: + lines = list(csv.reader(f, delimiter = ',', skipinitialspace = True)) # Printing Specific Part of CSV_file + #print(lines[0][4]) # Printing last line of second column + x = np.arange(len(lines)-5) + y = [] + for i in range(len(lines)-5): + C = int(lines[i][4]) + #Angle_diff = C - AoA_point_3 + y.append(C) + #print(y) +plt.plot(x , y, "-g", label="AOA") + +print(np.max(y), np.min(y), np.average(y), np.median(y)) + +plt.ylabel("AOA_diff") +plt.xlabel("BurstID") +plt.title("AoA_point_-5_Average") +plt.show() \ No newline at end of file diff --git a/Lib/site-packages/easy-install.pth b/Lib/site-packages/easy-install.pth new file mode 100755 index 0000000..c246fdb --- /dev/null +++ b/Lib/site-packages/easy-install.pth @@ -0,0 +1,2 @@ +./setuptools-40.8.0-py3.7.egg +./pip-19.0.3-py3.7.egg diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/PKG-INFO b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/PKG-INFO new file mode 100755 index 0000000..51d4230 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,73 @@ +Metadata-Version: 1.2 +Name: pip +Version: 19.0.3 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: pypa-dev@groups.google.com +License: MIT +Description: pip - The Python Package Installer + ================================== + + .. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + + .. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + + pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. + + Please take a look at our documentation for how to install and use pip: + + * `Installation`_ + * `Usage`_ + * `Release notes`_ + + If you find bugs, need help, or want to talk to the developers please use our mailing lists or chat rooms: + + * `Issue tracking`_ + * `Discourse channel`_ + * `User IRC`_ + + If you want to get involved head over to GitHub to get the source code and feel free to jump on the developer mailing lists and chat rooms: + + * `GitHub page`_ + * `Dev mailing list`_ + * `Dev IRC`_ + + Code of Conduct + --------------- + + Everyone interacting in the pip project's codebases, issue trackers, chat + rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + + .. _package installer: https://packaging.python.org/en/latest/current/ + .. _Python Package Index: https://pypi.org + .. _Installation: https://pip.pypa.io/en/stable/installing.html + .. _Usage: https://pip.pypa.io/en/stable/ + .. _Release notes: https://pip.pypa.io/en/stable/news.html + .. _GitHub page: https://github.com/pypa/pip + .. _Issue tracking: https://github.com/pypa/pip/issues + .. _Discourse channel: https://discuss.python.org/c/packaging + .. _Dev mailing list: https://groups.google.com/forum/#!forum/pypa-dev + .. _User IRC: https://webchat.freenode.net/?channels=%23pypa + .. _Dev IRC: https://webchat.freenode.net/?channels=%23pypa-dev + .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + +Keywords: distutils easy_install egg setuptools wheel virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/SOURCES.txt b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/SOURCES.txt new file mode 100755 index 0000000..eb4810d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,391 @@ +AUTHORS.txt +LICENSE.txt +MANIFEST.in +NEWS.rst +README.rst +pyproject.toml +setup.cfg +setup.py +docs/pip_sphinxext.py +docs/html/conf.py +docs/html/cookbook.rst +docs/html/index.rst +docs/html/installing.rst +docs/html/logic.rst +docs/html/news.rst +docs/html/quickstart.rst +docs/html/usage.rst +docs/html/user_guide.rst +docs/html/development/configuration.rst +docs/html/development/contributing.rst +docs/html/development/getting-started.rst +docs/html/development/index.rst +docs/html/development/release-process.rst +docs/html/development/vendoring-policy.rst +docs/html/reference/index.rst +docs/html/reference/pip.rst +docs/html/reference/pip_check.rst +docs/html/reference/pip_config.rst +docs/html/reference/pip_download.rst +docs/html/reference/pip_freeze.rst +docs/html/reference/pip_hash.rst +docs/html/reference/pip_install.rst +docs/html/reference/pip_list.rst +docs/html/reference/pip_search.rst +docs/html/reference/pip_show.rst +docs/html/reference/pip_uninstall.rst +docs/html/reference/pip_wheel.rst +docs/man/index.rst +docs/man/commands/check.rst +docs/man/commands/config.rst +docs/man/commands/download.rst +docs/man/commands/freeze.rst +docs/man/commands/hash.rst +docs/man/commands/help.rst +docs/man/commands/install.rst +docs/man/commands/list.rst +docs/man/commands/search.rst +docs/man/commands/show.rst +docs/man/commands/uninstall.rst +docs/man/commands/wheel.rst +src/pip/__init__.py +src/pip/__main__.py +src/pip.egg-info/PKG-INFO +src/pip.egg-info/SOURCES.txt +src/pip.egg-info/dependency_links.txt +src/pip.egg-info/entry_points.txt +src/pip.egg-info/not-zip-safe +src/pip.egg-info/top_level.txt +src/pip/_internal/__init__.py +src/pip/_internal/build_env.py +src/pip/_internal/cache.py +src/pip/_internal/configuration.py +src/pip/_internal/download.py +src/pip/_internal/exceptions.py +src/pip/_internal/index.py +src/pip/_internal/locations.py +src/pip/_internal/pep425tags.py +src/pip/_internal/pyproject.py +src/pip/_internal/resolve.py +src/pip/_internal/wheel.py +src/pip/_internal/cli/__init__.py +src/pip/_internal/cli/autocompletion.py +src/pip/_internal/cli/base_command.py +src/pip/_internal/cli/cmdoptions.py +src/pip/_internal/cli/main_parser.py +src/pip/_internal/cli/parser.py +src/pip/_internal/cli/status_codes.py +src/pip/_internal/commands/__init__.py +src/pip/_internal/commands/check.py +src/pip/_internal/commands/completion.py +src/pip/_internal/commands/configuration.py +src/pip/_internal/commands/download.py +src/pip/_internal/commands/freeze.py +src/pip/_internal/commands/hash.py +src/pip/_internal/commands/help.py +src/pip/_internal/commands/install.py +src/pip/_internal/commands/list.py +src/pip/_internal/commands/search.py +src/pip/_internal/commands/show.py +src/pip/_internal/commands/uninstall.py +src/pip/_internal/commands/wheel.py +src/pip/_internal/models/__init__.py +src/pip/_internal/models/candidate.py +src/pip/_internal/models/format_control.py +src/pip/_internal/models/index.py +src/pip/_internal/models/link.py +src/pip/_internal/operations/__init__.py +src/pip/_internal/operations/check.py +src/pip/_internal/operations/freeze.py +src/pip/_internal/operations/prepare.py +src/pip/_internal/req/__init__.py +src/pip/_internal/req/constructors.py +src/pip/_internal/req/req_file.py +src/pip/_internal/req/req_install.py +src/pip/_internal/req/req_set.py +src/pip/_internal/req/req_tracker.py +src/pip/_internal/req/req_uninstall.py +src/pip/_internal/utils/__init__.py +src/pip/_internal/utils/appdirs.py +src/pip/_internal/utils/compat.py +src/pip/_internal/utils/deprecation.py +src/pip/_internal/utils/encoding.py +src/pip/_internal/utils/filesystem.py +src/pip/_internal/utils/glibc.py +src/pip/_internal/utils/hashes.py +src/pip/_internal/utils/logging.py +src/pip/_internal/utils/misc.py +src/pip/_internal/utils/models.py +src/pip/_internal/utils/outdated.py +src/pip/_internal/utils/packaging.py +src/pip/_internal/utils/setuptools_build.py +src/pip/_internal/utils/temp_dir.py +src/pip/_internal/utils/typing.py +src/pip/_internal/utils/ui.py +src/pip/_internal/vcs/__init__.py +src/pip/_internal/vcs/bazaar.py +src/pip/_internal/vcs/git.py +src/pip/_internal/vcs/mercurial.py +src/pip/_internal/vcs/subversion.py +src/pip/_vendor/README.rst +src/pip/_vendor/__init__.py +src/pip/_vendor/appdirs.LICENSE.txt +src/pip/_vendor/appdirs.py +src/pip/_vendor/distro.LICENSE +src/pip/_vendor/distro.py +src/pip/_vendor/ipaddress.LICENSE +src/pip/_vendor/ipaddress.py +src/pip/_vendor/pyparsing.LICENSE +src/pip/_vendor/pyparsing.py +src/pip/_vendor/retrying.LICENSE +src/pip/_vendor/retrying.py +src/pip/_vendor/six.LICENSE +src/pip/_vendor/six.py +src/pip/_vendor/vendor.txt +src/pip/_vendor/cachecontrol/LICENSE.txt +src/pip/_vendor/cachecontrol/__init__.py +src/pip/_vendor/cachecontrol/_cmd.py +src/pip/_vendor/cachecontrol/adapter.py +src/pip/_vendor/cachecontrol/cache.py +src/pip/_vendor/cachecontrol/compat.py +src/pip/_vendor/cachecontrol/controller.py +src/pip/_vendor/cachecontrol/filewrapper.py +src/pip/_vendor/cachecontrol/heuristics.py +src/pip/_vendor/cachecontrol/serialize.py +src/pip/_vendor/cachecontrol/wrapper.py +src/pip/_vendor/cachecontrol/caches/__init__.py +src/pip/_vendor/cachecontrol/caches/file_cache.py +src/pip/_vendor/cachecontrol/caches/redis_cache.py +src/pip/_vendor/certifi/LICENSE +src/pip/_vendor/certifi/__init__.py +src/pip/_vendor/certifi/__main__.py +src/pip/_vendor/certifi/cacert.pem +src/pip/_vendor/certifi/core.py +src/pip/_vendor/chardet/LICENSE +src/pip/_vendor/chardet/__init__.py +src/pip/_vendor/chardet/big5freq.py +src/pip/_vendor/chardet/big5prober.py +src/pip/_vendor/chardet/chardistribution.py +src/pip/_vendor/chardet/charsetgroupprober.py +src/pip/_vendor/chardet/charsetprober.py +src/pip/_vendor/chardet/codingstatemachine.py +src/pip/_vendor/chardet/compat.py +src/pip/_vendor/chardet/cp949prober.py +src/pip/_vendor/chardet/enums.py +src/pip/_vendor/chardet/escprober.py +src/pip/_vendor/chardet/escsm.py +src/pip/_vendor/chardet/eucjpprober.py +src/pip/_vendor/chardet/euckrfreq.py +src/pip/_vendor/chardet/euckrprober.py +src/pip/_vendor/chardet/euctwfreq.py +src/pip/_vendor/chardet/euctwprober.py +src/pip/_vendor/chardet/gb2312freq.py +src/pip/_vendor/chardet/gb2312prober.py +src/pip/_vendor/chardet/hebrewprober.py +src/pip/_vendor/chardet/jisfreq.py +src/pip/_vendor/chardet/jpcntx.py +src/pip/_vendor/chardet/langbulgarianmodel.py +src/pip/_vendor/chardet/langcyrillicmodel.py +src/pip/_vendor/chardet/langgreekmodel.py +src/pip/_vendor/chardet/langhebrewmodel.py +src/pip/_vendor/chardet/langhungarianmodel.py +src/pip/_vendor/chardet/langthaimodel.py +src/pip/_vendor/chardet/langturkishmodel.py +src/pip/_vendor/chardet/latin1prober.py +src/pip/_vendor/chardet/mbcharsetprober.py +src/pip/_vendor/chardet/mbcsgroupprober.py +src/pip/_vendor/chardet/mbcssm.py +src/pip/_vendor/chardet/sbcharsetprober.py +src/pip/_vendor/chardet/sbcsgroupprober.py +src/pip/_vendor/chardet/sjisprober.py +src/pip/_vendor/chardet/universaldetector.py +src/pip/_vendor/chardet/utf8prober.py +src/pip/_vendor/chardet/version.py +src/pip/_vendor/chardet/cli/__init__.py +src/pip/_vendor/chardet/cli/chardetect.py +src/pip/_vendor/colorama/LICENSE.txt +src/pip/_vendor/colorama/__init__.py +src/pip/_vendor/colorama/ansi.py +src/pip/_vendor/colorama/ansitowin32.py +src/pip/_vendor/colorama/initialise.py +src/pip/_vendor/colorama/win32.py +src/pip/_vendor/colorama/winterm.py +src/pip/_vendor/distlib/LICENSE.txt +src/pip/_vendor/distlib/__init__.py +src/pip/_vendor/distlib/compat.py +src/pip/_vendor/distlib/database.py +src/pip/_vendor/distlib/index.py +src/pip/_vendor/distlib/locators.py +src/pip/_vendor/distlib/manifest.py +src/pip/_vendor/distlib/markers.py +src/pip/_vendor/distlib/metadata.py +src/pip/_vendor/distlib/resources.py +src/pip/_vendor/distlib/scripts.py +src/pip/_vendor/distlib/t32.exe +src/pip/_vendor/distlib/t64.exe +src/pip/_vendor/distlib/util.py +src/pip/_vendor/distlib/version.py +src/pip/_vendor/distlib/w32.exe +src/pip/_vendor/distlib/w64.exe +src/pip/_vendor/distlib/wheel.py +src/pip/_vendor/distlib/_backport/__init__.py +src/pip/_vendor/distlib/_backport/misc.py +src/pip/_vendor/distlib/_backport/shutil.py +src/pip/_vendor/distlib/_backport/sysconfig.cfg +src/pip/_vendor/distlib/_backport/sysconfig.py +src/pip/_vendor/distlib/_backport/tarfile.py +src/pip/_vendor/html5lib/LICENSE +src/pip/_vendor/html5lib/__init__.py +src/pip/_vendor/html5lib/_ihatexml.py +src/pip/_vendor/html5lib/_inputstream.py +src/pip/_vendor/html5lib/_tokenizer.py +src/pip/_vendor/html5lib/_utils.py +src/pip/_vendor/html5lib/constants.py +src/pip/_vendor/html5lib/html5parser.py +src/pip/_vendor/html5lib/serializer.py +src/pip/_vendor/html5lib/_trie/__init__.py +src/pip/_vendor/html5lib/_trie/_base.py +src/pip/_vendor/html5lib/_trie/datrie.py +src/pip/_vendor/html5lib/_trie/py.py +src/pip/_vendor/html5lib/filters/__init__.py +src/pip/_vendor/html5lib/filters/alphabeticalattributes.py +src/pip/_vendor/html5lib/filters/base.py +src/pip/_vendor/html5lib/filters/inject_meta_charset.py +src/pip/_vendor/html5lib/filters/lint.py +src/pip/_vendor/html5lib/filters/optionaltags.py +src/pip/_vendor/html5lib/filters/sanitizer.py +src/pip/_vendor/html5lib/filters/whitespace.py +src/pip/_vendor/html5lib/treeadapters/__init__.py +src/pip/_vendor/html5lib/treeadapters/genshi.py +src/pip/_vendor/html5lib/treeadapters/sax.py +src/pip/_vendor/html5lib/treebuilders/__init__.py +src/pip/_vendor/html5lib/treebuilders/base.py +src/pip/_vendor/html5lib/treebuilders/dom.py +src/pip/_vendor/html5lib/treebuilders/etree.py +src/pip/_vendor/html5lib/treebuilders/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/__init__.py +src/pip/_vendor/html5lib/treewalkers/base.py +src/pip/_vendor/html5lib/treewalkers/dom.py +src/pip/_vendor/html5lib/treewalkers/etree.py +src/pip/_vendor/html5lib/treewalkers/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/genshi.py +src/pip/_vendor/idna/LICENSE.rst +src/pip/_vendor/idna/__init__.py +src/pip/_vendor/idna/codec.py +src/pip/_vendor/idna/compat.py +src/pip/_vendor/idna/core.py +src/pip/_vendor/idna/idnadata.py +src/pip/_vendor/idna/intranges.py +src/pip/_vendor/idna/package_data.py +src/pip/_vendor/idna/uts46data.py +src/pip/_vendor/lockfile/LICENSE +src/pip/_vendor/lockfile/__init__.py +src/pip/_vendor/lockfile/linklockfile.py +src/pip/_vendor/lockfile/mkdirlockfile.py +src/pip/_vendor/lockfile/pidlockfile.py +src/pip/_vendor/lockfile/sqlitelockfile.py +src/pip/_vendor/lockfile/symlinklockfile.py +src/pip/_vendor/msgpack/COPYING +src/pip/_vendor/msgpack/__init__.py +src/pip/_vendor/msgpack/_version.py +src/pip/_vendor/msgpack/exceptions.py +src/pip/_vendor/msgpack/fallback.py +src/pip/_vendor/packaging/LICENSE +src/pip/_vendor/packaging/LICENSE.APACHE +src/pip/_vendor/packaging/LICENSE.BSD +src/pip/_vendor/packaging/__about__.py +src/pip/_vendor/packaging/__init__.py +src/pip/_vendor/packaging/_compat.py +src/pip/_vendor/packaging/_structures.py +src/pip/_vendor/packaging/markers.py +src/pip/_vendor/packaging/requirements.py +src/pip/_vendor/packaging/specifiers.py +src/pip/_vendor/packaging/utils.py +src/pip/_vendor/packaging/version.py +src/pip/_vendor/pep517/LICENSE +src/pip/_vendor/pep517/__init__.py +src/pip/_vendor/pep517/_in_process.py +src/pip/_vendor/pep517/build.py +src/pip/_vendor/pep517/check.py +src/pip/_vendor/pep517/colorlog.py +src/pip/_vendor/pep517/compat.py +src/pip/_vendor/pep517/envbuild.py +src/pip/_vendor/pep517/wrappers.py +src/pip/_vendor/pkg_resources/LICENSE +src/pip/_vendor/pkg_resources/__init__.py +src/pip/_vendor/pkg_resources/py31compat.py +src/pip/_vendor/progress/LICENSE +src/pip/_vendor/progress/__init__.py +src/pip/_vendor/progress/bar.py +src/pip/_vendor/progress/counter.py +src/pip/_vendor/progress/helpers.py +src/pip/_vendor/progress/spinner.py +src/pip/_vendor/pytoml/LICENSE +src/pip/_vendor/pytoml/__init__.py +src/pip/_vendor/pytoml/core.py +src/pip/_vendor/pytoml/parser.py +src/pip/_vendor/pytoml/test.py +src/pip/_vendor/pytoml/utils.py +src/pip/_vendor/pytoml/writer.py +src/pip/_vendor/requests/LICENSE +src/pip/_vendor/requests/__init__.py +src/pip/_vendor/requests/__version__.py +src/pip/_vendor/requests/_internal_utils.py +src/pip/_vendor/requests/adapters.py +src/pip/_vendor/requests/api.py +src/pip/_vendor/requests/auth.py +src/pip/_vendor/requests/certs.py +src/pip/_vendor/requests/compat.py +src/pip/_vendor/requests/cookies.py +src/pip/_vendor/requests/exceptions.py +src/pip/_vendor/requests/help.py +src/pip/_vendor/requests/hooks.py +src/pip/_vendor/requests/models.py +src/pip/_vendor/requests/packages.py +src/pip/_vendor/requests/sessions.py +src/pip/_vendor/requests/status_codes.py +src/pip/_vendor/requests/structures.py +src/pip/_vendor/requests/utils.py +src/pip/_vendor/urllib3/LICENSE.txt +src/pip/_vendor/urllib3/__init__.py +src/pip/_vendor/urllib3/_collections.py +src/pip/_vendor/urllib3/connection.py +src/pip/_vendor/urllib3/connectionpool.py +src/pip/_vendor/urllib3/exceptions.py +src/pip/_vendor/urllib3/fields.py +src/pip/_vendor/urllib3/filepost.py +src/pip/_vendor/urllib3/poolmanager.py +src/pip/_vendor/urllib3/request.py +src/pip/_vendor/urllib3/response.py +src/pip/_vendor/urllib3/contrib/__init__.py +src/pip/_vendor/urllib3/contrib/_appengine_environ.py +src/pip/_vendor/urllib3/contrib/appengine.py +src/pip/_vendor/urllib3/contrib/ntlmpool.py +src/pip/_vendor/urllib3/contrib/pyopenssl.py +src/pip/_vendor/urllib3/contrib/securetransport.py +src/pip/_vendor/urllib3/contrib/socks.py +src/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +src/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +src/pip/_vendor/urllib3/packages/__init__.py +src/pip/_vendor/urllib3/packages/six.py +src/pip/_vendor/urllib3/packages/backports/__init__.py +src/pip/_vendor/urllib3/packages/backports/makefile.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py +src/pip/_vendor/urllib3/util/__init__.py +src/pip/_vendor/urllib3/util/connection.py +src/pip/_vendor/urllib3/util/queue.py +src/pip/_vendor/urllib3/util/request.py +src/pip/_vendor/urllib3/util/response.py +src/pip/_vendor/urllib3/util/retry.py +src/pip/_vendor/urllib3/util/ssl_.py +src/pip/_vendor/urllib3/util/timeout.py +src/pip/_vendor/urllib3/util/url.py +src/pip/_vendor/urllib3/util/wait.py +src/pip/_vendor/webencodings/LICENSE +src/pip/_vendor/webencodings/__init__.py +src/pip/_vendor/webencodings/labels.py +src/pip/_vendor/webencodings/mklabels.py +src/pip/_vendor/webencodings/tests.py +src/pip/_vendor/webencodings/x_user_defined.py \ No newline at end of file diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/dependency_links.txt b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/dependency_links.txt new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/entry_points.txt b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/entry_points.txt new file mode 100755 index 0000000..f5809cb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal:main +pip3 = pip._internal:main +pip3.7 = pip._internal:main + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/not-zip-safe b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/not-zip-safe new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/top_level.txt b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/top_level.txt new file mode 100755 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__init__.py new file mode 100755 index 0000000..f48c1ca --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__init__.py @@ -0,0 +1 @@ +__version__ = "19.0.3" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__main__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__main__.py new file mode 100755 index 0000000..0c223f8 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/__main__.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import os +import sys + +# If we are running from a wheel, add the wheel to sys.path +# This allows the usage python pip-*.whl/pip install pip-*.whl +if __package__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal import main as _main # isort:skip # noqa + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/__init__.py new file mode 100755 index 0000000..276124d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/__init__.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +import locale +import logging +import os +import warnings + +import sys + +# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, +# but if invoked (i.e. imported), it will issue a warning to stderr if socks +# isn't available. requests unconditionally imports urllib3's socks contrib +# module, triggering this warning. The warning breaks DEP-8 tests (because of +# the stderr output) and is just plain annoying in normal usage. I don't want +# to add socks as yet another dependency for pip, nor do I want to allow-stder +# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to +# be done before the import of pip.vcs. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.filterwarnings("ignore", category=DependencyWarning) # noqa + +# We want to inject the use of SecureTransport as early as possible so that any +# references or sessions or what have you are ensured to have it, however we +# only want to do this in the case that we're running on macOS and the linked +# OpenSSL is too old to handle TLSv1.2 +try: + import ssl +except ImportError: + pass +else: + # Checks for OpenSSL 1.0.1 on MacOS + if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + pass + else: + securetransport.inject_into_urllib3() + +from pip._internal.cli.autocompletion import autocomplete +from pip._internal.cli.main_parser import parse_command +from pip._internal.commands import commands_dict +from pip._internal.exceptions import PipError +from pip._internal.utils import deprecation +from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +logger = logging.getLogger(__name__) + +# Hide the InsecureRequestWarning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + autocomplete() + + try: + cmd_name, cmd_args = parse_command(args) + except PipError as exc: + sys.stderr.write("ERROR: %s" % exc) + sys.stderr.write(os.linesep) + sys.exit(1) + + # Needed for locale.getpreferredencoding(False) to work + # in pip._internal.utils.encoding.auto_decode + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as e: + # setlocale can apparently crash if locale are uninitialized + logger.debug("Ignoring error %s when setting locale", e) + command = commands_dict[cmd_name](isolated=("--isolated" in cmd_args)) + return command.main(cmd_args) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/build_env.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/build_env.py new file mode 100755 index 0000000..d744cc7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/build_env.py @@ -0,0 +1,215 @@ +"""Build Environment used for isolation during sdist building +""" + +import logging +import os +import sys +import textwrap +from collections import OrderedDict +from distutils.sysconfig import get_python_lib +from sysconfig import get_paths + +from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet + +from pip import __file__ as pip_location +from pip._internal.utils.misc import call_subprocess +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner + +if MYPY_CHECK_RUNNING: + from typing import Tuple, Set, Iterable, Optional, List # noqa: F401 + from pip._internal.index import PackageFinder # noqa: F401 + +logger = logging.getLogger(__name__) + + +class _Prefix: + + def __init__(self, path): + # type: (str) -> None + self.path = path + self.setup = False + self.bin_dir = get_paths( + 'nt' if os.name == 'nt' else 'posix_prefix', + vars={'base': path, 'platbase': path} + )['scripts'] + # Note: prefer distutils' sysconfig to get the + # library paths so PyPy is correctly supported. + purelib = get_python_lib(plat_specific=False, prefix=path) + platlib = get_python_lib(plat_specific=True, prefix=path) + if purelib == platlib: + self.lib_dirs = [purelib] + else: + self.lib_dirs = [purelib, platlib] + + +class BuildEnvironment(object): + """Creates and manages an isolated environment to install build deps + """ + + def __init__(self): + # type: () -> None + self._temp_dir = TempDirectory(kind="build-env") + self._temp_dir.create() + + self._prefixes = OrderedDict(( + (name, _Prefix(os.path.join(self._temp_dir.path, name))) + for name in ('normal', 'overlay') + )) + + self._bin_dirs = [] # type: List[str] + self._lib_dirs = [] # type: List[str] + for prefix in reversed(list(self._prefixes.values())): + self._bin_dirs.append(prefix.bin_dir) + self._lib_dirs.extend(prefix.lib_dirs) + + # Customize site to: + # - ensure .pth files are honored + # - prevent access to system site packages + system_sites = { + os.path.normcase(site) for site in ( + get_python_lib(plat_specific=False), + get_python_lib(plat_specific=True), + ) + } + self._site_dir = os.path.join(self._temp_dir.path, 'site') + if not os.path.exists(self._site_dir): + os.mkdir(self._site_dir) + with open(os.path.join(self._site_dir, 'sitecustomize.py'), 'w') as fp: + fp.write(textwrap.dedent( + ''' + import os, site, sys + + # First, drop system-sites related paths. + original_sys_path = sys.path[:] + known_paths = set() + for path in {system_sites!r}: + site.addsitedir(path, known_paths=known_paths) + system_paths = set( + os.path.normcase(path) + for path in sys.path[len(original_sys_path):] + ) + original_sys_path = [ + path for path in original_sys_path + if os.path.normcase(path) not in system_paths + ] + sys.path = original_sys_path + + # Second, add lib directories. + # ensuring .pth file are processed. + for path in {lib_dirs!r}: + assert not path in sys.path + site.addsitedir(path) + ''' + ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)) + + def __enter__(self): + self._save_env = { + name: os.environ.get(name, None) + for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH') + } + + path = self._bin_dirs[:] + old_path = self._save_env['PATH'] + if old_path: + path.extend(old_path.split(os.pathsep)) + + pythonpath = [self._site_dir] + + os.environ.update({ + 'PATH': os.pathsep.join(path), + 'PYTHONNOUSERSITE': '1', + 'PYTHONPATH': os.pathsep.join(pythonpath), + }) + + def __exit__(self, exc_type, exc_val, exc_tb): + for varname, old_value in self._save_env.items(): + if old_value is None: + os.environ.pop(varname, None) + else: + os.environ[varname] = old_value + + def cleanup(self): + # type: () -> None + self._temp_dir.cleanup() + + def check_requirements(self, reqs): + # type: (Iterable[str]) -> Tuple[Set[Tuple[str, str]], Set[str]] + """Return 2 sets: + - conflicting requirements: set of (installed, wanted) reqs tuples + - missing requirements: set of reqs + """ + missing = set() + conflicting = set() + if reqs: + ws = WorkingSet(self._lib_dirs) + for req in reqs: + try: + if ws.find(Requirement.parse(req)) is None: + missing.add(req) + except VersionConflict as e: + conflicting.add((str(e.args[0].as_requirement()), + str(e.args[1]))) + return conflicting, missing + + def install_requirements( + self, + finder, # type: PackageFinder + requirements, # type: Iterable[str] + prefix_as_string, # type: str + message # type: Optional[str] + ): + # type: (...) -> None + prefix = self._prefixes[prefix_as_string] + assert not prefix.setup + prefix.setup = True + if not requirements: + return + args = [ + sys.executable, os.path.dirname(pip_location), 'install', + '--ignore-installed', '--no-user', '--prefix', prefix.path, + '--no-warn-script-location', + ] # type: List[str] + if logger.getEffectiveLevel() <= logging.DEBUG: + args.append('-v') + for format_control in ('no_binary', 'only_binary'): + formats = getattr(finder.format_control, format_control) + args.extend(('--' + format_control.replace('_', '-'), + ','.join(sorted(formats or {':none:'})))) + if finder.index_urls: + args.extend(['-i', finder.index_urls[0]]) + for extra_index in finder.index_urls[1:]: + args.extend(['--extra-index-url', extra_index]) + else: + args.append('--no-index') + for link in finder.find_links: + args.extend(['--find-links', link]) + for _, host, _ in finder.secure_origins: + args.extend(['--trusted-host', host]) + if finder.allow_all_prereleases: + args.append('--pre') + args.append('--') + args.extend(requirements) + with open_spinner(message) as spinner: + call_subprocess(args, show_stdout=False, spinner=spinner) + + +class NoOpBuildEnvironment(BuildEnvironment): + """A no-op drop-in replacement for BuildEnvironment + """ + + def __init__(self): + pass + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def cleanup(self): + pass + + def install_requirements(self, finder, requirements, prefix, message): + raise NotImplementedError() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cache.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cache.py new file mode 100755 index 0000000..eb295c4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cache.py @@ -0,0 +1,224 @@ +"""Cache Management +""" + +import errno +import hashlib +import logging +import os + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.download import path_to_url +from pip._internal.models.link import Link +from pip._internal.utils.compat import expanduser +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.wheel import InvalidWheelFilename, Wheel + +if MYPY_CHECK_RUNNING: + from typing import Optional, Set, List, Any # noqa: F401 + from pip._internal.index import FormatControl # noqa: F401 + +logger = logging.getLogger(__name__) + + +class Cache(object): + """An abstract class - provides cache directories for data from links + + + :param cache_dir: The root of the cache. + :param format_control: An object of FormatControl class to limit + binaries being read from the cache. + :param allowed_formats: which formats of files the cache should store. + ('binary' and 'source' are the only allowed values) + """ + + def __init__(self, cache_dir, format_control, allowed_formats): + # type: (str, FormatControl, Set[str]) -> None + super(Cache, self).__init__() + self.cache_dir = expanduser(cache_dir) if cache_dir else None + self.format_control = format_control + self.allowed_formats = allowed_formats + + _valid_formats = {"source", "binary"} + assert self.allowed_formats.union(_valid_formats) == _valid_formats + + def _get_cache_path_parts(self, link): + # type: (Link) -> List[str] + """Get parts of part that must be os.path.joined with cache_dir + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = [link.url_without_fragment] + if link.hash_name is not None and link.hash is not None: + key_parts.append("=".join([link.hash_name, link.hash])) + key_url = "#".join(key_parts) + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = hashlib.sha224(key_url.encode()).hexdigest() + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + return parts + + def _get_candidates(self, link, package_name): + # type: (Link, Optional[str]) -> List[Any] + can_not_cache = ( + not self.cache_dir or + not package_name or + not link + ) + if can_not_cache: + return [] + + canonical_name = canonicalize_name(package_name) + formats = self.format_control.get_allowed_formats( + canonical_name + ) + if not self.allowed_formats.intersection(formats): + return [] + + root = self.get_path_for_link(link) + try: + return os.listdir(root) + except OSError as err: + if err.errno in {errno.ENOENT, errno.ENOTDIR}: + return [] + raise + + def get_path_for_link(self, link): + # type: (Link) -> str + """Return a directory to store cached items in for link. + """ + raise NotImplementedError() + + def get(self, link, package_name): + # type: (Link, Optional[str]) -> Link + """Returns a link to a cached item if it exists, otherwise returns the + passed link. + """ + raise NotImplementedError() + + def _link_for_candidate(self, link, candidate): + # type: (Link, str) -> Link + root = self.get_path_for_link(link) + path = os.path.join(root, candidate) + + return Link(path_to_url(path)) + + def cleanup(self): + # type: () -> None + pass + + +class SimpleWheelCache(Cache): + """A cache of wheels for future installs. + """ + + def __init__(self, cache_dir, format_control): + # type: (str, FormatControl) -> None + super(SimpleWheelCache, self).__init__( + cache_dir, format_control, {"binary"} + ) + + def get_path_for_link(self, link): + # type: (Link) -> str + """Return a directory to store cached wheels for link + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + parts = self._get_cache_path_parts(link) + + # Store wheels within the root cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + + def get(self, link, package_name): + # type: (Link, Optional[str]) -> Link + candidates = [] + + for wheel_name in self._get_candidates(link, package_name): + try: + wheel = Wheel(wheel_name) + except InvalidWheelFilename: + continue + if not wheel.supported(): + # Built for a different python/arch/etc + continue + candidates.append((wheel.support_index_min(), wheel_name)) + + if not candidates: + return link + + return self._link_for_candidate(link, min(candidates)[1]) + + +class EphemWheelCache(SimpleWheelCache): + """A SimpleWheelCache that creates it's own temporary cache directory + """ + + def __init__(self, format_control): + # type: (FormatControl) -> None + self._temp_dir = TempDirectory(kind="ephem-wheel-cache") + self._temp_dir.create() + + super(EphemWheelCache, self).__init__( + self._temp_dir.path, format_control + ) + + def cleanup(self): + # type: () -> None + self._temp_dir.cleanup() + + +class WheelCache(Cache): + """Wraps EphemWheelCache and SimpleWheelCache into a single Cache + + This Cache allows for gracefully degradation, using the ephem wheel cache + when a certain link is not found in the simple wheel cache first. + """ + + def __init__(self, cache_dir, format_control): + # type: (str, FormatControl) -> None + super(WheelCache, self).__init__( + cache_dir, format_control, {'binary'} + ) + self._wheel_cache = SimpleWheelCache(cache_dir, format_control) + self._ephem_cache = EphemWheelCache(format_control) + + def get_path_for_link(self, link): + # type: (Link) -> str + return self._wheel_cache.get_path_for_link(link) + + def get_ephem_path_for_link(self, link): + # type: (Link) -> str + return self._ephem_cache.get_path_for_link(link) + + def get(self, link, package_name): + # type: (Link, Optional[str]) -> Link + retval = self._wheel_cache.get(link, package_name) + if retval is link: + retval = self._ephem_cache.get(link, package_name) + return retval + + def cleanup(self): + # type: () -> None + self._wheel_cache.cleanup() + self._ephem_cache.cleanup() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/__init__.py new file mode 100755 index 0000000..e589bb9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/__init__.py @@ -0,0 +1,4 @@ +"""Subpackage containing all of pip's command line interface related code +""" + +# This file intentionally does not import submodules diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/autocompletion.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/autocompletion.py new file mode 100755 index 0000000..0a04199 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/autocompletion.py @@ -0,0 +1,152 @@ +"""Logic that powers autocompletion installed by ``pip completion``. +""" + +import optparse +import os +import sys + +from pip._internal.cli.main_parser import create_main_parser +from pip._internal.commands import commands_dict, get_summaries +from pip._internal.utils.misc import get_installed_distributions + + +def autocomplete(): + """Entry Point for completion of main and subcommand options. + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword - 1] + except IndexError: + current = '' + + subcommands = [cmd for cmd, summary in get_summaries()] + options = [] + # subcommand + try: + subcommand_name = [w for w in cwords if w in subcommands][0] + except IndexError: + subcommand_name = None + + parser = create_main_parser() + # subcommand options + if subcommand_name: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for show and uninstall + should_list_installed = ( + subcommand_name in ['show', 'uninstall'] and + not current.startswith('-') + ) + if should_list_installed: + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print(dist) + sys.exit(1) + + subcommand = commands_dict[subcommand_name]() + + for opt in subcommand.parser.option_list_all: + if opt.help != optparse.SUPPRESS_HELP: + for opt_str in opt._long_opts + opt._short_opts: + options.append((opt_str, opt.nargs)) + + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + options = [(x, v) for (x, v) in options if x not in prev_opts] + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + # get completion type given cwords and available subcommand options + completion_type = get_path_completion_type( + cwords, cword, subcommand.parser.option_list_all, + ) + # get completion files and directories if ``completion_type`` is + # ````, ```` or ```` + if completion_type: + options = auto_complete_paths(current, completion_type) + options = ((opt, 0) for opt in options) + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + + opts = [i.option_list for i in parser.option_groups] + opts.append(parser.option_list) + opts = (o for it in opts for o in it) + if current.startswith('-'): + for opt in opts: + if opt.help != optparse.SUPPRESS_HELP: + subcommands += opt._long_opts + opt._short_opts + else: + # get completion type given cwords and all available options + completion_type = get_path_completion_type(cwords, cword, opts) + if completion_type: + subcommands = auto_complete_paths(current, completion_type) + + print(' '.join([x for x in subcommands if x.startswith(current)])) + sys.exit(1) + + +def get_path_completion_type(cwords, cword, opts): + """Get the type of path completion (``file``, ``dir``, ``path`` or None) + + :param cwords: same as the environmental variable ``COMP_WORDS`` + :param cword: same as the environmental variable ``COMP_CWORD`` + :param opts: The available options to check + :return: path completion type (``file``, ``dir``, ``path`` or None) + """ + if cword < 2 or not cwords[cword - 2].startswith('-'): + return + for opt in opts: + if opt.help == optparse.SUPPRESS_HELP: + continue + for o in str(opt).split('/'): + if cwords[cword - 2].split('=')[0] == o: + if not opt.metavar or any( + x in ('path', 'file', 'dir') + for x in opt.metavar.split('/')): + return opt.metavar + + +def auto_complete_paths(current, completion_type): + """If ``completion_type`` is ``file`` or ``path``, list all regular files + and directories starting with ``current``; otherwise only list directories + starting with ``current``. + + :param current: The word to be completed + :param completion_type: path completion type(`file`, `path` or `dir`)i + :return: A generator of regular files and/or directories + """ + directory, filename = os.path.split(current) + current_path = os.path.abspath(directory) + # Don't complete paths if they can't be accessed + if not os.access(current_path, os.R_OK): + return + filename = os.path.normcase(filename) + # list all files that start with ``filename`` + file_list = (x for x in os.listdir(current_path) + if os.path.normcase(x).startswith(filename)) + for f in file_list: + opt = os.path.join(current_path, f) + comp_file = os.path.normcase(os.path.join(directory, f)) + # complete regular files when there is not ```` after option + # complete directories when there is ````, ```` or + # ````after option + if completion_type != 'dir' and os.path.isfile(opt): + yield comp_file + elif os.path.isdir(opt): + yield os.path.join(comp_file, '') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/base_command.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/base_command.py new file mode 100755 index 0000000..3ceea49 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/base_command.py @@ -0,0 +1,341 @@ +"""Base Command class, and related routines""" +from __future__ import absolute_import, print_function + +import logging +import logging.config +import optparse +import os +import platform +import sys +import traceback + +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.cli.status_codes import ( + ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.download import PipSession +from pip._internal.exceptions import ( + BadCommand, CommandError, InstallationError, PreviousBuildDirError, + UninstallationError, +) +from pip._internal.index import PackageFinder +from pip._internal.locations import running_under_virtualenv +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.req.req_file import parse_requirements +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging +from pip._internal.utils.misc import ( + get_prog, normalize_path, redact_password_from_url, +) +from pip._internal.utils.outdated import pip_version_check +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, List, Tuple, Any # noqa: F401 + from optparse import Values # noqa: F401 + from pip._internal.cache import WheelCache # noqa: F401 + from pip._internal.req.req_set import RequirementSet # noqa: F401 + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(object): + name = None # type: Optional[str] + usage = None # type: Optional[str] + hidden = False # type: bool + ignore_require_venv = False # type: bool + + def __init__(self, isolated=False): + # type: (bool) -> None + parser_kw = { + 'usage': self.usage, + 'prog': '%s %s' % (get_prog(), self.name), + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': self.name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.parser = ConfigOptionParser(**parser_kw) + + # Commands should add options to this option group + optgroup_name = '%s Options' % self.name.capitalize() + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + def run(self, options, args): + # type: (Values, List[Any]) -> Any + raise NotImplementedError + + def _build_session(self, options, retries=None, timeout=None): + # type: (Values, Optional[int], Optional[int]) -> PipSession + session = PipSession( + cache=( + normalize_path(os.path.join(options.cache_dir, "http")) + if options.cache_dir else None + ), + retries=retries if retries is not None else options.retries, + insecure_hosts=options.trusted_hosts, + ) + + # Handle custom ca-bundles from the user + if options.cert: + session.verify = options.cert + + # Handle SSL client certificate + if options.client_cert: + session.cert = options.client_cert + + # Handle timeouts + if options.timeout or timeout: + session.timeout = ( + timeout if timeout is not None else options.timeout + ) + + # Handle configured proxies + if options.proxy: + session.proxies = { + "http": options.proxy, + "https": options.proxy, + } + + # Determine if we can prompt the user for authentication or not + session.auth.prompting = not options.no_input + + return session + + def parse_args(self, args): + # type: (List[str]) -> Tuple + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + # type: (List[str]) -> int + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + level_number = setup_logging( + verbosity=self.verbosity, + no_color=options.no_color, + user_log_file=options.log, + ) + + if sys.version_info[:2] == (3, 4): + deprecated( + "Python 3.4 support has been deprecated. pip 19.1 will be the " + "last one supporting it. Please upgrade your Python as Python " + "3.4 won't be maintained after March 2019 (cf PEP 429).", + replacement=None, + gone_in='19.2', + ) + elif sys.version_info[:2] == (2, 7): + message = ( + "A future version of pip will drop support for Python 2.7." + ) + if platform.python_implementation() == "CPython": + message = ( + "Python 2.7 will reach the end of its life on January " + "1st, 2020. Please upgrade your Python as Python 2.7 " + "won't be maintained after that date. " + ) + message + deprecated(message, replacement=None, gone_in=None) + + # TODO: Try to get these passing down from the command? + # without resorting to os.environ to hold these. + # This also affects isolated builds and it should. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + try: + status = self.run(options, args) + # FIXME: all commands should return an exit status + # and when it is done, isinstance is not needed anymore + if isinstance(status, int): + return status + except PreviousBuildDirError as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return PREVIOUS_BUILD_DIR_ERROR + except (InstallationError, UninstallationError, BadCommand) as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('ERROR: %s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BrokenStdoutLoggingError: + # Bypass our logger and write any remaining messages to stderr + # because stdout no longer works. + print('ERROR: Pipe to stdout was broken', file=sys.stderr) + if level_number <= logging.DEBUG: + traceback.print_exc(file=sys.stderr) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BaseException: + logger.critical('Exception:', exc_info=True) + + return UNKNOWN_ERROR + finally: + allow_version_check = ( + # Does this command have the index_group options? + hasattr(options, "no_index") and + # Is this command allowed to perform this check? + not (options.disable_pip_version_check or options.no_index) + ) + # Check if we're using the latest version of pip available + if allow_version_check: + session = self._build_session( + options, + retries=0, + timeout=min(5, options.timeout) + ) + with session: + pip_version_check(session, options) + + # Shutdown the logging module + logging.shutdown() + + return SUCCESS + + +class RequirementCommand(Command): + + @staticmethod + def populate_requirement_set(requirement_set, # type: RequirementSet + args, # type: List[str] + options, # type: Values + finder, # type: PackageFinder + session, # type: PipSession + name, # type: str + wheel_cache # type: Optional[WheelCache] + ): + # type: (...) -> None + """ + Marshal cmd line args into a requirement set. + """ + # NOTE: As a side-effect, options.require_hashes and + # requirement_set.require_hashes may be updated + + for filename in options.constraints: + for req_to_add in parse_requirements( + filename, + constraint=True, finder=finder, options=options, + session=session, wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in args: + req_to_add = install_req_from_line( + req, None, isolated=options.isolated_mode, + use_pep517=options.use_pep517, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in options.editables: + req_to_add = install_req_from_editable( + req, + isolated=options.isolated_mode, + use_pep517=options.use_pep517, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for filename in options.requirements: + for req_to_add in parse_requirements( + filename, + finder=finder, options=options, session=session, + wheel_cache=wheel_cache, + use_pep517=options.use_pep517): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + # If --require-hashes was a line in a requirements file, tell + # RequirementSet about it: + requirement_set.require_hashes = options.require_hashes + + if not (args or options.editables or options.requirements): + opts = {'name': name} + if options.find_links: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(maybe you meant "pip %(name)s %(links)s"?)' % + dict(opts, links=' '.join(options.find_links))) + else: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(see "pip help %(name)s")' % opts) + + def _build_package_finder( + self, + options, # type: Values + session, # type: PipSession + platform=None, # type: Optional[str] + python_versions=None, # type: Optional[List[str]] + abi=None, # type: Optional[str] + implementation=None # type: Optional[str] + ): + # type: (...) -> PackageFinder + """ + Create a package finder appropriate to this requirement command. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug( + 'Ignoring indexes: %s', + ','.join(redact_password_from_url(url) for url in index_urls), + ) + index_urls = [] + + return PackageFinder( + find_links=options.find_links, + format_control=options.format_control, + index_urls=index_urls, + trusted_hosts=options.trusted_hosts, + allow_all_prereleases=options.pre, + session=session, + platform=platform, + versions=python_versions, + abi=abi, + implementation=implementation, + prefer_binary=options.prefer_binary, + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/cmdoptions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/cmdoptions.py new file mode 100755 index 0000000..5cf5ee9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/cmdoptions.py @@ -0,0 +1,809 @@ +""" +shared options and groups + +The principle here is to define options once, but *not* instantiate them +globally. One reason being that options with action='append' can carry state +between parses. pip parses general options twice internally, and shouldn't +pass on state. To be consistent, all options will follow this design. + +""" +from __future__ import absolute_import + +import textwrap +import warnings +from distutils.util import strtobool +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup + +from pip._internal.exceptions import CommandError +from pip._internal.locations import USER_CACHE_DIR, src_prefix +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.utils.hashes import STRONG_HASHES +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import BAR_TYPES + +if MYPY_CHECK_RUNNING: + from typing import Any, Callable, Dict, List, Optional, Union # noqa: F401 + from optparse import OptionParser, Values # noqa: F401 + from pip._internal.cli.parser import ConfigOptionParser # noqa: F401 + + +def raise_option_error(parser, option, msg): + """ + Raise an option parsing error using parser.error(). + + Args: + parser: an OptionParser instance. + option: an Option instance. + msg: the error text. + """ + msg = '{} error: {}'.format(option, msg) + msg = textwrap.fill(' '.join(msg.split())) + parser.error(msg) + + +def make_option_group(group, parser): + # type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + # type: (Values, Optional[Values]) -> None + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] + if any(map(getname, names)): + control = options.format_control + control.disallow_binaries() + warnings.warn( + 'Disabling all use of wheels due to the use of --build-options ' + '/ --global-options / --install-options.', stacklevel=2, + ) + + +def check_dist_restriction(options, check_target=False): + # type: (Values, bool) -> None + """Function for determining if custom platform options are allowed. + + :param options: The OptionParser options. + :param check_target: Whether or not to check if --target is being used. + """ + dist_restriction_set = any([ + options.python_version, + options.platform, + options.abi, + options.implementation, + ]) + + binary_only = FormatControl(set(), {':all:'}) + sdist_dependencies_allowed = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + + # Installations or downloads using dist restrictions must not combine + # source distributions and dist-specific wheels, as they are not + # gauranteed to be locally compatible. + if dist_restriction_set and sdist_dependencies_allowed: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + if check_target: + if dist_restriction_set and not options.target_dir: + raise CommandError( + "Can not use any platform or abi specific options unless " + "installing via '--target'" + ) + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Callable[..., Option] + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) # type: Callable[..., Option] + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Callable[..., Option] + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) # type: Callable[..., Option] + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output", +) # type: Callable[..., Option] + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Callable[..., Option] + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Callable[..., Option] + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Callable[..., Option] + +log = partial( + Option, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + help="Path to a verbose appending log." +) # type: Callable[..., Option] + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Callable[..., Option] + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Callable[..., Option] + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Callable[..., Option] + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Callable[..., Option] + +skip_requirements_regex = partial( + Option, + # A regex to be used to skip requirements + '--skip-requirements-regex', + dest='skip_requirements_regex', + type='str', + default='', + help=SUPPRESS_HELP, +) # type: Callable[..., Option] + + +def exists_action(): + # type: () -> Option + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + ) + + +cert = partial( + Option, + '--cert', + dest='cert', + type='str', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Callable[..., Option] + +client_cert = partial( + Option, + '--client-cert', + dest='client_cert', + type='str', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Callable[..., Option] + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Callable[..., Option] + + +def extra_index_url(): + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Callable[..., Option] + + +def find_links(): + # type: () -> Option + return Option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='url', + help="If a url or path to an html file, then parse for links to " + "archives. If a local path or file:// url that's a directory, " + "then look for archives in the directory listing.", + ) + + +def trusted_host(): + # type: () -> Option + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host as trusted, even though it does not have valid " + "or any HTTPS.", + ) + + +def constraints(): + # type: () -> Option + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + # type: () -> Option + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + # type: () -> Option + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +src = partial( + Option, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Callable[..., Option] + + +def _get_format_control(values, option): + # type: (Values, Option) -> Any + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + # type: () -> Option + format_control = FormatControl(set(), set()) + return Option( + "--no-binary", dest="format_control", action="callback", + callback=_handle_no_binary, type="str", + default=format_control, + help="Do not use binary packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all binary packages, :none: to empty the set, or one or " + "more package names with commas between them. Note that some " + "packages are tricky to compile and may fail to install when " + "this option is used on them.", + ) + + +def only_binary(): + # type: () -> Option + format_control = FormatControl(set(), set()) + return Option( + "--only-binary", dest="format_control", action="callback", + callback=_handle_only_binary, type="str", + default=format_control, + help="Do not use source packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all source packages, :none: to empty the set, or one or " + "more package names with commas between them. Packages without " + "binary distributions will fail to install when this option is " + "used on them.", + ) + + +platform = partial( + Option, + '--platform', + dest='platform', + metavar='platform', + default=None, + help=("Only use wheels compatible with . " + "Defaults to the platform of the running system."), +) # type: Callable[..., Option] + + +python_version = partial( + Option, + '--python-version', + dest='python_version', + metavar='python_version', + default=None, + help=("Only use wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified."), +) # type: Callable[..., Option] + + +implementation = partial( + Option, + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only use wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), +) # type: Callable[..., Option] + + +abi = partial( + Option, + '--abi', + dest='abi', + metavar='abi', + default=None, + help=("Only use wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option."), +) # type: Callable[..., Option] + + +def prefer_binary(): + # type: () -> Option + return Option( + "--prefer-binary", + dest="prefer_binary", + action="store_true", + default=False, + help="Prefer older binary packages over newer source packages." + ) + + +cache_dir = partial( + Option, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + help="Store the cache data in ." +) # type: Callable[..., Option] + + +def no_cache_dir_callback(option, opt, value, parser): + """ + Process a value provided for the --no-cache-dir option. + + This is an optparse.Option callback for the --no-cache-dir option. + """ + # The value argument will be None if --no-cache-dir is passed via the + # command-line, since the option doesn't accept arguments. However, + # the value can be non-None if the option is triggered e.g. by an + # environment variable, like PIP_NO_CACHE_DIR=true. + if value is not None: + # Then parse the string value to get argument error-checking. + try: + strtobool(value) + except ValueError as exc: + raise_option_error(parser, option=option, msg=str(exc)) + + # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool() + # converted to 0 (like "false" or "no") caused cache_dir to be disabled + # rather than enabled (logic would say the latter). Thus, we disable + # the cache directory not just on values that parse to True, but (for + # backwards compatibility reasons) also on values that parse to False. + # In other words, always set it to False if the option is provided in + # some (valid) form. + parser.values.cache_dir = False + + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="callback", + callback=no_cache_dir_callback, + help="Disable the cache.", +) # type: Callable[..., Option] + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Callable[..., Option] + +build_dir = partial( + Option, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', + help='Directory to unpack packages into and build in. Note that ' + 'an initial build still takes place in a temporary directory. ' + 'The location of temporary directories can be controlled by setting ' + 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' + 'When passed, build directories are not cleaned in case of failures.' +) # type: Callable[..., Option] + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Callable[..., Option] + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Callable[..., Option] + + +def no_use_pep517_callback(option, opt, value, parser): + """ + Process a value provided for the --no-use-pep517 option. + + This is an optparse.Option callback for the no_use_pep517 option. + """ + # Since --no-use-pep517 doesn't accept arguments, the value argument + # will be None if --no-use-pep517 is passed via the command-line. + # However, the value can be non-None if the option is triggered e.g. + # by an environment variable, for example "PIP_NO_USE_PEP517=true". + if value is not None: + msg = """A value was passed for --no-use-pep517, + probably using either the PIP_NO_USE_PEP517 environment variable + or the "no-use-pep517" config file option. Use an appropriate value + of the PIP_USE_PEP517 environment variable or the "use-pep517" + config file option instead. + """ + raise_option_error(parser, option=option, msg=msg) + + # Otherwise, --no-use-pep517 was passed via the command-line. + parser.values.use_pep517 = False + + +use_pep517 = partial( + Option, + '--use-pep517', + dest='use_pep517', + action='store_true', + default=None, + help='Use PEP 517 for building source distributions ' + '(use --no-use-pep517 to force legacy behaviour).' +) # type: Any + +no_use_pep517 = partial( + Option, + '--no-use-pep517', + dest='use_pep517', + action='callback', + callback=no_use_pep517_callback, + default=None, + help=SUPPRESS_HELP +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Callable[..., Option] + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Callable[..., Option] + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories." +) # type: Callable[..., Option] + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Callable[..., Option] + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Callable[..., Option] + + +# Deprecated, Remove later +always_unzip = partial( + Option, + '-Z', '--always-unzip', + dest='always_unzip', + action='store_true', + help=SUPPRESS_HELP, +) # type: Callable[..., Option] + + +def _merge_hash(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} # type: ignore + try: + algo, digest = value.split(':', 1) + except ValueError: + parser.error('Arguments to %s must be a hash name ' + 'followed by a value, like --hash=sha256:abcde...' % + opt_str) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for %s are %s.' % + (opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Callable[..., Option] + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Callable[..., Option] + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + skip_requirements_regex, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + ] +} # type: Dict[str, Any] + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + ] +} # type: Dict[str, Any] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/main_parser.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/main_parser.py new file mode 100755 index 0000000..b17c749 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/main_parser.py @@ -0,0 +1,104 @@ +"""A single place for constructing and exposing the main parser +""" + +import os +import sys + +from pip import __version__ +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.commands import ( + commands_dict, get_similar_commands, get_summaries, +) +from pip._internal.exceptions import CommandError +from pip._internal.utils.misc import get_prog +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Tuple, List # noqa: F401 + + +__all__ = ["create_main_parser", "parse_command"] + + +def create_main_parser(): + # type: () -> ConfigOptionParser + """Creates and returns the main parser for pip's CLI + """ + + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + pip_pkg_dir = os.path.abspath(os.path.join( + os.path.dirname(__file__), "..", "..", + )) + parser.version = 'pip %s from %s (python %s)' % ( + __version__, pip_pkg_dir, sys.version[:3], + ) + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + # so the help formatter knows + parser.main = True # type: ignore + + # create command listing for description + command_summaries = get_summaries() + description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + parser.description = '\n'.join(description) + + return parser + + +def parse_command(args): + # type: (List[str]) -> Tuple[str, List[str]] + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) # type: ignore + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/parser.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/parser.py new file mode 100755 index 0000000..e1eaac4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/parser.py @@ -0,0 +1,261 @@ +"""Base option parser setup""" +from __future__ import absolute_import + +import logging +import optparse +import sys +import textwrap +from distutils.util import strtobool + +from pip._vendor.six import string_types + +from pip._internal.cli.status_codes import UNKNOWN_ERROR +from pip._internal.configuration import Configuration, ConfigurationError +from pip._internal.utils.compat import get_terminal_size + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = get_terminal_size()[0] - 2 + optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option, ' <%s>', ', ') + + def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): + """ + Return a comma-separated list of option strings and metavars. + + :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') + :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar + :param optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt % metavar.lower()) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + Ensure there is only one newline between usage and the first heading + if there is no description. + """ + msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = '%s:\n%s\n' % (label, description) + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + """ + + def expand_default(self, option): + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print("An error occurred during configuration: %s" % exc) + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false', 'count'): + try: + val = strtobool(val) + except ValueError: + error_msg = invalid_config_error_message( + option.action, key, val + ) + self.error(error_msg) + + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(UNKNOWN_ERROR, str(err)) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, string_types): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(UNKNOWN_ERROR, "%s\n" % msg) + + +def invalid_config_error_message(action, key, val): + """Returns a better error message when invalid configuration option + is provided.""" + if action in ('store_true', 'store_false'): + return ("{0} is not a valid value for {1} option, " + "please specify a boolean value like yes/no, " + "true/false or 1/0 instead.").format(val, key) + + return ("{0} is not a valid value for {1} option, " + "please specify a numerical value like 1/0 " + "instead.").format(val, key) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/status_codes.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/status_codes.py new file mode 100755 index 0000000..275360a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/cli/status_codes.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/__init__.py new file mode 100755 index 0000000..c7d1da3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/__init__.py @@ -0,0 +1,79 @@ +""" +Package containing all pip commands +""" +from __future__ import absolute_import + +from pip._internal.commands.completion import CompletionCommand +from pip._internal.commands.configuration import ConfigurationCommand +from pip._internal.commands.download import DownloadCommand +from pip._internal.commands.freeze import FreezeCommand +from pip._internal.commands.hash import HashCommand +from pip._internal.commands.help import HelpCommand +from pip._internal.commands.list import ListCommand +from pip._internal.commands.check import CheckCommand +from pip._internal.commands.search import SearchCommand +from pip._internal.commands.show import ShowCommand +from pip._internal.commands.install import InstallCommand +from pip._internal.commands.uninstall import UninstallCommand +from pip._internal.commands.wheel import WheelCommand + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Type # noqa: F401 + from pip._internal.cli.base_command import Command # noqa: F401 + +commands_order = [ + InstallCommand, + DownloadCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + CheckCommand, + ConfigurationCommand, + SearchCommand, + WheelCommand, + HashCommand, + CompletionCommand, + HelpCommand, +] # type: List[Type[Command]] + +commands_dict = {c.name: c for c in commands_order} + + +def get_summaries(ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + if ordered: + cmditems = _sort_commands(commands_dict, commands_order) + else: + cmditems = commands_dict.items() + + for name, command_class in cmditems: + yield (name, command_class.summary) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + return close_commands[0] + else: + return False + + +def _sort_commands(cmddict, order): + def keyfn(key): + try: + return order.index(key[1]) + except ValueError: + # unordered items should come last + return 0xff + + return sorted(cmddict.items(), key=keyfn) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/check.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/check.py new file mode 100755 index 0000000..801cecc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/check.py @@ -0,0 +1,41 @@ +import logging + +from pip._internal.cli.base_command import Command +from pip._internal.operations.check import ( + check_package_set, create_package_set_from_installed, +) + +logger = logging.getLogger(__name__) + + +class CheckCommand(Command): + """Verify installed packages have compatible dependencies.""" + name = 'check' + usage = """ + %prog [options]""" + summary = 'Verify installed packages have compatible dependencies.' + + def run(self, options, args): + package_set, parsing_probs = create_package_set_from_installed() + missing, conflicting = check_package_set(package_set) + + for project_name in missing: + version = package_set[project_name].version + for dependency in missing[project_name]: + logger.info( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[0], + ) + + for project_name in conflicting: + version = package_set[project_name].version + for dep_name, dep_version, req in conflicting[project_name]: + logger.info( + "%s %s has requirement %s, but you have %s %s.", + project_name, version, req, dep_name, dep_version, + ) + + if missing or conflicting or parsing_probs: + return 1 + else: + logger.info("No broken requirements found.") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/completion.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/completion.py new file mode 100755 index 0000000..2fcdd39 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/completion.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import sys +import textwrap + +from pip._internal.cli.base_command import Command +from pip._internal.utils.misc import get_prog + +BASE_COMPLETION = """ +# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ + _pip_completion() + { + COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 ) ) + } + complete -o default -F _pip_completion %(prog)s + """, + 'zsh': """ + function _pip_completion { + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] ) ) + } + compctl -K _pip_completion %(prog)s + """, + 'fish': """ + function __fish_complete_pip + set -lx COMP_WORDS (commandline -o) "" + set -lx COMP_CWORD ( \\ + math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ + ) + set -lx PIP_AUTO_COMPLETE 1 + string split \\ -- (eval $COMP_WORDS[1]) + end + complete -fa "(__fish_complete_pip)" -c %(prog)s + """, +} + + +class CompletionCommand(Command): + """A helper command to be used for command completion.""" + name = 'completion' + summary = 'A helper command used for command completion.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(CompletionCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + cmd_opts.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + cmd_opts.add_option( + '--fish', '-f', + action='store_const', + const='fish', + dest='shell', + help='Emit completion code for fish') + + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--' + shell for shell in sorted(shells)] + if options.shell in shells: + script = textwrap.dedent( + COMPLETION_SCRIPTS.get(options.shell, '') % { + 'prog': get_prog(), + } + ) + print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) + else: + sys.stderr.write( + 'ERROR: You must pass %s\n' % ' or '.join(shell_options) + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/configuration.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/configuration.py new file mode 100755 index 0000000..826c08d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/configuration.py @@ -0,0 +1,227 @@ +import logging +import os +import subprocess + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.configuration import Configuration, kinds +from pip._internal.exceptions import PipError +from pip._internal.locations import venv_config_file +from pip._internal.utils.misc import get_prog + +logger = logging.getLogger(__name__) + + +class ConfigurationCommand(Command): + """Manage local and global configuration. + + Subcommands: + + list: List the active configuration (or from the file specified) + edit: Edit the configuration file in an editor + get: Get the value associated with name + set: Set the name=value + unset: Unset the value associated with name + + If none of --user, --global and --venv are passed, a virtual + environment configuration file is used if one is active and the file + exists. Otherwise, all modifications happen on the to the user file by + default. + """ + + name = 'config' + usage = """ + %prog [] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + """ + + summary = "Manage local and global configuration." + + def __init__(self, *args, **kwargs): + super(ConfigurationCommand, self).__init__(*args, **kwargs) + + self.configuration = None + + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--venv', + dest='venv_file', + action='store_true', + default=False, + help='Use the virtualenv configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name + } + + # Determine action + if not args or args[0] not in handlers: + logger.error("Need an action ({}) to perform.".format( + ", ".join(sorted(handlers))) + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + file_options = { + kinds.USER: options.user_file, + kinds.GLOBAL: options.global_file, + kinds.VENV: options.venv_file + } + + if sum(file_options.values()) == 0: + if not need_value: + return None + # Default to user, unless there's a virtualenv file. + elif os.path.exists(venv_config_file): + return kinds.VENV + else: + return kinds.USER + elif sum(file_options.values()) == 1: + # There's probably a better expression for this. + return [key for key in file_options if file_options[key]][0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --venv, --global) to perform." + ) + + def list_values(self, options, args): + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + logger.info("%s=%r", key, value) + + def get_name(self, options, args): + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + logger.info("%s", value) + + def set_name_value(self, options, args): + key, value = self._get_n_args(args, "set [name] [value]", n=2) + self.configuration.set_value(key, value) + + self._save_configuration() + + def unset_name(self, options, args): + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def open_in_editor(self, options, args): + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # We successfully ran a modifying command. Need to save the + # configuration. + try: + self.configuration.save() + except Exception: + logger.error( + "Unable to save configuration. Please report this as a bug.", + exc_info=1 + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/download.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/download.py new file mode 100755 index 0000000..a57e4bc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/download.py @@ -0,0 +1,176 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + name = 'download' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Download packages.' + + def __init__(self, *args, **kw): + super(DownloadCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.global_options()) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.pre()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.use_pep517()) + cmd_opts.add_option(cmdoptions.no_use_pep517()) + + cmd_opts.add_option( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + cmdoptions.check_dist_restriction(options) + + options.src_dir = os.path.abspath(options.src_dir) + options.download_dir = normalize_path(options.download_dir) + + ensure_dir(options.download_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="download" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + self.populate_requirement_set( + requirement_set, + args, + options, + finder, + session, + self.name, + None + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=options.download_dir, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=None, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=False, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + downloaded = ' '.join([ + req.name for req in requirement_set.successfully_downloaded + ]) + if downloaded: + logger.info('Successfully downloaded %s', downloaded) + + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + + return requirement_set diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/freeze.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/freeze.py new file mode 100755 index 0000000..dc9c53a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/freeze.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import + +import sys + +from pip._internal.cache import WheelCache +from pip._internal.cli.base_command import Command +from pip._internal.models.format_control import FormatControl +from pip._internal.operations.freeze import freeze +from pip._internal.utils.compat import stdlib_pkgs + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + name = 'freeze' + usage = """ + %prog [options]""" + summary = 'Output installed packages in requirements format.' + log_streams = ("ext://sys.stderr", "ext://sys.stderr") + + def __init__(self, *args, **kw): + super(FreezeCommand, self).__init__(*args, **kw) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + format_control = FormatControl(set(), set()) + wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + freeze_kwargs = dict( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + skip_regex=options.skip_requirements_regex, + isolated=options.isolated_mode, + wheel_cache=wheel_cache, + skip=skip, + exclude_editable=options.exclude_editable, + ) + + try: + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') + finally: + wheel_cache.cleanup() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/hash.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/hash.py new file mode 100755 index 0000000..423440e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/hash.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import hashlib +import logging +import sys + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + + """ + name = 'hash' + usage = '%prog [options] ...' + summary = 'Compute hashes of package archives.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(HashCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-a', '--algorithm', + dest='algorithm', + choices=STRONG_HASHES, + action='store', + default=FAVORITE_HASH, + help='The hash algorithm to use: one of %s' % + ', '.join(STRONG_HASHES)) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + self.parser.print_usage(sys.stderr) + return ERROR + + algorithm = options.algorithm + for path in args: + logger.info('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + + +def _hash_of_file(path, algorithm): + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/help.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/help.py new file mode 100755 index 0000000..49a81cb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/help.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + ignore_require_venv = True + + def run(self, options, args): + from pip._internal.commands import commands_dict, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands_dict[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/install.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/install.py new file mode 100755 index 0000000..1c244d2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/install.py @@ -0,0 +1,566 @@ +from __future__ import absolute_import + +import errno +import logging +import operator +import os +import shutil +from optparse import SUPPRESS_HELP + +from pip._vendor import pkg_resources + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.cli.status_codes import ERROR +from pip._internal.exceptions import ( + CommandError, InstallationError, PreviousBuildDirError, +) +from pip._internal.locations import distutils_scheme, virtualenv_no_global +from pip._internal.operations.check import check_install_conflicts +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet, install_given_reqs +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ( + ensure_dir, get_installed_version, + protect_pip_from_modification_on_windows, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + name = 'install' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + + def __init__(self, *args, **kw): + super(InstallCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.pre()) + + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + cmd_opts.add_option( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + cmd_opts.add_option(cmdoptions.build_dir()) + + cmd_opts.add_option(cmdoptions.src()) + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='Reinstall all packages even if they are already ' + 'up-to-date.') + + cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.use_pep517()) + cmd_opts.add_option(cmdoptions.no_use_pep517()) + + cmd_opts.add_option(cmdoptions.install_options()) + cmd_opts.add_option(cmdoptions.global_options()) + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-warn-script-location", + action="store_false", + dest="warn_script_location", + default=True, + help="Do not warn when installing scripts outside PATH", + ) + cmd_opts.add_option( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + help="Do not warn about broken dependencies", + ) + + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + cmdoptions.check_dist_restriction(options, check_target=True) + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + if options.prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + install_options.append('--user') + install_options.append('--prefix=') + + target_temp_dir = TempDirectory(kind="target") + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir.create() + install_options.append('--home=' + target_temp_dir.path) + + global_options = options.global_options or [] + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="install" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + check_supported_wheels=not options.target_dir, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + upgrade_strategy=upgrade_strategy, + force_reinstall=options.force_reinstall, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=options.ignore_installed, + isolated=options.isolated_mode, + use_pep517=options.use_pep517 + ) + resolver.resolve(requirement_set) + + protect_pip_from_modification_on_windows( + modifying_pip=requirement_set.has_requirement("pip") + ) + + # Consider legacy and PEP517-using requirements separately + legacy_requirements = [] + pep517_requirements = [] + for req in requirement_set.requirements.values(): + if req.use_pep517: + pep517_requirements.append(req) + else: + legacy_requirements.append(req) + + # We don't build wheels for legacy requirements if we + # don't have wheel installed or we don't have a cache dir + try: + import wheel # noqa: F401 + build_legacy = bool(options.cache_dir) + except ImportError: + build_legacy = False + + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=[], global_options=[], + ) + + # Always build PEP 517 requirements + build_failures = wb.build( + pep517_requirements, + session=session, autobuilding=True + ) + + if build_legacy: + # We don't care about failures building legacy + # requirements, as we'll fall through to a direct + # install for those. + wb.build( + legacy_requirements, + session=session, autobuilding=True + ) + + # If we're using PEP 517, we cannot do a direct install + # so we fail here. + if build_failures: + raise InstallationError( + "Could not build wheels for {} which use" + " PEP 517 and cannot be installed directly".format( + ", ".join(r.name for r in build_failures))) + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Consistency Checking of the package set we're installing. + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + self._warn_about_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir.path, + prefix=options.prefix_path, + pycompile=options.compile, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + ) + + lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir.path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + working_set = pkg_resources.WorkingSet(lib_locations) + + reqs = sorted(installed, key=operator.attrgetter('name')) + items = [] + for req in reqs: + item = req.name + try: + installed_version = get_installed_version( + req.name, working_set=working_set + ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) + installed = ' '.join(items) + if installed: + logger.info('Successfully installed %s', installed) + except EnvironmentError as error: + show_traceback = (self.verbosity >= 1) + + message = create_env_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) + + return ERROR + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() + + if options.target_dir: + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + return requirement_set + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + ensure_dir(target_dir) + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + lib_dir_list = [] + + with target_temp_dir: + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] + + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) + + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. Pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _warn_about_conflicts(self, to_install): + try: + package_set, _dep_info = check_install_conflicts(to_install) + except Exception: + logger.error("Error checking for conflicts.", exc_info=True) + return + missing, conflicting = _dep_info + + # NOTE: There is some duplication here from pip check + for project_name in missing: + version = package_set[project_name][0] + for dependency in missing[project_name]: + logger.critical( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[1], + ) + + for project_name in conflicting: + version = package_set[project_name][0] + for dep_name, dep_version, req in conflicting[project_name]: + logger.critical( + "%s %s has requirement %s, but you'll have %s %s which is " + "incompatible.", + project_name, version, req, dep_name, dep_version, + ) + + +def get_lib_location_guesses(*args, **kwargs): + scheme = distutils_scheme('', *args, **kwargs) + return [scheme['purelib'], scheme['platlib']] + + +def create_env_error_message(error, show_traceback, using_user_site): + """Format an error message for an EnvironmentError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an EnvironmentError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/list.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/list.py new file mode 100755 index 0000000..a640274 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/list.py @@ -0,0 +1,301 @@ +from __future__ import absolute_import + +import json +import logging + +from pip._vendor import six +from pip._vendor.six.moves import zip_longest + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import Command +from pip._internal.exceptions import CommandError +from pip._internal.index import PackageFinder +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.packaging import get_installer + +logger = logging.getLogger(__name__) + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + usage = """ + %prog [options]""" + summary = 'List installed packages.' + + def __init__(self, *args, **kw): + super(ListCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "or json", + ) + + cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, self.parser + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_all_prereleases=options.pre, + trusted_hosts=options.trusted_hosts, + session=session, + ) + + def run(self, options, args): + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + ) + + # get_not_required must be called firstly in order to find and + # filter out all dependencies correctly. Otherwise a package + # can't be identified as requirement because some parent packages + # could be filtered out before. + if options.not_required: + packages = self.get_not_required(packages, options) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + self.output_package_listing(packages, options) + + def get_outdated(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version > dist.parsed_version + ] + + def get_uptodate(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version == dist.parsed_version + ] + + def get_not_required(self, packages, options): + dep_keys = set() + for dist in packages: + dep_keys.update(requirement.key for requirement in dist.requires()) + return {pkg for pkg in packages if pkg.key not in dep_keys} + + def iter_packages_latest_infos(self, packages, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + with self._build_session(options) as session: + finder = self._build_package_finder(options, index_urls, session) + + for dist in packages: + typ = 'unknown' + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + if not all_candidates: + continue + best_candidate = max(all_candidates, + key=finder._candidate_sort_key) + remote_version = best_candidate.version + if best_candidate.location.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + yield dist + + def output_package_listing(self, packages, options): + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + elif options.list_format == 'freeze': + for dist in packages: + if options.verbose >= 1: + logger.info("%s==%s (%s)", dist.project_name, + dist.version, dist.location) + else: + logger.info("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + logger.info(format_for_json(packages, options)) + + def output_package_listing_columns(self, data, header): + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) + + for val in pkg_strings: + logger.info(val) + + +def tabulate(vals): + # From pfmoore on GitHub: + # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 + assert len(vals) > 0 + + sizes = [0] * max(len(x) for x in vals) + for row in vals: + sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] + + result = [] + for row in vals: + display = " ".join([str(c).ljust(s) if c is not None else '' + for s, c in zip_longest(sizes, row)]) + result.append(display) + + return result, sizes + + +def format_for_columns(pkgs, options): + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': six.text_type(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = six.text_type(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/search.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/search.py new file mode 100755 index 0000000..c157a31 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/search.py @@ -0,0 +1,135 @@ +from __future__ import absolute_import + +import logging +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS +from pip._internal.download import PipXmlrpcTransport +from pip._internal.exceptions import CommandError +from pip._internal.models.index import PyPI +from pip._internal.utils.compat import get_terminal_size +from pip._internal.utils.logging import indent_log + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + index_url = options.index + with self._build_session(options) as session: + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = OrderedDict() + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not None: + target_width = terminal_width - name_column_width - 5 + if target_width > 10: + # wrap and indent summary to fit terminal + summary = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, latest), summary) + try: + logger.info(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + with indent_log(): + if dist.version == latest: + logger.info('INSTALLED: %s (latest)', dist.version) + else: + logger.info('INSTALLED: %s', dist.version) + logger.info('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + return max(versions, key=parse_version) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/show.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/show.py new file mode 100755 index 0000000..f92c9bc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/show.py @@ -0,0 +1,168 @@ +from __future__ import absolute_import + +import logging +import os +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """ + Show information about one or more installed packages. + + The output is in RFC-compliant mail header format. + """ + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + metadata = None + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [l.split(',')[0] for l in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + """ + Print the informations from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + logger.info("---") + + name = dist.get('name', '') + required_by = [ + pkg.project_name for pkg in pkg_resources.working_set + if name in [required.name for required in pkg.requires()] + ] + + logger.info("Name: %s", name) + logger.info("Version: %s", dist.get('version', '')) + logger.info("Summary: %s", dist.get('summary', '')) + logger.info("Home-page: %s", dist.get('home-page', '')) + logger.info("Author: %s", dist.get('author', '')) + logger.info("Author-email: %s", dist.get('author-email', '')) + logger.info("License: %s", dist.get('license', '')) + logger.info("Location: %s", dist.get('location', '')) + logger.info("Requires: %s", ', '.join(dist.get('requires', []))) + logger.info("Required-by: %s", ', '.join(required_by)) + + if verbose: + logger.info("Metadata-Version: %s", + dist.get('metadata-version', '')) + logger.info("Installer: %s", dist.get('installer', '')) + logger.info("Classifiers:") + for classifier in dist.get('classifiers', []): + logger.info(" %s", classifier) + logger.info("Entry-points:") + for entry in dist.get('entry_points', []): + logger.info(" %s", entry.strip()) + if list_files: + logger.info("Files:") + for line in dist.get('files', []): + logger.info(" %s", line.strip()) + if "files" not in dist: + logger.info("Cannot locate installed-files.txt") + return results_printed diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/uninstall.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/uninstall.py new file mode 100755 index 0000000..0cd6f54 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/uninstall.py @@ -0,0 +1,78 @@ +from __future__ import absolute_import + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.exceptions import InstallationError +from pip._internal.req import parse_requirements +from pip._internal.req.constructors import install_req_from_line +from pip._internal.utils.misc import protect_pip_from_modification_on_windows + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + with self._build_session(options) as session: + reqs_to_uninstall = {} + for name in args: + req = install_req_from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for req in parse_requirements( + filename, + options=options, + session=session): + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to %(name)s (see ' + '"pip help %(name)s")' % dict(name=self.name) + ) + + protect_pip_from_modification_on_windows( + modifying_pip="pip" in reqs_to_uninstall + ) + + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/wheel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/wheel.py new file mode 100755 index 0000000..cd72a3d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/commands/wheel.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import logging +import os + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.exceptions import CommandError, PreviousBuildDirError +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.use_pep517()) + cmd_opts.add_option(cmdoptions.no_use_pep517()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="wheel" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=options.wheel_dir, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=True, + isolated=options.isolated_mode, + use_pep517=options.use_pep517 + ) + resolver.resolve(requirement_set) + + # build wheels + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=options.build_options or [], + global_options=options.global_options or [], + no_clean=options.no_clean, + ) + build_failures = wb.build( + requirement_set.requirements.values(), session=session, + ) + if len(build_failures) != 0: + raise CommandError( + "Failed to build one or more wheels" + ) + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/configuration.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/configuration.py new file mode 100755 index 0000000..fe6df9b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/configuration.py @@ -0,0 +1,387 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import locale +import logging +import os + +from pip._vendor import six +from pip._vendor.six.moves import configparser + +from pip._internal.exceptions import ( + ConfigurationError, ConfigurationFileCouldNotBeLoaded, +) +from pip._internal.locations import ( + legacy_config_file, new_config_file, running_under_virtualenv, + site_config_files, venv_config_file, +) +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Any, Dict, Iterable, List, NewType, Optional, Tuple + ) + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + return name.split(".", 1) + + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) + + +class Configuration(object): + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Kind) -> None + super(Configuration, self).__init__() + + _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] + if load_only not in _valid_load_only: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, _valid_load_only[:-1])) + ) + ) + self.isolated = isolated # type: bool + self.load_only = load_only # type: Optional[Kind] + + # The order here determines the override order. + self._override_order = [ + kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + ] + + self._ignore_env_names = ["version", "help"] + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in self._override_order + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in self._override_order + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError("No such key - {}".format(key)) + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration. + """ + self._ensure_have_load_only() + + if key not in self._config[self.load_only]: + raise ConfigurationError("No such key - {}".format(key)) + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Remove the key in the parser + modified_something = False + if parser.has_section(section): + # Returns whether the option was removed or not + modified_something = parser.remove_option(section, name) + + if modified_something: + # name removed from parser, section may now be empty + section_iter = iter(parser.items(section)) + try: + val = six.next(section_iter) + except StopIteration: + val = None + + if val is None: + parser.remove_section(section) + + self._mark_as_modified(fname, parser) + else: + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the currentin-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) # type: ignore + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in self._override_order: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration files + """ + config_files = dict(self._iter_config_files()) + if config_files[kinds.ENV][0:1] == [os.devnull]: + logger.debug( + "Skipping loading configuration files due to " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + # See https://github.com/pypa/pip/issues/4963 + raise ConfigurationFileCouldNotBeLoaded( + reason="contains invalid {} characters".format( + locale.getpreferredencoding(False) + ), + fname=fname, + ) + except configparser.Error as error: + # See https://github.com/pypa/pip/issues/4893 + raise ConfigurationFileCouldNotBeLoaded(error=error) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self._get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + def _get_environ_vars(self): + # type: () -> Iterable[Tuple[str, str]] + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.items(): + should_be_yielded = ( + key.startswith("PIP_") and + key[4:].lower() not in self._ignore_env_names + ) + if should_be_yielded: + yield key[4:].lower(), val + + # XXX: This is patched in the tests. + def _iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + # at the base we have any global configuration + yield kinds.GLOBAL, list(site_config_files) + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, [legacy_config_file, new_config_file] + + # finally virtualenv configuration first trumping others + if running_under_virtualenv(): + yield kinds.VENV, [venv_config_file] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/download.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/download.py new file mode 100755 index 0000000..2bbe176 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/download.py @@ -0,0 +1,971 @@ +from __future__ import absolute_import + +import cgi +import email.utils +import getpass +import json +import logging +import mimetypes +import os +import platform +import re +import shutil +import sys + +from pip._vendor import requests, six, urllib3 +from pip._vendor.cachecontrol import CacheControlAdapter +from pip._vendor.cachecontrol.caches import FileCache +from pip._vendor.lockfile import LockError +from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter +from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response +from pip._vendor.requests.structures import CaseInsensitiveDict +from pip._vendor.requests.utils import get_netrc_auth +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request +from pip._vendor.urllib3.util import IS_PYOPENSSL + +import pip +from pip._internal.exceptions import HashMismatch, InstallationError +from pip._internal.locations import write_delete_marker_file +from pip._internal.models.index import PyPI +from pip._internal.utils.encoding import auto_decode +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.glibc import libc_ver +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, + display_path, format_size, get_installed_version, rmtree, + split_auth_from_netloc, splitext, unpack_file, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import DownloadProgressProvider +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Optional, Tuple, Dict, IO, Text, Union + ) + from pip._internal.models.link import Link # noqa: F401 + from pip._internal.utils.hashes import Hashes # noqa: F401 + from pip._internal.vcs import AuthInfo # noqa: F401 + +try: + import ssl # noqa +except ImportError: + ssl = None + +HAS_TLS = (ssl is not None) or IS_PYOPENSSL + +__all__ = ['get_file_content', + 'is_url', 'url_to_path', 'path_to_url', + 'is_archive_file', 'unpack_vcs_link', + 'unpack_file_url', 'is_vcs_url', 'is_file_url', + 'unpack_http_url', 'unpack_url'] + + +logger = logging.getLogger(__name__) + + +def user_agent(): + """ + Return a string representing the user agent. + """ + data = { + "installer": {"name": "pip", "version": pip.__version__}, + "python": platform.python_version(), + "implementation": { + "name": platform.python_implementation(), + }, + } + + if data["implementation"]["name"] == 'CPython': + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'PyPy': + if sys.pypy_version_info.releaselevel == 'final': + pypy_version_info = sys.pypy_version_info[:3] + else: + pypy_version_info = sys.pypy_version_info + data["implementation"]["version"] = ".".join( + [str(x) for x in pypy_version_info] + ) + elif data["implementation"]["name"] == 'Jython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'IronPython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + + if sys.platform.startswith("linux"): + from pip._vendor import distro + distro_infos = dict(filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + )) + libc = dict(filter( + lambda x: x[1], + zip(["lib", "version"], libc_ver()), + )) + if libc: + distro_infos["libc"] = libc + if distro_infos: + data["distro"] = distro_infos + + if sys.platform.startswith("darwin") and platform.mac_ver()[0]: + data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} + + if platform.system(): + data.setdefault("system", {})["name"] = platform.system() + + if platform.release(): + data.setdefault("system", {})["release"] = platform.release() + + if platform.machine(): + data["cpu"] = platform.machine() + + if HAS_TLS: + data["openssl_version"] = ssl.OPENSSL_VERSION + + setuptools_version = get_installed_version("setuptools") + if setuptools_version is not None: + data["setuptools_version"] = setuptools_version + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True): + # type: (bool) -> None + self.prompting = prompting + self.passwords = {} # type: Dict[str, AuthInfo] + + def __call__(self, req): + parsed = urllib_parse.urlparse(req.url) + + # Split the credentials from the netloc. + netloc, url_user_password = split_auth_from_netloc(parsed.netloc) + + # Set the url of the request to the url without any credentials + req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + # Use the credentials embedded in the url if we have none stored + if username is None: + username, password = url_user_password + + # Get creds from netrc if we still don't have them + if username is None and password is None: + netrc_auth = get_netrc_auth(req.url) + username, password = netrc_auth if netrc_auth else (None, None) + + if username or password: + # Store the username and password + self.passwords[netloc] = (username, password) + + # Send the basic auth with this request + req = HTTPBasicAuth(username or "", password or "")(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + def handle_401(self, resp, **kwargs): + # We only care about 401 responses, anything else we want to just + # pass through the actual response + if resp.status_code != 401: + return resp + + # We are not able to prompt the user so simply return the response + if not self.prompting: + return resp + + parsed = urllib_parse.urlparse(resp.url) + + # Prompt the user for a new username and password + username = six.moves.input("User for %s: " % parsed.netloc) + password = getpass.getpass("Password: ") + + # Store the new username and password to use for future requests + if username or password: + self.passwords[parsed.netloc] = (username, password) + + # Consume content and release the original connection to allow our new + # request to reuse the same one. + resp.content + resp.raw.release_conn() + + # Add our new username and password to the request + req = HTTPBasicAuth(username or "", password or "")(resp.request) + req.register_hook("response", self.warn_on_401) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def warn_on_401(self, resp, **kwargs): + # warn user that they provided incorrect credentials + if resp.status_code == 401: + logger.warning('401 Error, Credentials not correct for %s', + resp.request.url) + + +class LocalFSAdapter(BaseAdapter): + + def send(self, request, stream=None, timeout=None, verify=None, cert=None, + proxies=None): + pathname = url_to_path(request.url) + + resp = Response() + resp.status_code = 200 + resp.url = request.url + + try: + stats = os.stat(pathname) + except OSError as exc: + resp.status_code = 404 + resp.raw = exc + else: + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + content_type = mimetypes.guess_type(pathname)[0] or "text/plain" + resp.headers = CaseInsensitiveDict({ + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + }) + + resp.raw = open(pathname, "rb") + resp.close = resp.raw.close + + return resp + + def close(self): + pass + + +class SafeFileCache(FileCache): + """ + A file based cache which is safe to use even when the target directory may + not be accessible or writable. + """ + + def __init__(self, *args, **kwargs): + super(SafeFileCache, self).__init__(*args, **kwargs) + + # Check to ensure that the directory containing our cache directory + # is owned by the user current executing pip. If it does not exist + # we will check the parent directory until we find one that does exist. + # If it is not owned by the user executing pip then we will disable + # the cache and log a warning. + if not check_path_owner(self.directory): + logger.warning( + "The directory '%s' or its parent directory is not owned by " + "the current user and the cache has been disabled. Please " + "check the permissions and owner of that directory. If " + "executing pip with sudo, you may want sudo's -H flag.", + self.directory, + ) + + # Set our directory to None to disable the Cache + self.directory = None + + def get(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).get(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def set(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).set(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def delete(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).delete(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + +class InsecureHTTPAdapter(HTTPAdapter): + + def cert_verify(self, conn, url, verify, cert): + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + + +class PipSession(requests.Session): + + timeout = None # type: Optional[int] + + def __init__(self, *args, **kwargs): + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + insecure_hosts = kwargs.pop("insecure_hosts", []) + + super(PipSession, self).__init__(*args, **kwargs) + + # Attach our User Agent to the request + self.headers["User-Agent"] = user_agent() + + # Attach our Authentication handler to the session + self.auth = MultiDomainBasicAuth() + + # Create our urllib3.Retry instance which will allow us to customize + # how we handle retries. + retries = urllib3.Retry( + # Set the total number of retries that a particular request can + # have. + total=retries, + + # A 503 error from PyPI typically means that the Fastly -> Origin + # connection got interrupted in some way. A 503 error in general + # is typically considered a transient error so we'll go ahead and + # retry it. + # A 500 may indicate transient error in Amazon S3 + # A 520 or 527 - may indicate transient error in CloudFlare + status_forcelist=[500, 503, 520, 527], + + # Add a small amount of back off between failed requests in + # order to prevent hammering the service. + backoff_factor=0.25, + ) + + # We want to _only_ cache responses on securely fetched origins. We do + # this because we can't validate the response of an insecurely fetched + # origin, and we don't want someone to be able to poison the cache and + # require manual eviction from the cache to fix it. + if cache: + secure_adapter = CacheControlAdapter( + cache=SafeFileCache(cache, use_dir_lock=True), + max_retries=retries, + ) + else: + secure_adapter = HTTPAdapter(max_retries=retries) + + # Our Insecure HTTPAdapter disables HTTPS validation. It does not + # support caching (see above) so we'll use it for all http:// URLs as + # well as any https:// host that we've marked as ignoring TLS errors + # for. + insecure_adapter = InsecureHTTPAdapter(max_retries=retries) + + self.mount("https://", secure_adapter) + self.mount("http://", insecure_adapter) + + # Enable file:// urls + self.mount("file://", LocalFSAdapter()) + + # We want to use a non-validating adapter for any requests which are + # deemed insecure. + for host in insecure_hosts: + self.mount("https://{}/".format(host), insecure_adapter) + + def request(self, method, url, *args, **kwargs): + # Allow setting a default timeout on a session + kwargs.setdefault("timeout", self.timeout) + + # Dispatch the actual request + return super(PipSession, self).request(method, url, *args, **kwargs) + + +def get_file_content(url, comes_from=None, session=None): + # type: (str, Optional[str], Optional[PipSession]) -> Tuple[str, Text] + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + + :param url: File path or url. + :param comes_from: Origin description of requirements. + :param session: Instance of pip.download.PipSession. + """ + if session is None: + raise TypeError( + "get_file_content() missing 1 required keyword argument: 'session'" + ) + + match = _scheme_re.search(url) + if match: + scheme = match.group(1).lower() + if (scheme == 'file' and comes_from and + comes_from.startswith('http')): + raise InstallationError( + 'Requirements file %s references URL %s, which is local' + % (comes_from, url)) + if scheme == 'file': + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib_parse.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + else: + # FIXME: catch some errors + resp = session.get(url) + resp.raise_for_status() + return resp.url, resp.text + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except IOError as exc: + raise InstallationError( + 'Could not open requirements file: %s' % str(exc) + ) + return url, content + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) + + +def is_url(name): + # type: (Union[str, Text]) -> bool + """Returns true if the name looks like a URL""" + if ':' not in name: + return False + scheme = name.split(':', 1)[0].lower() + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def url_to_path(url): + # type: (str) -> str + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not %r)" % url) + + _, netloc, path, _, _ = urllib_parse.urlsplit(url) + + # if we have a UNC path, prepend UNC share notation + if netloc: + netloc = '\\\\' + netloc + + path = urllib_request.url2pathname(netloc + path) + return path + + +def path_to_url(path): + # type: (Union[str, Text]) -> str + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) + return url + + +def is_archive_file(name): + # type: (str) -> bool + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False + + +def unpack_vcs_link(link, location): + vcs_backend = _get_used_vcs_backend(link) + vcs_backend.unpack(location) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + # type: (Link) -> bool + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + # type: (Link) -> bool + return link.url.lower().startswith('file:') + + +def is_dir_url(link): + # type: (Link) -> bool + """Return whether a file:// Link points to a directory. + + ``link`` must not have any other scheme but file://. Call is_file_url() + first. + + """ + link_path = url_to_path(link.url_without_fragment) + return os.path.isdir(link_path) + + +def _progress_indicator(iterable, *args, **kwargs): + return iterable + + +def _download_url( + resp, # type: Response + link, # type: Link + content_file, # type: IO + hashes, # type: Hashes + progress_bar # type: str +): + # type: (...) -> None + try: + total_length = int(resp.headers['content-length']) + except (ValueError, KeyError, TypeError): + total_length = 0 + + cached_resp = getattr(resp, "from_cache", False) + if logger.getEffectiveLevel() > logging.INFO: + show_progress = False + elif cached_resp: + show_progress = False + elif total_length > (40 * 1000): + show_progress = True + elif not total_length: + show_progress = True + else: + show_progress = False + + show_url = link.show_url + + def resp_read(chunk_size): + try: + # Special case for urllib3. + for chunk in resp.raw.stream( + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = resp.raw.read(chunk_size) + if not chunk: + break + yield chunk + + def written_chunks(chunks): + for chunk in chunks: + content_file.write(chunk) + yield chunk + + progress_indicator = _progress_indicator + + if link.netloc == PyPI.netloc: + url = show_url + else: + url = link.url_without_fragment + + if show_progress: # We don't show progress on cached responses + progress_indicator = DownloadProgressProvider(progress_bar, + max=total_length) + if total_length: + logger.info("Downloading %s (%s)", url, format_size(total_length)) + else: + logger.info("Downloading %s", url) + elif cached_resp: + logger.info("Using cached %s", url) + else: + logger.info("Downloading %s", url) + + logger.debug('Downloading from URL %s', link) + + downloaded_chunks = written_chunks( + progress_indicator( + resp_read(CONTENT_CHUNK_SIZE), + CONTENT_CHUNK_SIZE + ) + ) + if hashes: + hashes.check_against_chunks(downloaded_chunks) + else: + consume(downloaded_chunks) + + +def _copy_file(filename, location, link): + copy = True + download_location = os.path.join(location, link.filename) + if os.path.exists(download_location): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % + display_path(download_location), ('i', 'w', 'b', 'a')) + if response == 'i': + copy = False + elif response == 'w': + logger.warning('Deleting %s', display_path(download_location)) + os.remove(download_location) + elif response == 'b': + dest_file = backup_dir(download_location) + logger.warning( + 'Backing up %s to %s', + display_path(download_location), + display_path(dest_file), + ) + shutil.move(download_location, dest_file) + elif response == 'a': + sys.exit(-1) + if copy: + shutil.copy(filename, download_location) + logger.info('Saved %s', display_path(download_location)) + + +def unpack_http_url( + link, # type: Link + location, # type: str + download_dir=None, # type: Optional[str] + session=None, # type: Optional[PipSession] + hashes=None, # type: Optional[Hashes] + progress_bar="on" # type: str +): + # type: (...) -> None + if session is None: + raise TypeError( + "unpack_http_url() missing 1 required keyword argument: 'session'" + ) + + with TempDirectory(kind="unpack") as temp_dir: + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = mimetypes.guess_type(from_path)[0] + else: + # let's download to a tmp dir + from_path, content_type = _download_http_url(link, + session, + temp_dir.path, + hashes, + progress_bar) + + # unpack the archive to the build dir location. even when only + # downloading archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified; let's copy the archive there + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + if not already_downloaded_path: + os.unlink(from_path) + + +def unpack_file_url( + link, # type: Link + location, # type: str + download_dir=None, # type: Optional[str] + hashes=None # type: Optional[Hashes] +): + # type: (...) -> None + """Unpack link into location. + + If download_dir is provided and link points to a file, make a copy + of the link file inside download_dir. + """ + link_path = url_to_path(link.url_without_fragment) + + # If it's a url to a local directory + if is_dir_url(link): + if os.path.isdir(location): + rmtree(location) + shutil.copytree(link_path, location, symlinks=True) + if download_dir: + logger.info('Link is a directory, ignoring download_dir') + return + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(link_path) + + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link_path + + content_type = mimetypes.guess_type(from_path)[0] + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified and not already downloaded + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + +def _copy_dist_from_dir(link_path, location): + """Copy distribution files in `link_path` to `location`. + + Invoked when user requests to install a local directory. E.g.: + + pip install . + pip install ~/dev/git-repos/python-prompt-toolkit + + """ + + # Note: This is currently VERY SLOW if you have a lot of data in the + # directory, because it copies everything with `shutil.copytree`. + # What it should really do is build an sdist and install that. + # See https://github.com/pypa/pip/issues/2195 + + if os.path.isdir(location): + rmtree(location) + + # build an sdist + setup_py = 'setup.py' + sdist_args = [sys.executable] + sdist_args.append('-c') + sdist_args.append(SETUPTOOLS_SHIM % setup_py) + sdist_args.append('sdist') + sdist_args += ['--dist-dir', location] + logger.info('Running setup.py sdist for %s', link_path) + + with indent_log(): + call_subprocess(sdist_args, cwd=link_path, show_stdout=False) + + # unpack sdist into `location` + sdist = os.path.join(location, os.listdir(location)[0]) + logger.info('Unpacking sdist %s into %s', sdist, location) + unpack_file(sdist, location, content_type=None, link=None) + + +class PipXmlrpcTransport(xmlrpc_client.Transport): + """Provide a `xmlrpclib.Transport` implementation via a `PipSession` + object. + """ + + def __init__(self, index_url, session, use_datetime=False): + xmlrpc_client.Transport.__init__(self, use_datetime) + index_parts = urllib_parse.urlparse(index_url) + self._scheme = index_parts.scheme + self._session = session + + def request(self, host, handler, request_body, verbose=False): + parts = (self._scheme, host, handler, None, None, None) + url = urllib_parse.urlunparse(parts) + try: + headers = {'Content-Type': 'text/xml'} + response = self._session.post(url, data=request_body, + headers=headers, stream=True) + response.raise_for_status() + self.verbose = verbose + return self.parse_response(response.raw) + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", + exc.response.status_code, url, + ) + raise + + +def unpack_url( + link, # type: Optional[Link] + location, # type: Optional[str] + download_dir=None, # type: Optional[str] + only_download=False, # type: bool + session=None, # type: Optional[PipSession] + hashes=None, # type: Optional[Hashes] + progress_bar="on" # type: str +): + # type: (...) -> None + """Unpack link. + If link is a VCS link: + if only_download, export into download_dir and ignore location + else unpack into location + for other types of link: + - unpack into location + - if download_dir, copy the file into download_dir + - if only_download, mark location for deletion + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if is_vcs_url(link): + unpack_vcs_link(link, location) + + # file urls + elif is_file_url(link): + unpack_file_url(link, location, download_dir, hashes=hashes) + + # http urls + else: + if session is None: + session = PipSession() + + unpack_http_url( + link, + location, + download_dir, + session, + hashes=hashes, + progress_bar=progress_bar + ) + if only_download: + write_delete_marker_file(location) + + +def _download_http_url( + link, # type: Link + session, # type: PipSession + temp_dir, # type: str + hashes, # type: Hashes + progress_bar # type: str +): + # type: (...) -> Tuple[str, str] + """Download link url into temp_dir using provided session""" + target_url = link.url.split('#', 1)[0] + try: + resp = session.get( + target_url, + # We use Accept-Encoding: identity here because requests + # defaults to accepting compressed responses. This breaks in + # a variety of ways depending on how the server is configured. + # - Some servers will notice that the file isn't a compressible + # file and will leave the file alone and with an empty + # Content-Encoding + # - Some servers will notice that the file is already + # compressed and will leave the file alone and will add a + # Content-Encoding: gzip header + # - Some servers won't notice anything at all and will take + # a file that's already been compressed and compress it again + # and set the Content-Encoding: gzip header + # By setting this to request only the identity encoding We're + # hoping to eliminate the third case. Hopefully there does not + # exist a server which when given a file will notice it is + # already compressed and that you're not asking for a + # compressed file and will then decompress it before sending + # because if that's the case I don't think it'll ever be + # possible to make this work. + headers={"Accept-Encoding": "identity"}, + stream=True, + ) + resp.raise_for_status() + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", exc.response.status_code, link, + ) + raise + + content_type = resp.headers.get('content-type', '') + filename = link.filename # fallback + # Have a look at the Content-Disposition header for a better guess + content_disposition = resp.headers.get('content-disposition') + if content_disposition: + type, params = cgi.parse_header(content_disposition) + # We use ``or`` here because we don't want to use an "empty" value + # from the filename param. + filename = params.get('filename') or filename + ext = splitext(filename)[1] + if not ext: + ext = mimetypes.guess_extension(content_type) + if ext: + filename += ext + if not ext and link.url != resp.url: + ext = os.path.splitext(resp.url)[1] + if ext: + filename += ext + file_path = os.path.join(temp_dir, filename) + with open(file_path, 'wb') as content_file: + _download_url(resp, link, content_file, hashes, progress_bar) + return file_path, content_type + + +def _check_download_dir(link, download_dir, hashes): + # type: (Link, str, Hashes) -> Optional[str] + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + if os.path.exists(download_path): + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + return None diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/exceptions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/exceptions.py new file mode 100755 index 0000000..38ceeea --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/exceptions.py @@ -0,0 +1,274 @@ +"""Exceptions used throughout package""" +from __future__ import absolute_import + +from itertools import chain, groupby, repeat + +from pip._vendor.six import iteritems + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + self.errors = [] + + def append(self, error): + self.errors.append(error) + + def __str__(self): + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + + def __nonzero__(self): + return bool(self.errors) + + def __bool__(self): + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None # type: Optional[InstallRequirement] + head = '' + + def body(self): + """Return a summary of me for display under the heading. + + This default implementation simply prints a description of the + triggering requirement. + + :param req: The InstallRequirement that provoked this error, with + populate_link() having already been called + + """ + return ' %s' % self._requirement_name() + + def __str__(self): + return '%s\n%s' % (self.head, self.body()) + + def _requirement_name(self): + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' %s --hash=%s:%s' % (package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + return ' %s:\n%s' % (self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # For now, all the decent hashes have 6-char names, so we can get + # away with hard-coding space literals. + return chain([hash_name], repeat(' or')) + + lines = [] + for hash_name, expecteds in iteritems(self.allowed): + prefix = hash_then_or(hash_name) + lines.extend((' Expected %s %s' % (next(prefix), e)) + for e in expecteds) + lines.append(' Got %s\n' % + self.gots[hash_name].hexdigest()) + prefix = ' or' + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" + + +class ConfigurationFileCouldNotBeLoaded(ConfigurationError): + """When there are errors while loading a configuration file + """ + + def __init__(self, reason="could not be loaded", fname=None, error=None): + super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) + self.reason = reason + self.fname = fname + self.error = error + + def __str__(self): + if self.fname is not None: + message_part = " in {}.".format(self.fname) + else: + assert self.error is not None + message_part = ".\n{}\n".format(self.error.message) + return "Configuration file {}{}".format(self.reason, message_part) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/index.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/index.py new file mode 100755 index 0000000..9eda3a3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/index.py @@ -0,0 +1,990 @@ +"""Routines related to PyPI, indexes""" +from __future__ import absolute_import + +import cgi +import itertools +import logging +import mimetypes +import os +import posixpath +import re +import sys +from collections import namedtuple + +from pip._vendor import html5lib, requests, six +from pip._vendor.distlib.compat import unescape +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.requests.exceptions import RetryError, SSLError +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, + UnsupportedWheel, +) +from pip._internal.models.candidate import InstallationCandidate +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.models.link import Link +from pip._internal.pep425tags import get_supported +from pip._internal.utils.compat import ipaddress +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, WHEEL_EXTENSION, normalize_path, + redact_password_from_url, +) +from pip._internal.utils.packaging import check_requires_python +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.wheel import Wheel + +if MYPY_CHECK_RUNNING: + from logging import Logger # noqa: F401 + from typing import ( # noqa: F401 + Tuple, Optional, Any, List, Union, Callable, Set, Sequence, + Iterable, MutableMapping + ) + from pip._vendor.packaging.version import _BaseVersion # noqa: F401 + from pip._vendor.requests import Response # noqa: F401 + from pip._internal.req import InstallRequirement # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + + SecureOrigin = Tuple[str, str, Optional[str]] + BuildTag = Tuple[Any, ...] # either emply tuple or Tuple[int, str] + CandidateSortingKey = Tuple[int, _BaseVersion, BuildTag, Optional[int]] + +__all__ = ['FormatControl', 'PackageFinder'] + + +SECURE_ORIGINS = [ + # protocol, hostname, port + # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) + ("https", "*", "*"), + ("*", "localhost", "*"), + ("*", "127.0.0.0/8", "*"), + ("*", "::1/128", "*"), + ("file", "*", None), + # ssh is always secure. + ("ssh", "*", "*"), +] # type: List[SecureOrigin] + + +logger = logging.getLogger(__name__) + + +def _match_vcs_scheme(url): + # type: (str) -> Optional[str] + """Look for VCS schemes in the URL. + + Returns the matched VCS scheme, or None if there's no match. + """ + from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + return scheme + return None + + +def _is_url_like_archive(url): + # type: (str) -> bool + """Return whether the URL looks like an archive. + """ + filename = Link(url).filename + for bad_ext in ARCHIVE_EXTENSIONS: + if filename.endswith(bad_ext): + return True + return False + + +class _NotHTML(Exception): + def __init__(self, content_type, request_desc): + # type: (str, str) -> None + super(_NotHTML, self).__init__(content_type, request_desc) + self.content_type = content_type + self.request_desc = request_desc + + +def _ensure_html_header(response): + # type: (Response) -> None + """Check the Content-Type header to ensure the response contains HTML. + + Raises `_NotHTML` if the content type is not text/html. + """ + content_type = response.headers.get("Content-Type", "") + if not content_type.lower().startswith("text/html"): + raise _NotHTML(content_type, response.request.method) + + +class _NotHTTP(Exception): + pass + + +def _ensure_html_response(url, session): + # type: (str, PipSession) -> None + """Send a HEAD request to the URL, and ensure the response contains HTML. + + Raises `_NotHTTP` if the URL is not available for a HEAD request, or + `_NotHTML` if the content type is not text/html. + """ + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) + if scheme not in {'http', 'https'}: + raise _NotHTTP() + + resp = session.head(url, allow_redirects=True) + resp.raise_for_status() + + _ensure_html_header(resp) + + +def _get_html_response(url, session): + # type: (str, PipSession) -> Response + """Access an HTML page with GET, and return the response. + + This consists of three parts: + + 1. If the URL looks suspiciously like an archive, send a HEAD first to + check the Content-Type is HTML, to avoid downloading a large file. + Raise `_NotHTTP` if the content type cannot be determined, or + `_NotHTML` if it is not HTML. + 2. Actually perform the request. Raise HTTP exceptions on network failures. + 3. Check the Content-Type header to make sure we got HTML, and raise + `_NotHTML` otherwise. + """ + if _is_url_like_archive(url): + _ensure_html_response(url, session=session) + + logger.debug('Getting page %s', url) + + resp = session.get( + url, + headers={ + "Accept": "text/html", + # We don't want to blindly returned cached data for + # /simple/, because authors generally expecting that + # twine upload && pip install will function, but if + # they've done a pip install in the last ~10 minutes + # it won't. Thus by setting this to zero we will not + # blindly use any cached data, however the benefit of + # using max-age=0 instead of no-cache, is that we will + # still support conditional requests, so we will still + # minimize traffic sent in cases where the page hasn't + # changed at all, we will just always incur the round + # trip for the conditional GET now instead of only + # once per 10 minutes. + # For more information, please see pypa/pip#5670. + "Cache-Control": "max-age=0", + }, + ) + resp.raise_for_status() + + # The check for archives above only works if the url ends with + # something that looks like an archive. However that is not a + # requirement of an url. Unless we issue a HEAD request on every + # url we cannot know ahead of time for sure if something is HTML + # or not. However we can check after we've downloaded it. + _ensure_html_header(resp) + + return resp + + +def _handle_get_page_fail( + link, # type: Link + reason, # type: Union[str, Exception] + meth=None # type: Optional[Callable[..., None]] +): + # type: (...) -> None + if meth is None: + meth = logger.debug + meth("Could not fetch URL %s: %s - skipping", link, reason) + + +def _get_html_page(link, session=None): + # type: (Link, Optional[PipSession]) -> Optional[HTMLPage] + if session is None: + raise TypeError( + "_get_html_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + vcs_scheme = _match_vcs_scheme(url) + if vcs_scheme: + logger.debug('Cannot look at %s URL %s', vcs_scheme, link) + return None + + # Tack index.html onto file:// URLs that point to directories + scheme, _, path, _, _, _ = urllib_parse.urlparse(url) + if (scheme == 'file' and os.path.isdir(urllib_request.url2pathname(path))): + # add trailing slash if not present so urljoin doesn't trim + # final segment + if not url.endswith('/'): + url += '/' + url = urllib_parse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s', url) + + try: + resp = _get_html_response(url, session=session) + except _NotHTTP as exc: + logger.debug( + 'Skipping page %s because it looks like an archive, and cannot ' + 'be checked by HEAD.', link, + ) + except _NotHTML as exc: + logger.debug( + 'Skipping page %s because the %s request got Content-Type: %s', + link, exc.request_desc, exc.content_type, + ) + except requests.HTTPError as exc: + _handle_get_page_fail(link, exc) + except RetryError as exc: + _handle_get_page_fail(link, exc) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + _handle_get_page_fail(link, reason, meth=logger.info) + except requests.ConnectionError as exc: + _handle_get_page_fail(link, "connection error: %s" % exc) + except requests.Timeout: + _handle_get_page_fail(link, "timed out") + else: + return HTMLPage(resp.content, resp.url, resp.headers) + return None + + +class PackageFinder(object): + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links. + """ + + def __init__( + self, + find_links, # type: List[str] + index_urls, # type: List[str] + allow_all_prereleases=False, # type: bool + trusted_hosts=None, # type: Optional[Iterable[str]] + session=None, # type: Optional[PipSession] + format_control=None, # type: Optional[FormatControl] + platform=None, # type: Optional[str] + versions=None, # type: Optional[List[str]] + abi=None, # type: Optional[str] + implementation=None, # type: Optional[str] + prefer_binary=False # type: bool + ): + # type: (...) -> None + """Create a PackageFinder. + + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param platform: A string or None. If None, searches for packages + that are supported by the current system. Otherwise, will find + packages that can be built on the platform passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param versions: A list of strings or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param abi: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param implementation: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + """ + if session is None: + raise TypeError( + "PackageFinder() missing 1 required keyword argument: " + "'session'" + ) + + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + self.find_links = [] # type: List[str] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + self.find_links.append(link) + + self.index_urls = index_urls + + # These are boring links that have already been logged somehow: + self.logged_links = set() # type: Set[Link] + + self.format_control = format_control or FormatControl(set(), set()) + + # Domains that we won't emit warnings for when not using HTTPS + self.secure_origins = [ + ("*", host, "*") + for host in (trusted_hosts if trusted_hosts else []) + ] # type: List[SecureOrigin] + + # Do we want to allow _all_ pre-releases? + self.allow_all_prereleases = allow_all_prereleases + + # The Session we'll use to make requests + self.session = session + + # The valid tags to check potential found wheel candidates against + self.valid_tags = get_supported( + versions=versions, + platform=platform, + abi=abi, + impl=implementation, + ) + + # Do we prefer old, but valid, binary dist over new source dist + self.prefer_binary = prefer_binary + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not HAS_TLS: + for link in itertools.chain(self.index_urls, self.find_links): + parsed = urllib_parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + def get_formatted_locations(self): + # type: () -> str + lines = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + lines.append( + "Looking in indexes: {}".format(", ".join( + redact_password_from_url(url) for url in self.index_urls)) + ) + if self.find_links: + lines.append( + "Looking in links: {}".format(", ".join(self.find_links)) + ) + return "\n".join(lines) + + @staticmethod + def _sort_locations(locations, expand_dir=False): + # type: (Sequence[str], bool) -> Tuple[List[str], List[str]] + """ + Sort locations into "files" (archives) and "urls", and return + a pair of lists (files,urls) + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate list + def sort_path(path): + url = path_to_url(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + + is_local_path = os.path.exists(url) + is_file_url = url.startswith('file:') + + if is_local_path or is_file_url: + if is_local_path: + path = url + else: + path = url_to_path(url) + if os.path.isdir(path): + if expand_dir: + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif is_file_url: + urls.append(url) + else: + logger.warning( + "Path '{0}' is ignored: " + "it is a directory.".format(path), + ) + elif os.path.isfile(path): + sort_path(path) + else: + logger.warning( + "Url '%s' is ignored: it is neither a file " + "nor a directory.", url, + ) + elif is_url(url): + # Only add url with clear scheme + urls.append(url) + else: + logger.warning( + "Url '%s' is ignored. It is either a non-existing " + "path or lacks a specific scheme.", url, + ) + + return files, urls + + def _candidate_sort_key(self, candidate): + # type: (InstallationCandidate) -> CandidateSortingKey + """ + Function used to generate link sort key for link tuples. + The greater the return value, the more preferred it is. + If not finding wheels, then sorted by version only. + If finding wheels, then the sort order is by version, then: + 1. existing installs + 2. wheels ordered via Wheel.support_index_min(self.valid_tags) + 3. source archives + If prefer_binary was set, then all wheels are sorted above sources. + Note: it was considered to embed this logic into the Link + comparison operators, but then different sdist links + with the same version, would have to be considered equal + """ + support_num = len(self.valid_tags) + build_tag = tuple() # type: BuildTag + binary_preference = 0 + if candidate.location.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(candidate.location.filename) + if not wheel.supported(self.valid_tags): + raise UnsupportedWheel( + "%s is not a supported wheel for this platform. It " + "can't be sorted." % wheel.filename + ) + if self.prefer_binary: + binary_preference = 1 + pri = -(wheel.support_index_min(self.valid_tags)) + if wheel.build_tag is not None: + match = re.match(r'^(\d+)(.*)$', wheel.build_tag) + build_tag_groups = match.groups() + build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) + else: # sdist + pri = -(support_num) + return (binary_preference, candidate.version, build_tag, pri) + + def _validate_secure_origin(self, logger, location): + # type: (Logger, Link) -> bool + # Determine if this url used a secure transport mechanism + parsed = urllib_parse.urlparse(str(location)) + origin = (parsed.scheme, parsed.hostname, parsed.port) + + # The protocol to use to see if the protocol matches. + # Don't count the repository type as part of the protocol: in + # cases such as "git+ssh", only use "ssh". (I.e., Only verify against + # the last scheme.) + protocol = origin[0].rsplit('+', 1)[-1] + + # Determine if our origin is a secure origin by looking through our + # hardcoded list of secure origins, as well as any additional ones + # configured on this PackageFinder instance. + for secure_origin in (SECURE_ORIGINS + self.secure_origins): + if protocol != secure_origin[0] and secure_origin[0] != "*": + continue + + try: + # We need to do this decode dance to ensure that we have a + # unicode object, even on Python 2.x. + addr = ipaddress.ip_address( + origin[1] + if ( + isinstance(origin[1], six.text_type) or + origin[1] is None + ) + else origin[1].decode("utf8") + ) + network = ipaddress.ip_network( + secure_origin[1] + if isinstance(secure_origin[1], six.text_type) + # setting secure_origin[1] to proper Union[bytes, str] + # creates problems in other places + else secure_origin[1].decode("utf8") # type: ignore + ) + except ValueError: + # We don't have both a valid address or a valid network, so + # we'll check this origin against hostnames. + if (origin[1] and + origin[1].lower() != secure_origin[1].lower() and + secure_origin[1] != "*"): + continue + else: + # We have a valid address and network, so see if the address + # is contained within the network. + if addr not in network: + continue + + # Check to see if the port patches + if (origin[2] != secure_origin[2] and + secure_origin[2] != "*" and + secure_origin[2] is not None): + continue + + # If we've gotten here, then this origin matches the current + # secure origin and we should return True + return True + + # If we've gotten to this point, then the origin isn't secure and we + # will not accept it as a valid location to search. We will however + # log a warning that we are ignoring it. + logger.warning( + "The repository located at %s is not a trusted or secure host and " + "is being ignored. If this repository is available via HTTPS we " + "recommend you use HTTPS instead, otherwise you may silence " + "this warning and allow it anyway with '--trusted-host %s'.", + parsed.hostname, + parsed.hostname, + ) + + return False + + def _get_index_urls_locations(self, project_name): + # type: (str) -> List[str] + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + loc = posixpath.join( + url, + urllib_parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] + + def find_all_candidates(self, project_name): + # type: (str) -> List[Optional[InstallationCandidate]] + """Find all available InstallationCandidate for project_name + + This checks index_urls and find_links. + All versions found are returned as an InstallationCandidate list. + + See _link_package_versions for details on which files are accepted + """ + index_locations = self._get_index_urls_locations(project_name) + index_file_loc, index_url_loc = self._sort_locations(index_locations) + fl_file_loc, fl_url_loc = self._sort_locations( + self.find_links, expand_dir=True, + ) + + file_locations = (Link(url) for url in itertools.chain( + index_file_loc, fl_file_loc, + )) + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links. + # We want to filter out any thing which does not have a secure origin. + url_locations = [ + link for link in itertools.chain( + (Link(url) for url in index_url_loc), + (Link(url) for url in fl_url_loc), + ) + if self._validate_secure_origin(logger, link) + ] + + logger.debug('%d location(s) to search for versions of %s:', + len(url_locations), project_name) + + for location in url_locations: + logger.debug('* %s', location) + + canonical_name = canonicalize_name(project_name) + formats = self.format_control.get_allowed_formats(canonical_name) + search = Search(project_name, canonical_name, formats) + find_links_versions = self._package_versions( + # We trust every directly linked archive in find_links + (Link(url, '-f') for url in self.find_links), + search + ) + + page_versions = [] + for page in self._get_pages(url_locations, project_name): + logger.debug('Analyzing links from page %s', page.url) + with indent_log(): + page_versions.extend( + self._package_versions(page.iter_links(), search) + ) + + file_versions = self._package_versions(file_locations, search) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.location.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return file_versions + find_links_versions + page_versions + + def find_requirement(self, req, upgrade): + # type: (InstallRequirement, bool) -> Optional[Link] + """Try to find a Link matching req + + Expects req, an InstallRequirement and upgrade, a boolean + Returns a Link if found, + Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise + """ + all_candidates = self.find_all_candidates(req.name) + + # Filter out anything which doesn't match our specifier + compatible_versions = set( + req.specifier.filter( + # We turn the version object into a str here because otherwise + # when we're debundled but setuptools isn't, Python will see + # packaging.version.Version and + # pkg_resources._vendor.packaging.version.Version as different + # types. This way we'll use a str as a common data interchange + # format. If we stop using the pkg_resources provided specifier + # and start using our own, we can drop the cast to str(). + [str(c.version) for c in all_candidates], + prereleases=( + self.allow_all_prereleases + if self.allow_all_prereleases else None + ), + ) + ) + applicable_candidates = [ + # Again, converting to str to deal with debundling. + c for c in all_candidates if str(c.version) in compatible_versions + ] + + if applicable_candidates: + best_candidate = max(applicable_candidates, + key=self._candidate_sort_key) + else: + best_candidate = None + + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + else: + installed_version = None + + if installed_version is None and best_candidate is None: + logger.critical( + 'Could not find a version that satisfies the requirement %s ' + '(from versions: %s)', + req, + ', '.join( + sorted( + {str(c.version) for c in all_candidates}, + key=parse_version, + ) + ) + ) + + raise DistributionNotFound( + 'No matching distribution found for %s' % req + ) + + best_installed = False + if installed_version and ( + best_candidate is None or + best_candidate.version <= installed_version): + best_installed = True + + if not upgrade and installed_version is not None: + if best_installed: + logger.debug( + 'Existing installed version (%s) is most up-to-date and ' + 'satisfies requirement', + installed_version, + ) + else: + logger.debug( + 'Existing installed version (%s) satisfies requirement ' + '(most up-to-date version is %s)', + installed_version, + best_candidate.version, + ) + return None + + if best_installed: + # We have an existing version, and its the best version + logger.debug( + 'Installed version (%s) is most up-to-date (past versions: ' + '%s)', + installed_version, + ', '.join(sorted(compatible_versions, key=parse_version)) or + "none", + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + ', '.join(sorted(compatible_versions, key=parse_version)) + ) + return best_candidate.location + + def _get_pages(self, locations, project_name): + # type: (Iterable[Link], str) -> Iterable[HTMLPage] + """ + Yields (page, page_url) from the given locations, skipping + locations that have errors. + """ + seen = set() # type: Set[Link] + for location in locations: + if location in seen: + continue + seen.add(location) + + page = _get_html_page(location, session=self.session) + if page is None: + continue + + yield page + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + def _sort_links(self, links): + # type: (Iterable[Link]) -> List[Link] + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() # type: Set[Link] + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _package_versions( + self, + links, # type: Iterable[Link] + search # type: Search + ): + # type: (...) -> List[Optional[InstallationCandidate]] + result = [] + for link in self._sort_links(links): + v = self._link_package_versions(link, search) + if v is not None: + result.append(v) + return result + + def _log_skipped_link(self, link, reason): + # type: (Link, str) -> None + if link not in self.logged_links: + logger.debug('Skipping link %s; %s', link, reason) + self.logged_links.add(link) + + def _link_package_versions(self, link, search): + # type: (Link, Search) -> Optional[InstallationCandidate] + """Return an InstallationCandidate or None""" + version = None + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + self._log_skipped_link(link, 'not a file') + return None + if ext not in SUPPORTED_EXTENSIONS: + self._log_skipped_link( + link, 'unsupported archive format: %s' % ext, + ) + return None + if "binary" not in search.formats and ext == WHEEL_EXTENSION: + self._log_skipped_link( + link, 'No binaries permitted for %s' % search.supplied, + ) + return None + if "macosx10" in link.path and ext == '.zip': + self._log_skipped_link(link, 'macosx10 one') + return None + if ext == WHEEL_EXTENSION: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + self._log_skipped_link(link, 'invalid wheel filename') + return None + if canonicalize_name(wheel.name) != search.canonical: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return None + + if not wheel.supported(self.valid_tags): + self._log_skipped_link( + link, 'it is not compatible with this Python') + return None + + version = wheel.version + + # This should be up by the search.ok_binary check, but see issue 2700. + if "source" not in search.formats and ext != WHEEL_EXTENSION: + self._log_skipped_link( + link, 'No sources permitted for %s' % search.supplied, + ) + return None + + if not version: + version = _egg_info_matches(egg_info, search.canonical) + if not version: + self._log_skipped_link( + link, 'Missing project version for %s' % search.supplied) + return None + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + self._log_skipped_link( + link, 'Python version is incorrect') + return None + try: + support_this_python = check_requires_python(link.requires_python) + except specifiers.InvalidSpecifier: + logger.debug("Package %s has an invalid Requires-Python entry: %s", + link.filename, link.requires_python) + support_this_python = True + + if not support_this_python: + logger.debug("The package %s is incompatible with the python " + "version in use. Acceptable python versions are: %s", + link, link.requires_python) + return None + logger.debug('Found link %s, version: %s', link, version) + + return InstallationCandidate(search.supplied, version, link) + + +def _find_name_version_sep(egg_info, canonical_name): + # type: (str, str) -> int + """Find the separator's index based on the package's canonical name. + + `egg_info` must be an egg info string for the given package, and + `canonical_name` must be the package's canonical name. + + This function is needed since the canonicalized name does not necessarily + have the same length as the egg info's name part. An example:: + + >>> egg_info = 'foo__bar-1.0' + >>> canonical_name = 'foo-bar' + >>> _find_name_version_sep(egg_info, canonical_name) + 8 + """ + # Project name and version must be separated by one single dash. Find all + # occurrences of dashes; if the string in front of it matches the canonical + # name, this is the one separating the name and version parts. + for i, c in enumerate(egg_info): + if c != "-": + continue + if canonicalize_name(egg_info[:i]) == canonical_name: + return i + raise ValueError("{} does not match {}".format(egg_info, canonical_name)) + + +def _egg_info_matches(egg_info, canonical_name): + # type: (str, str) -> Optional[str] + """Pull the version part out of a string. + + :param egg_info: The string to parse. E.g. foo-2.1 + :param canonical_name: The canonicalized name of the package this + belongs to. + """ + try: + version_start = _find_name_version_sep(egg_info, canonical_name) + 1 + except ValueError: + return None + version = egg_info[version_start:] + if not version: + return None + return version + + +def _determine_base_url(document, page_url): + """Determine the HTML document's base URL. + + This looks for a ```` tag in the HTML document. If present, its href + attribute denotes the base URL of anchor tags in the document. If there is + no such tag (or if it does not have a valid href attribute), the HTML + file's URL is used as the base URL. + + :param document: An HTML document representation. The current + implementation expects the result of ``html5lib.parse()``. + :param page_url: The URL of the HTML document. + """ + for base in document.findall(".//base"): + href = base.get("href") + if href is not None: + return href + return page_url + + +def _get_encoding_from_headers(headers): + """Determine if we have any encoding information in our headers. + """ + if headers and "Content-Type" in headers: + content_type, params = cgi.parse_header(headers["Content-Type"]) + if "charset" in params: + return params['charset'] + return None + + +_CLEAN_LINK_RE = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + +def _clean_link(url): + # type: (str) -> str + """Makes sure a link is fully encoded. That is, if a ' ' shows up in + the link, it will be rewritten to %20 (while not over-quoting + % or other characters).""" + return _CLEAN_LINK_RE.sub(lambda match: '%%%2x' % ord(match.group(0)), url) + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + def __init__(self, content, url, headers=None): + # type: (bytes, str, MutableMapping[str, str]) -> None + self.content = content + self.url = url + self.headers = headers + + def __str__(self): + return redact_password_from_url(self.url) + + def iter_links(self): + # type: () -> Iterable[Link] + """Yields all links in the page""" + document = html5lib.parse( + self.content, + transport_encoding=_get_encoding_from_headers(self.headers), + namespaceHTMLElements=False, + ) + base_url = _determine_base_url(document, self.url) + for anchor in document.findall(".//a"): + if anchor.get("href"): + href = anchor.get("href") + url = _clean_link(urllib_parse.urljoin(base_url, href)) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + yield Link(url, self.url, requires_python=pyrequire) + + +Search = namedtuple('Search', 'supplied canonical formats') +"""Capture key aspects of a search. + +:attribute supplied: The user supplied package. +:attribute canonical: The canonical package name. +:attribute formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. +""" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/locations.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/locations.py new file mode 100755 index 0000000..c6e2a3e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/locations.py @@ -0,0 +1,211 @@ +"""Locations where we look for configs, install stuff, etc""" +from __future__ import absolute_import + +import os +import os.path +import platform +import site +import sys +import sysconfig +from distutils import sysconfig as distutils_sysconfig +from distutils.command.install import SCHEME_KEYS # type: ignore + +from pip._internal.utils import appdirs +from pip._internal.utils.compat import WINDOWS, expanduser +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Union, Dict, List, Optional # noqa: F401 + + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +DELETE_MARKER_MESSAGE = '''\ +This file is placed here by pip to indicate the source was put +here by pip. + +Once this package is successfully installed this source code will be +deleted (unless you remove this file). +''' +PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' + + +def write_delete_marker_file(directory): + # type: (str) -> None + """ + Write the pip delete marker file into this directory. + """ + filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) + with open(filepath, 'w') as marker_fp: + marker_fp.write(DELETE_MARKER_MESSAGE) + + +def running_under_virtualenv(): + # type: () -> bool + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + if hasattr(sys, 'real_prefix'): + return True + elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): + return True + + return False + + +def virtualenv_no_global(): + # type: () -> bool + """ + Return True if in a venv and no system site packages. + """ + # this mirrors the logic in virtualenv.py for locating the + # no-global-site-packages.txt file + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') + if running_under_virtualenv() and os.path.isfile(no_global_file): + return True + else: + return False + + +if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') +else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + +# under macOS + virtualenv sys.prefix is not properly resolved +# it is something like /path/to/python/bin/.. +# Note: using realpath due to tmp dirs on OSX being symlinks +src_prefix = os.path.abspath(src_prefix) + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") # type: Optional[str] + +# This is because of a bug in PyPy's sysconfig module, see +# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths +# for more information. +if platform.python_implementation().lower() == "pypy": + site_packages = distutils_sysconfig.get_python_lib() +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE +user_dir = expanduser('~') +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.ini' + + legacy_storage_dir = os.path.join(user_dir, 'pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.conf' + + legacy_storage_dir = os.path.join(user_dir, '.pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + +site_config_files = [ + os.path.join(path, config_basename) + for path in appdirs.site_config_dirs('pip') +] + +venv_config_file = os.path.join(sys.prefix, config_basename) +new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) + + +def distutils_scheme(dist_name, user=False, home=None, root=None, + isolated=False, prefix=None): + # type:(str, bool, str, str, bool, str) -> dict + """ + Return a distutils install scheme + """ + from distutils.dist import Distribution + + scheme = {} + + if isolated: + extra_dist_args = {"script_args": ["--no-user-cfg"]} + else: + extra_dist_args = {} + dist_args = {'name': dist_name} # type: Dict[str, Union[str, List[str]]] + dist_args.update(extra_dist_args) + + d = Distribution(dist_args) + # Ignoring, typeshed issue reported python/typeshed/issues/2567 + d.parse_config_files() + # NOTE: Ignoring type since mypy can't find attributes on 'Command' + i = d.get_command_obj('install', create=True) # type: Any + assert i is not None + # NOTE: setting user or home has the side-effect of creating the home dir + # or user base for installations during finalize_options() + # ideally, we'd prefer a scheme class that has no side-effects. + assert not (user and prefix), "user={} prefix={}".format(user, prefix) + i.user = user or i.user + if user: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # platlib). Note, i.install_lib is *always* set after + # finalize_options(); we only want to override here if the user + # has explicitly requested it hence going back to the config + + # Ignoring, typeshed issue reported python/typeshed/issues/2567 + if 'install_lib' in d.get_option_dict('install'): # type: ignore + scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + + if running_under_virtualenv(): + scheme['headers'] = os.path.join( + sys.prefix, + 'include', + 'site', + 'python' + sys.version[:3], + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/__init__.py new file mode 100755 index 0000000..7855226 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/__init__.py @@ -0,0 +1,2 @@ +"""A package that contains models that represent entities. +""" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/candidate.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/candidate.py new file mode 100755 index 0000000..4475458 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/candidate.py @@ -0,0 +1,31 @@ +from pip._vendor.packaging.version import parse as parse_version + +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._vendor.packaging.version import _BaseVersion # noqa: F401 + from pip._internal.models.link import Link # noqa: F401 + from typing import Any, Union # noqa: F401 + + +class InstallationCandidate(KeyBasedCompareMixin): + """Represents a potential "candidate" for installation. + """ + + def __init__(self, project, version, location): + # type: (Any, str, Link) -> None + self.project = project + self.version = parse_version(version) # type: _BaseVersion + self.location = location + + super(InstallationCandidate, self).__init__( + key=(self.project, self.version, self.location), + defining_class=InstallationCandidate + ) + + def __repr__(self): + # type: () -> str + return "".format( + self.project, self.version, self.location, + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/format_control.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/format_control.py new file mode 100755 index 0000000..971a391 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/format_control.py @@ -0,0 +1,73 @@ +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, Set, FrozenSet # noqa: F401 + + +class FormatControl(object): + """Helper for managing formats from which a package can be installed. + """ + + def __init__(self, no_binary=None, only_binary=None): + # type: (Optional[Set], Optional[Set]) -> None + if no_binary is None: + no_binary = set() + if only_binary is None: + only_binary = set() + + self.no_binary = no_binary + self.only_binary = only_binary + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "{}({}, {})".format( + self.__class__.__name__, + self.no_binary, + self.only_binary + ) + + @staticmethod + def handle_mutual_excludes(value, target, other): + # type: (str, Optional[Set], Optional[Set]) -> None + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + # Without a none, we want to discard everything as :all: covers it + if ':none:' not in new: + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + def get_allowed_formats(self, canonical_name): + # type: (str) -> FrozenSet + result = {"binary", "source"} + if canonical_name in self.only_binary: + result.discard('source') + elif canonical_name in self.no_binary: + result.discard('binary') + elif ':all:' in self.only_binary: + result.discard('source') + elif ':all:' in self.no_binary: + result.discard('binary') + return frozenset(result) + + def disallow_binaries(self): + # type: () -> None + self.handle_mutual_excludes( + ':all:', self.no_binary, self.only_binary, + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/index.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/index.py new file mode 100755 index 0000000..ead1efb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/index.py @@ -0,0 +1,31 @@ +from pip._vendor.six.moves.urllib import parse as urllib_parse + + +class PackageIndex(object): + """Represents a Package Index and provides easier access to endpoints + """ + + def __init__(self, url, file_storage_domain): + # type: (str, str) -> None + super(PackageIndex, self).__init__() + self.url = url + self.netloc = urllib_parse.urlsplit(url).netloc + self.simple_url = self._url_for_path('simple') + self.pypi_url = self._url_for_path('pypi') + + # This is part of a temporary hack used to block installs of PyPI + # packages which depend on external urls only necessary until PyPI can + # block such packages themselves + self.file_storage_domain = file_storage_domain + + def _url_for_path(self, path): + # type: (str) -> str + return urllib_parse.urljoin(self.url, path) + + +PyPI = PackageIndex( + 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' +) +TestPyPI = PackageIndex( + 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' +) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/link.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/link.py new file mode 100755 index 0000000..ad2f93e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/models/link.py @@ -0,0 +1,163 @@ +import posixpath +import re + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import ( + WHEEL_EXTENSION, redact_password_from_url, splitext, +) +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple, Union, Text # noqa: F401 + from pip._internal.index import HTMLPage # noqa: F401 + + +class Link(KeyBasedCompareMixin): + """Represents a parsed link from a Package Index's simple URL + """ + + def __init__(self, url, comes_from=None, requires_python=None): + # type: (str, Optional[Union[str, HTMLPage]], Optional[str]) -> None + """ + url: + url of the resource pointed to (href of the link) + comes_from: + instance of HTMLPage where the link was found, or string. + requires_python: + String containing the `Requires-Python` metadata field, specified + in PEP 345. This may be specified by a data-requires-python + attribute in the HTML link tag, as described in PEP 503. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self.url = url + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + + super(Link, self).__init__( + key=(self.url), + defining_class=Link + ) + + def __str__(self): + if self.requires_python: + rp = ' (requires-python:%s)' % self.requires_python + else: + rp = '' + if self.comes_from: + return '%s (from %s)%s' % (redact_password_from_url(self.url), + self.comes_from, rp) + else: + return redact_password_from_url(str(self.url)) + + def __repr__(self): + return '' % self + + @property + def filename(self): + # type: () -> str + _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) + name = posixpath.basename(path.rstrip('/')) or netloc + name = urllib_parse.unquote(name) + assert name, ('URL %r produced no filename' % self.url) + return name + + @property + def scheme(self): + # type: () -> str + return urllib_parse.urlsplit(self.url)[0] + + @property + def netloc(self): + # type: () -> str + return urllib_parse.urlsplit(self.url)[1] + + @property + def path(self): + # type: () -> str + return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) + + def splitext(self): + # type: () -> Tuple[str, str] + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + # type: () -> str + return self.splitext()[1] + + @property + def url_without_fragment(self): + # type: () -> str + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) + return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + # type: () -> Optional[str] + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + # type: () -> Optional[str] + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + # type: () -> Optional[str] + match = self._hash_re.search(self.url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + # type: () -> Optional[str] + match = self._hash_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + # type: () -> Optional[str] + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_wheel(self): + # type: () -> bool + return self.ext == WHEEL_EXTENSION + + @property + def is_artifact(self): + # type: () -> bool + """ + Determines if this points to an actual artifact (e.g. a tarball) or if + it points to an "abstract" thing like a path or a VCS location. + """ + from pip._internal.vcs import vcs + + if self.scheme in vcs.all_schemes: + return False + + return True diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/check.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/check.py new file mode 100755 index 0000000..0b56eda --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/check.py @@ -0,0 +1,155 @@ +"""Validation of dependencies of packages +""" + +import logging +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.operations.prepare import make_abstract_dist +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +logger = logging.getLogger(__name__) + +if MYPY_CHECK_RUNNING: + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from typing import ( # noqa: F401 + Any, Callable, Dict, Optional, Set, Tuple, List + ) + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> Tuple[PackageSet, bool] + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + + package_set = {} + problems = False + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + try: + package_set[name] = PackageDetails(dist.version, dist.requires()) + except RequirementParseError as e: + # Don't crash on broken metadata + logging.warning("Error parsing requirements for %s: %s", name, e) + problems = True + return package_set, problems + + +def check_package_set(package_set, should_ignore=None): + # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult + """Check if a package set is consistent + + If should_ignore is passed, it should be a callable that takes a + package name and returns a boolean. + """ + if should_ignore is None: + def should_ignore(name): + return False + + missing = dict() + conflicting = dict() + + for package_name in package_set: + # Info about dependencies of package_name + missing_deps = set() # type: Set[Missing] + conflicting_deps = set() # type: Set[Conflicting] + + if should_ignore(package_name): + continue + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + package_set, _ = create_package_set_from_installed() + # Install packages + would_be_installed = _simulate_installation_of(to_install, package_set) + + # Only warn about directly-dependent packages; create a whitelist of them + whitelist = _create_whitelist(would_be_installed, package_set) + + return ( + package_set, + check_package_set( + package_set, should_ignore=lambda name: name not in whitelist + ) + ) + + +def _simulate_installation_of(to_install, package_set): + # type: (List[InstallRequirement], PackageSet) -> Set[str] + """Computes the version of packages after installing to_install. + """ + + # Keep track of packages that were installed + installed = set() + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + dist = make_abstract_dist(inst_req).dist() + name = canonicalize_name(dist.key) + package_set[name] = PackageDetails(dist.version, dist.requires()) + + installed.add(name) + + return installed + + +def _create_whitelist(would_be_installed, package_set): + # type: (Set[str], PackageSet) -> Set[str] + packages_affected = set(would_be_installed) + + for package_name in package_set: + if package_name in packages_affected: + continue + + for req in package_set[package_name].requires: + if canonicalize_name(req.name) in packages_affected: + packages_affected.add(package_name) + break + + return packages_affected diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/freeze.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/freeze.py new file mode 100755 index 0000000..388bb73 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/freeze.py @@ -0,0 +1,247 @@ +from __future__ import absolute_import + +import collections +import logging +import os +import re + +from pip._vendor import six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import BadCommand, InstallationError +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Iterator, Optional, List, Container, Set, Dict, Tuple, Iterable, Union + ) + from pip._internal.cache import WheelCache # noqa: F401 + from pip._vendor.pkg_resources import ( # noqa: F401 + Distribution, Requirement + ) + + RequirementInfo = Tuple[Optional[Union[str, Requirement]], bool, List[str]] + + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, # type: Optional[List[str]] + find_links=None, # type: Optional[List[str]] + local_only=None, # type: Optional[bool] + user_only=None, # type: Optional[bool] + skip_regex=None, # type: Optional[str] + isolated=False, # type: bool + wheel_cache=None, # type: Optional[WheelCache] + exclude_editable=False, # type: bool + skip=() # type: Container[str] +): + # type: (...) -> Iterator[str] + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex).search + + for link in find_links: + yield '-f %s' % link + installations = {} # type: Dict[str, FrozenRequirement] + for dist in get_installed_distributions(local_only=local_only, + skip=(), + user_only=user_only): + try: + req = FrozenRequirement.from_dist(dist) + except RequirementParseError: + logger.warning( + "Could not parse requirement: %s", + dist.project_name + ) + continue + if exclude_editable and req.editable: + continue + installations[req.name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() # type: Set[str] + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) # type: Dict[str, List[str]] + for req_file_path in requirement: + with open(req_file_path) as req_file: + for line in req_file: + if (not line.strip() or + line.strip().startswith('#') or + (skip_match and skip_match(line)) or + line.startswith(( + '-r', '--requirement', + '-Z', '--always-unzip', + '-f', '--find-links', + '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', + '--extra-index-url'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = install_req_from_editable( + line, + isolated=isolated, + wheel_cache=wheel_cache, + ) + else: + line_req = install_req_from_line( + COMMENT_RE.sub('', line).strip(), + isolated=isolated, + wheel_cache=wheel_cache, + ) + + if not line_req.name: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + elif line_req.name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but " + "package %r is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), line_req.name + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[line_req.name]).rstrip() + del installations[line_req.name] + req_files[line_req.name].append(req_file_path) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in six.iteritems(req_files): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() + + +def get_requirement_info(dist): + # type: (Distribution) -> RequirementInfo + """ + Compute and return values (req, editable, comments) for use in + FrozenRequirement.from_dist(). + """ + if not dist_is_editable(dist): + return (None, False, []) + + location = os.path.normcase(os.path.abspath(dist.location)) + + from pip._internal.vcs import vcs, RemoteNotFoundError + vc_type = vcs.get_backend_type(location) + + if not vc_type: + req = dist.as_requirement() + logger.debug( + 'No VCS found for editable requirement {!r} in: {!r}', req, + location, + ) + comments = [ + '# Editable install with no version control ({})'.format(req) + ] + return (location, True, comments) + + try: + req = vc_type.get_src_requirement(location, dist.project_name) + except RemoteNotFoundError: + req = dist.as_requirement() + comments = [ + '# Editable {} install with no remote ({})'.format( + vc_type.__name__, req, + ) + ] + return (location, True, comments) + + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + vc_type.name, + ) + return (None, True, []) + + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + else: + if req is not None: + return (req, True, []) + + logger.warning( + 'Could not determine repository location of %s', location + ) + comments = ['## !! Could not determine repository location'] + + return (None, False, comments) + + +class FrozenRequirement(object): + def __init__(self, name, req, editable, comments=()): + # type: (str, Union[str, Requirement], bool, Iterable[str]) -> None + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + @classmethod + def from_dist(cls, dist): + # type: (Distribution) -> FrozenRequirement + req, editable, comments = get_requirement_info(dist) + if req is None: + req = dist.as_requirement() + + return cls(dist.project_name, req, editable, comments=comments) + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/prepare.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/prepare.py new file mode 100755 index 0000000..4f31dd5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/operations/prepare.py @@ -0,0 +1,413 @@ +"""Prepares a distribution for installation +""" + +import logging +import os + +from pip._vendor import pkg_resources, requests + +from pip._internal.build_env import BuildEnvironment +from pip._internal.download import ( + is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, +) +from pip._internal.exceptions import ( + DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, + PreviousBuildDirError, VcsHashUnsupported, +) +from pip._internal.utils.compat import expanduser +from pip._internal.utils.hashes import MissingHashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import display_path, normalize_path +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from pip._internal.index import PackageFinder # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + from pip._internal.req.req_tracker import RequirementTracker # noqa: F401 + +logger = logging.getLogger(__name__) + + +def make_abstract_dist(req): + # type: (InstallRequirement) -> DistAbstraction + """Factory to make an abstract dist object. + + Preconditions: Either an editable req with a source_dir, or satisfied_by or + a wheel link, or a non-editable req with a source_dir. + + :return: A concrete DistAbstraction. + """ + if req.editable: + return IsSDist(req) + elif req.link and req.link.is_wheel: + return IsWheel(req) + else: + return IsSDist(req) + + +class DistAbstraction(object): + """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. + + The requirements for anything installable are as follows: + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + - we must be able to generate a list of run-time dependencies + without installing any additional packages (or we would + have to either burn time by doing temporary isolated installs + or alternatively violate pips 'don't start installing unless + all requirements are available' rule - neither of which are + desirable). + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + - we must be able to create a Distribution object exposing the + above metadata. + """ + + def __init__(self, req): + # type: (InstallRequirement) -> None + self.req = req # type: InstallRequirement + + def dist(self): + # type: () -> Any + """Return a setuptools Dist object.""" + raise NotImplementedError + + def prep_for_dist(self, finder, build_isolation): + # type: (PackageFinder, bool) -> Any + """Ensure that we can get a Dist for this requirement.""" + raise NotImplementedError + + +class IsWheel(DistAbstraction): + + def dist(self): + # type: () -> pkg_resources.Distribution + return list(pkg_resources.find_distributions( + self.req.source_dir))[0] + + def prep_for_dist(self, finder, build_isolation): + # type: (PackageFinder, bool) -> Any + # FIXME:https://github.com/pypa/pip/issues/1112 + pass + + +class IsSDist(DistAbstraction): + + def dist(self): + return self.req.get_dist() + + def prep_for_dist(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None + # Prepare for building. We need to: + # 1. Load pyproject.toml (if it exists) + # 2. Set up the build environment + + self.req.load_pyproject_toml() + should_isolate = self.req.use_pep517 and build_isolation + + def _raise_conflicts(conflicting_with, conflicting_reqs): + raise InstallationError( + "Some build dependencies for %s conflict with %s: %s." % ( + self.req, conflicting_with, ', '.join( + '%s is incompatible with %s' % (installed, wanted) + for installed, wanted in sorted(conflicting)))) + + if should_isolate: + # Isolate in a BuildEnvironment and install the build-time + # requirements. + self.req.build_env = BuildEnvironment() + self.req.build_env.install_requirements( + finder, self.req.pyproject_requires, 'overlay', + "Installing build dependencies" + ) + conflicting, missing = self.req.build_env.check_requirements( + self.req.requirements_to_check + ) + if conflicting: + _raise_conflicts("PEP 517/518 supported requirements", + conflicting) + if missing: + logger.warning( + "Missing build requirements in pyproject.toml for %s.", + self.req, + ) + logger.warning( + "The project does not specify a build backend, and " + "pip cannot fall back to setuptools without %s.", + " and ".join(map(repr, sorted(missing))) + ) + # Install any extra build dependencies that the backend requests. + # This must be done in a second pass, as the pyproject.toml + # dependencies must be installed before we can call the backend. + with self.req.build_env: + # We need to have the env active when calling the hook. + self.req.spin_message = "Getting requirements to build wheel" + reqs = self.req.pep517_backend.get_requires_for_build_wheel() + conflicting, missing = self.req.build_env.check_requirements(reqs) + if conflicting: + _raise_conflicts("the backend dependencies", conflicting) + self.req.build_env.install_requirements( + finder, missing, 'normal', + "Installing backend dependencies" + ) + + self.req.prepare_metadata() + self.req.assert_source_matches_version() + + +class Installed(DistAbstraction): + + def dist(self): + # type: () -> pkg_resources.Distribution + return self.req.satisfied_by + + def prep_for_dist(self, finder, build_isolation): + # type: (PackageFinder, bool) -> Any + pass + + +class RequirementPreparer(object): + """Prepares a Requirement + """ + + def __init__( + self, + build_dir, # type: str + download_dir, # type: Optional[str] + src_dir, # type: str + wheel_download_dir, # type: Optional[str] + progress_bar, # type: str + build_isolation, # type: bool + req_tracker # type: RequirementTracker + ): + # type: (...) -> None + super(RequirementPreparer, self).__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + self.req_tracker = req_tracker + + # Where still packed archives should be written to. If None, they are + # not saved, and are deleted immediately after unpacking. + self.download_dir = download_dir + + # Where still-packed .whl files should be written to. If None, they are + # written to the download_dir parameter. Separate to download_dir to + # permit only keeping wheel archives for pip wheel. + if wheel_download_dir: + wheel_download_dir = normalize_path(wheel_download_dir) + self.wheel_download_dir = wheel_download_dir + + # NOTE + # download_dir and wheel_download_dir overlap semantically and may + # be combined if we're willing to have non-wheel archives present in + # the wheelhouse output by 'pip wheel'. + + self.progress_bar = progress_bar + + # Is build isolation allowed? + self.build_isolation = build_isolation + + @property + def _download_should_save(self): + # type: () -> bool + # TODO: Modify to reduce indentation needed + if self.download_dir: + self.download_dir = expanduser(self.download_dir) + if os.path.exists(self.download_dir): + return True + else: + logger.critical('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '%s'" + % display_path(self.download_dir)) + return False + + def prepare_linked_requirement( + self, + req, # type: InstallRequirement + session, # type: PipSession + finder, # type: PackageFinder + upgrade_allowed, # type: bool + require_hashes # type: bool + ): + # type: (...) -> DistAbstraction + """Prepare a requirement that would be obtained from req.link + """ + # TODO: Breakup into smaller functions + if req.link and req.link.scheme == 'file': + path = url_to_path(req.link.url) + logger.info('Processing %s', display_path(path)) + else: + logger.info('Collecting %s', req) + + with indent_log(): + # @@ if filesystem packages are not marked + # editable in a req, a non deterministic error + # occurs when the script attempts to unpack the + # build directory + req.ensure_has_source_dir(self.build_dir) + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '%s' due to a" + " pre-existing build directory (%s). This is " + "likely due to a previous installation that failed" + ". pip is being responsible and not assuming it " + "can delete this. Please delete it and try again." + % (req, req.source_dir) + ) + req.populate_link(finder, upgrade_allowed, require_hashes) + + # We can't hit this spot and have populate_link return None. + # req.satisfied_by is None here (because we're + # guarded) and upgrade has no impact except when satisfied_by + # is not None. + # Then inside find_requirement existing_applicable -> False + # If no new versions are found, DistributionNotFound is raised, + # otherwise a result is guaranteed. + assert req.link + link = req.link + + # Now that we have the real link, we can tell what kind of + # requirements we have and raise some more informative errors + # than otherwise. (For example, we can raise VcsHashUnsupported + # for a VCS URL rather than HashMissing.) + if require_hashes: + # We could check these first 2 conditions inside + # unpack_url and save repetition of conditions, but then + # we would report less-useful error messages for + # unhashable requirements, complaining that there's no + # hash provided. + if is_vcs_url(link): + raise VcsHashUnsupported() + elif is_file_url(link) and is_dir_url(link): + raise DirectoryUrlHashUnsupported() + if not req.original_link and not req.is_pinned: + # Unpinned packages are asking for trouble when a new + # version is uploaded. This isn't a security check, but + # it saves users a surprising hash mismatch in the + # future. + # + # file:/// URLs aren't pinnable, so don't complain + # about them not being pinned. + raise HashUnpinned() + + hashes = req.hashes(trust_internet=not require_hashes) + if require_hashes and not hashes: + # Known-good hashes are missing for this requirement, so + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + hashes = MissingHashes() + + try: + download_dir = self.download_dir + # We always delete unpacked sdists after pip ran. + autodelete_unpacked = True + if req.link.is_wheel and self.wheel_download_dir: + # when doing 'pip wheel` we download wheels to a + # dedicated dir. + download_dir = self.wheel_download_dir + if req.link.is_wheel: + if download_dir: + # When downloading, we only unpack wheels to get + # metadata. + autodelete_unpacked = True + else: + # When installing a wheel, we use the unpacked + # wheel. + autodelete_unpacked = False + unpack_url( + req.link, req.source_dir, + download_dir, autodelete_unpacked, + session=session, hashes=hashes, + progress_bar=self.progress_bar + ) + except requests.HTTPError as exc: + logger.critical( + 'Could not install requirement %s because of error %s', + req, + exc, + ) + raise InstallationError( + 'Could not install requirement %s because of HTTP ' + 'error %s for URL %s' % + (req, exc, req.link) + ) + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + if self._download_should_save: + # Make a .zip of the source_dir we already created. + if req.link.scheme in vcs.all_schemes: + req.archive(self.download_dir) + return abstract_dist + + def prepare_editable_requirement( + self, + req, # type: InstallRequirement + require_hashes, # type: bool + use_user_site, # type: bool + finder # type: PackageFinder + ): + # type: (...) -> DistAbstraction + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if require_hashes: + raise InstallationError( + 'The editable requirement %s cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.' % req + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable(not self._download_should_save) + + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + + if self._download_should_save: + req.archive(self.download_dir) + req.check_if_exists(use_user_site) + + return abstract_dist + + def prepare_installed_requirement(self, req, require_hashes, skip_reason): + # type: (InstallRequirement, bool, Optional[str]) -> DistAbstraction + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to %r" % (req.satisfied_by,) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + abstract_dist = Installed(req) + + return abstract_dist diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pep425tags.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pep425tags.py new file mode 100755 index 0000000..1e782d1 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pep425tags.py @@ -0,0 +1,381 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" +from __future__ import absolute_import + +import distutils.util +import logging +import platform +import re +import sys +import sysconfig +import warnings +from collections import OrderedDict + +import pip._internal.utils.glibc +from pip._internal.utils.compat import get_extension_suffixes +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Tuple, Callable, List, Optional, Union, Dict + ) + + Pep425Tag = Tuple[str, str, str] + +logger = logging.getLogger(__name__) + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def get_config_var(var): + # type: (str) -> Optional[str] + try: + return sysconfig.get_config_var(var) + except IOError as e: # Issue #1074 + warnings.warn("{}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + # type: () -> str + """Return abbreviated implementation name.""" + if hasattr(sys, 'pypy_version_info'): + pyimpl = 'pp' + elif sys.platform.startswith('java'): + pyimpl = 'jy' + elif sys.platform == 'cli': + pyimpl = 'ip' + else: + pyimpl = 'cp' + return pyimpl + + +def get_impl_ver(): + # type: () -> str + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + # type: () -> Tuple[int, ...] + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + # attrs exist only on pypy + return (sys.version_info[0], + sys.pypy_version_info.major, # type: ignore + sys.pypy_version_info.minor) # type: ignore + else: + return sys.version_info[0], sys.version_info[1] + + +def get_impl_tag(): + # type: () -> str + """ + Returns the Tag for this specific implementation. + """ + return "{}{}".format(get_abbr_impl(), get_impl_ver()) + + +def get_flag(var, fallback, expected=True, warn=True): + # type: (str, Callable[..., bool], Union[bool, int], bool) -> bool + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + logger.debug("Config variable '%s' is unset, Python ABI tag may " + "be incorrect", var) + return fallback() + return val == expected + + +def get_abi_tag(): + # type: () -> Optional[str] + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def _is_running_32bit(): + # type: () -> bool + return sys.maxsize == 2147483647 + + +def get_platform(): + # type: () -> str + """Return our platform name 'win32', 'linux_x86_64'""" + if sys.platform == 'darwin': + # distutils.util.get_platform() returns the release based on the value + # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may + # be significantly older than the user's current machine. + release, _, machine = platform.mac_ver() + split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + + return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) + + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # type: () -> bool + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return pip._internal.utils.glibc.have_compatible_glibc(2, 5) + + +def is_manylinux2010_compatible(): + # type: () -> bool + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux2010_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 6 uses glibc 2.12. + return pip._internal.utils.glibc.have_compatible_glibc(2, 12) + + +def get_darwin_arches(major, minor, machine): + # type: (int, int, str) -> List[str] + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an macOS machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # type: (int, int, str) -> bool + # Looking at the application support for macOS versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) # type: Dict[str, Tuple[str, ...]] + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches + + +def get_all_minor_versions_as_strings(version_info): + # type: (Tuple[int, ...]) -> List[str] + versions = [] + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + return versions + + +def get_supported( + versions=None, # type: Optional[List[str]] + noarch=False, # type: bool + platform=None, # type: Optional[str] + impl=None, # type: Optional[str] + abi=None # type: Optional[str] +): + # type: (...) -> List[Pep425Tag] + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + :param platform: specify the exact platform you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abi: specify the exact abi you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + version_info = get_impl_version_info() + versions = get_all_minor_versions_as_strings(version_info) + + impl = impl or get_abbr_impl() + + abis = [] # type: List[str] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + for suffix in get_extension_suffixes(): + if suffix.startswith('.abi'): + abi3s.add(suffix.split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + if not noarch: + arch = platform or get_platform() + arch_prefix, arch_sep, arch_suffix = arch.partition('_') + if arch.startswith('macosx'): + # support macosx-10.6-intel on macosx-10.9-x86_64 + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + tpl = '{}_{}_%i_%s'.format(name, major) + arches = [] + for m in reversed(range(int(minor) + 1)): + for a in get_darwin_arches(int(major), m, actual_arch): + arches.append(tpl % (m, a)) + else: + # arch pattern didn't match (?!) + arches = [arch] + elif arch_prefix == 'manylinux2010': + # manylinux1 wheels run on most manylinux2010 systems with the + # exception of wheels depending on ncurses. PEP 571 states + # manylinux1 wheels should be considered manylinux2010 wheels: + # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels + arches = [arch, 'manylinux1' + arch_sep + arch_suffix] + elif platform is None: + arches = [] + if is_manylinux2010_compatible(): + arches.append('manylinux2010' + arch_sep + arch_suffix) + if is_manylinux1_compatible(): + arches.append('manylinux1' + arch_sep + arch_suffix) + arches.append(arch) + else: + arches = [arch] + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for abi in abi3s: # empty set if not Python 3 + for arch in arches: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported + + +implementation_tag = get_impl_tag() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pyproject.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pyproject.py new file mode 100755 index 0000000..8d739a6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/pyproject.py @@ -0,0 +1,171 @@ +from __future__ import absolute_import + +import io +import os +import sys + +from pip._vendor import pytoml, six + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Tuple, Optional, List # noqa: F401 + + +def _is_list_of_str(obj): + # type: (Any) -> bool + return ( + isinstance(obj, list) and + all(isinstance(item, six.string_types) for item in obj) + ) + + +def make_pyproject_path(setup_py_dir): + # type: (str) -> str + path = os.path.join(setup_py_dir, 'pyproject.toml') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(path, six.text_type): + path = path.encode(sys.getfilesystemencoding()) + + return path + + +def load_pyproject_toml( + use_pep517, # type: Optional[bool] + pyproject_toml, # type: str + setup_py, # type: str + req_name # type: str +): + # type: (...) -> Optional[Tuple[List[str], str, List[str]]] + """Load the pyproject.toml file. + + Parameters: + use_pep517 - Has the user requested PEP 517 processing? None + means the user hasn't explicitly specified. + pyproject_toml - Location of the project's pyproject.toml file + setup_py - Location of the project's setup.py file + req_name - The name of the requirement we're processing (for + error reporting) + + Returns: + None if we should use the legacy code path, otherwise a tuple + ( + requirements from pyproject.toml, + name of PEP 517 backend, + requirements we should check are installed after setting + up the build environment + ) + """ + has_pyproject = os.path.isfile(pyproject_toml) + has_setup = os.path.isfile(setup_py) + + if has_pyproject: + with io.open(pyproject_toml, encoding="utf-8") as f: + pp_toml = pytoml.load(f) + build_system = pp_toml.get("build-system") + else: + build_system = None + + # The following cases must use PEP 517 + # We check for use_pep517 being non-None and falsey because that means + # the user explicitly requested --no-use-pep517. The value 0 as + # opposed to False can occur when the value is provided via an + # environment variable or config file option (due to the quirk of + # strtobool() returning an integer in pip's configuration code). + if has_pyproject and not has_setup: + if use_pep517 is not None and not use_pep517: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project does not have a setup.py" + ) + use_pep517 = True + elif build_system and "build-backend" in build_system: + if use_pep517 is not None and not use_pep517: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project specifies a build backend of {} " + "in pyproject.toml".format( + build_system["build-backend"] + ) + ) + use_pep517 = True + + # If we haven't worked out whether to use PEP 517 yet, + # and the user hasn't explicitly stated a preference, + # we do so if the project has a pyproject.toml file. + elif use_pep517 is None: + use_pep517 = has_pyproject + + # At this point, we know whether we're going to use PEP 517. + assert use_pep517 is not None + + # If we're using the legacy code path, there is nothing further + # for us to do here. + if not use_pep517: + return None + + if build_system is None: + # Either the user has a pyproject.toml with no build-system + # section, or the user has no pyproject.toml, but has opted in + # explicitly via --use-pep517. + # In the absence of any explicit backend specification, we + # assume the setuptools backend that most closely emulates the + # traditional direct setup.py execution, and require wheel and + # a version of setuptools that supports that backend. + + build_system = { + "requires": ["setuptools>=40.8.0", "wheel"], + "build-backend": "setuptools.build_meta:__legacy__", + } + + # If we're using PEP 517, we have build system information (either + # from pyproject.toml, or defaulted by the code above). + # Note that at this point, we do not know if the user has actually + # specified a backend, though. + assert build_system is not None + + # Ensure that the build-system section in pyproject.toml conforms + # to PEP 518. + error_template = ( + "{package} has a pyproject.toml file that does not comply " + "with PEP 518: {reason}" + ) + + # Specifying the build-system table but not the requires key is invalid + if "requires" not in build_system: + raise InstallationError( + error_template.format(package=req_name, reason=( + "it has a 'build-system' table but not " + "'build-system.requires' which is mandatory in the table" + )) + ) + + # Error out if requires is not a list of strings + requires = build_system["requires"] + if not _is_list_of_str(requires): + raise InstallationError(error_template.format( + package=req_name, + reason="'build-system.requires' is not a list of strings.", + )) + + backend = build_system.get("build-backend") + check = [] # type: List[str] + if backend is None: + # If the user didn't specify a backend, we assume they want to use + # the setuptools backend. But we can't be sure they have included + # a version of setuptools which supplies the backend, or wheel + # (which is needed by the backend) in their requirements. So we + # make a note to check that those requirements are present once + # we have set up the environment. + # This is quite a lot of work to check for a very specific case. But + # the problem is, that case is potentially quite common - projects that + # adopted PEP 518 early for the ability to specify requirements to + # execute setup.py, but never considered needing to mention the build + # tools themselves. The original PEP 518 code had a similar check (but + # implemented in a different way). + backend = "setuptools.build_meta:__legacy__" + check = ["setuptools>=40.8.0", "wheel"] + + return (requires, backend, check) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/__init__.py new file mode 100755 index 0000000..5e4eb92 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/__init__.py @@ -0,0 +1,77 @@ +from __future__ import absolute_import + +import logging + +from .req_install import InstallRequirement +from .req_set import RequirementSet +from .req_file import parse_requirements +from pip._internal.utils.logging import indent_log +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Sequence # noqa: F401 + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +def install_given_reqs( + to_install, # type: List[InstallRequirement] + install_options, # type: List[str] + global_options=(), # type: Sequence[str] + *args, **kwargs +): + # type: (...) -> List[InstallRequirement] + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join([req.name for req in to_install]), + ) + + with indent_log(): + for requirement in to_install: + if requirement.conflicts_with: + logger.info( + 'Found existing installation: %s', + requirement.conflicts_with, + ) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + try: + requirement.install( + install_options, + global_options, + *args, + **kwargs + ) + except Exception: + should_rollback = ( + requirement.conflicts_with and + not requirement.install_succeeded + ) + # if install did not succeed, rollback previous uninstall + if should_rollback: + uninstalled_pathset.rollback() + raise + else: + should_commit = ( + requirement.conflicts_with and + requirement.install_succeeded + ) + if should_commit: + uninstalled_pathset.commit() + requirement.remove_temporary_source() + + return to_install diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/constructors.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/constructors.py new file mode 100755 index 0000000..1eed1dd --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/constructors.py @@ -0,0 +1,339 @@ +"""Backing implementation for InstallRequirement's various constructors + +The idea here is that these formed a major chunk of InstallRequirement's size +so, moving them and support code dedicated to them outside of that class +helps creates for better understandability for the rest of the code. + +These are meant to be used elsewhere within pip to create instances of +InstallRequirement. +""" + +import logging +import os +import re + +from pip._vendor.packaging.markers import Marker +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement +from pip._vendor.packaging.specifiers import Specifier +from pip._vendor.pkg_resources import RequirementParseError, parse_requirements + +from pip._internal.download import ( + is_archive_file, is_url, path_to_url, url_to_path, +) +from pip._internal.exceptions import InstallationError +from pip._internal.models.index import PyPI, TestPyPI +from pip._internal.models.link import Link +from pip._internal.pyproject import make_pyproject_path +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.misc import is_installable_dir +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.vcs import vcs +from pip._internal.wheel import Wheel + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Optional, Tuple, Set, Any, Union, Text, Dict, + ) + from pip._internal.cache import WheelCache # noqa: F401 + + +__all__ = [ + "install_req_from_editable", "install_req_from_line", + "parse_editable" +] + +logger = logging.getLogger(__name__) +operators = Specifier._operators.keys() + + +def _strip_extras(path): + # type: (str) -> Tuple[str, Optional[str]] + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +def parse_editable(editable_req): + # type: (str) -> Tuple[Optional[str], str, Optional[Set[str]]] + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + msg = ( + 'File "setup.py" not found. Directory cannot be installed ' + 'in editable mode: {}'.format(os.path.abspath(url_no_extras)) + ) + pyproject_path = make_pyproject_path(url_no_extras) + if os.path.isfile(pyproject_path): + msg += ( + '\n(A "pyproject.toml" file was found, but editable ' + 'mode currently requires a setup.py based build.)' + ) + raise InstallationError(msg) + + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, None + + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + break + + if '+' not in url: + raise InstallationError( + '%s should either be a path to a local project or a VCS url ' + 'beginning with svn+, git+, hg+, or bzr+' % + editable_req + ) + + vc_type = url.split('+', 1)[0].lower() + + if not vcs.get_backend(vc_type): + error_message = 'For --editable=%s only ' % editable_req + \ + ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ + ' is currently supported' + raise InstallationError(error_message) + + package_name = Link(url).egg_fragment + if not package_name: + raise InstallationError( + "Could not detect requirement name for '%s', please specify one " + "with #egg=your_package_name" % editable_req + ) + return package_name, url, None + + +def deduce_helpful_msg(req): + # type: (str) -> str + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " It does exist." + # Try to parse and check if it is a requirements file. + try: + with open(req, 'r') as fp: + # parse first line only + next(parse_requirements(fp.read())) + msg += " The argument you provided " + \ + "(%s) appears to be a" % (req) + \ + " requirements file. If that is the" + \ + " case, use the '-r' flag to install" + \ + " the packages specified within it." + except RequirementParseError: + logger.debug("Cannot parse '%s' as requirements \ + file" % (req), exc_info=True) + else: + msg += " File '%s' does not exist." % (req) + return msg + + +# ---- The actual constructors follow ---- + + +def install_req_from_editable( + editable_req, # type: str + comes_from=None, # type: Optional[str] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + wheel_cache=None, # type: Optional[WheelCache] + constraint=False # type: bool +): + # type: (...) -> InstallRequirement + name, url, extras_override = parse_editable(editable_req) + if url.startswith('file:'): + source_dir = url_to_path(url) + else: + source_dir = None + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % name) + else: + req = None + return InstallRequirement( + req, comes_from, source_dir=source_dir, + editable=True, + link=Link(url), + constraint=constraint, + use_pep517=use_pep517, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + extras=extras_override or (), + ) + + +def install_req_from_line( + name, # type: str + comes_from=None, # type: Optional[Union[str, InstallRequirement]] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + wheel_cache=None, # type: Optional[WheelCache] + constraint=False # type: bool +): + # type: (...) -> InstallRequirement + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers_as_string = name.split(marker_sep, 1) + markers_as_string = markers_as_string.strip() + if not markers_as_string: + markers = None + else: + markers = Marker(markers_as_string) + else: + markers = None + name = name.strip() + req_as_string = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras_as_string = None + + if is_url(name): + link = Link(name) + else: + p, extras_as_string = _strip_extras(path) + looks_like_dir = os.path.isdir(p) and ( + os.path.sep in name or + (os.path.altsep is not None and os.path.altsep in name) or + name.startswith('.') + ) + if looks_like_dir: + if not is_installable_dir(p): + raise InstallationError( + "Directory %r is not installable. Neither 'setup.py' " + "nor 'pyproject.toml' found." % name + ) + link = Link(path_to_url(p)) + elif is_archive_file(p): + if not os.path.isfile(p): + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + link = Link(path_to_url(p)) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req_as_string = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req_as_string = link.egg_fragment + + # a requirement specifier + else: + req_as_string = name + + if extras_as_string: + extras = Requirement("placeholder" + extras_as_string.lower()).extras + else: + extras = () + if req_as_string is not None: + try: + req = Requirement(req_as_string) + except InvalidRequirement: + if os.path.sep in req_as_string: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req_as_string) + elif ('=' in req_as_string and + not any(op in req_as_string for op in operators)): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = "" + raise InstallationError( + "Invalid requirement: '%s'\n%s" % (req_as_string, add_msg) + ) + else: + req = None + + return InstallRequirement( + req, comes_from, link=link, markers=markers, + use_pep517=use_pep517, isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + constraint=constraint, + extras=extras, + ) + + +def install_req_from_req_string( + req_string, # type: str + comes_from=None, # type: Optional[InstallRequirement] + isolated=False, # type: bool + wheel_cache=None, # type: Optional[WheelCache] + use_pep517=None # type: Optional[bool] +): + # type: (...) -> InstallRequirement + try: + req = Requirement(req_string) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % req) + + domains_not_allowed = [ + PyPI.file_storage_domain, + TestPyPI.file_storage_domain, + ] + if req.url and comes_from.link.netloc in domains_not_allowed: + # Explicitly disallow pypi packages that depend on external urls + raise InstallationError( + "Packages installed from PyPI cannot depend on packages " + "which are not also hosted on PyPI.\n" + "%s depends on %s " % (comes_from.name, req) + ) + + return InstallRequirement( + req, comes_from, isolated=isolated, wheel_cache=wheel_cache, + use_pep517=use_pep517 + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_file.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_file.py new file mode 100755 index 0000000..726f2f6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_file.py @@ -0,0 +1,382 @@ +""" +Requirements file parsing +""" + +from __future__ import absolute_import + +import optparse +import os +import re +import shlex +import sys + +from pip._vendor.six.moves import filterfalse +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.cli import cmdoptions +from pip._internal.download import get_file_content +from pip._internal.exceptions import RequirementsFileParseError +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Iterator, Tuple, Optional, List, Callable, Text + ) + from pip._internal.req import InstallRequirement # noqa: F401 + from pip._internal.cache import WheelCache # noqa: F401 + from pip._internal.index import PackageFinder # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + + ReqFileLines = Iterator[Tuple[int, Text]] + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s)+#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') + +SUPPORTED_OPTIONS = [ + cmdoptions.constraints, + cmdoptions.editable, + cmdoptions.requirements, + cmdoptions.no_index, + cmdoptions.index_url, + cmdoptions.find_links, + cmdoptions.extra_index_url, + cmdoptions.always_unzip, + cmdoptions.no_binary, + cmdoptions.only_binary, + cmdoptions.pre, + cmdoptions.trusted_host, + cmdoptions.require_hashes, +] # type: List[Callable[..., optparse.Option]] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] # type: List[Callable[..., optparse.Option]] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] + + +def parse_requirements( + filename, # type: str + finder=None, # type: Optional[PackageFinder] + comes_from=None, # type: Optional[str] + options=None, # type: Optional[optparse.Values] + session=None, # type: Optional[PipSession] + constraint=False, # type: bool + wheel_cache=None, # type: Optional[WheelCache] + use_pep517=None # type: Optional[bool] +): + # type: (...) -> Iterator[InstallRequirement] + """Parse a requirements file and yield InstallRequirement instances. + + :param filename: Path or url of requirements file. + :param finder: Instance of pip.index.PackageFinder. + :param comes_from: Origin description of requirements. + :param options: cli options. + :param session: Instance of pip.download.PipSession. + :param constraint: If true, parsing a constraint file rather than + requirements file. + :param wheel_cache: Instance of pip.wheel.WheelCache + :param use_pep517: Value of the --use-pep517 option. + """ + if session is None: + raise TypeError( + "parse_requirements() missing 1 required keyword argument: " + "'session'" + ) + + _, content = get_file_content( + filename, comes_from=comes_from, session=session + ) + + lines_enum = preprocess(content, options) + + for line_number, line in lines_enum: + req_iter = process_line(line, filename, line_number, finder, + comes_from, options, session, wheel_cache, + use_pep517=use_pep517, constraint=constraint) + for req in req_iter: + yield req + + +def preprocess(content, options): + # type: (Text, Optional[optparse.Values]) -> ReqFileLines + """Split, filter, and join lines, and return a line iterator + + :param content: the content of the requirements file + :param options: cli options + """ + lines_enum = enumerate(content.splitlines(), start=1) # type: ReqFileLines + lines_enum = join_lines(lines_enum) + lines_enum = ignore_comments(lines_enum) + lines_enum = skip_regex(lines_enum, options) + lines_enum = expand_env_variables(lines_enum) + return lines_enum + + +def process_line( + line, # type: Text + filename, # type: str + line_number, # type: int + finder=None, # type: Optional[PackageFinder] + comes_from=None, # type: Optional[str] + options=None, # type: Optional[optparse.Values] + session=None, # type: Optional[PipSession] + wheel_cache=None, # type: Optional[WheelCache] + use_pep517=None, # type: Optional[bool] + constraint=False # type: bool +): + # type: (...) -> Iterator[InstallRequirement] + """Process a single requirements line; This can result in creating/yielding + requirements, or updating the finder. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + + :param constraint: If True, parsing a constraints file. + :param options: OptionParser options that we may update + """ + parser = build_parser(line) + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + defaults.format_control = finder.format_control + args_str, options_str = break_args_options(line) + # Prior to 2.7.3, shlex cannot deal with unicode entries + if sys.version_info < (2, 7, 3): + # https://github.com/python/mypy/issues/1174 + options_str = options_str.encode('utf8') # type: ignore + # https://github.com/python/mypy/issues/1174 + opts, _ = parser.parse_args( + shlex.split(options_str), defaults) # type: ignore + + # preserve for the nested code path + line_comes_from = '%s %s (line %s)' % ( + '-c' if constraint else '-r', filename, line_number, + ) + + # yield a line requirement + if args_str: + isolated = options.isolated_mode if options else False + if options: + cmdoptions.check_install_build_global(options, opts) + # get the options that apply to requirements + req_options = {} + for dest in SUPPORTED_OPTIONS_REQ_DEST: + if dest in opts.__dict__ and opts.__dict__[dest]: + req_options[dest] = opts.__dict__[dest] + yield install_req_from_line( + args_str, line_comes_from, constraint=constraint, + use_pep517=use_pep517, + isolated=isolated, options=req_options, wheel_cache=wheel_cache + ) + + # yield an editable requirement + elif opts.editables: + isolated = options.isolated_mode if options else False + yield install_req_from_editable( + opts.editables[0], comes_from=line_comes_from, + use_pep517=use_pep517, + constraint=constraint, isolated=isolated, wheel_cache=wheel_cache + ) + + # parse a nested requirements file + elif opts.requirements or opts.constraints: + if opts.requirements: + req_path = opts.requirements[0] + nested_constraint = False + else: + req_path = opts.constraints[0] + nested_constraint = True + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib_parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join(os.path.dirname(filename), req_path) + # TODO: Why not use `comes_from='-r {} (line {})'` here as well? + parsed_reqs = parse_requirements( + req_path, finder, comes_from, options, session, + constraint=nested_constraint, wheel_cache=wheel_cache + ) + for req in parsed_reqs: + yield req + + # percolate hash-checking option upward + elif opts.require_hashes: + options.require_hashes = opts.require_hashes + + # set finder options + elif finder: + if opts.index_url: + finder.index_urls = [opts.index_url] + if opts.no_index is True: + finder.index_urls = [] + if opts.extra_index_urls: + finder.index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + finder.find_links.append(value) + if opts.pre: + finder.allow_all_prereleases = True + if opts.trusted_hosts: + finder.secure_origins.extend( + ("*", host, "*") for host in opts.trusted_hosts) + + +def break_args_options(line): + # type: (Text) -> Tuple[str, Text] + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) # type: ignore + + +def build_parser(line): + # type: (Text) -> optparse.OptionParser + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # add offending line + msg = 'Invalid requirement: %s\n%s' % (line, msg) + raise RequirementsFileParseError(msg) + # NOTE: mypy disallows assigning to a method + # https://github.com/python/mypy/issues/2427 + parser.exit = parser_exit # type: ignore + + return parser + + +def join_lines(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] # type: List[Text] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def skip_regex(lines_enum, options): + # type: (ReqFileLines, Optional[optparse.Values]) -> ReqFileLines + """ + Skip lines that match '--skip-requirements-regex' pattern + + Note: the regex pattern is only built once + """ + skip_regex = options.skip_requirements_regex if options else None + if skip_regex: + pattern = re.compile(skip_regex) + lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) + return lines_enum + + +def expand_env_variables(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discusssion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_install.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_install.py new file mode 100755 index 0000000..a4834b0 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_install.py @@ -0,0 +1,1021 @@ +from __future__ import absolute_import + +import logging +import os +import shutil +import sys +import sysconfig +import zipfile +from distutils.util import change_root + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.requirements import Requirement +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import Version +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.pep517.wrappers import Pep517HookCaller + +from pip._internal import wheel +from pip._internal.build_env import NoOpBuildEnvironment +from pip._internal.exceptions import InstallationError +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, +) +from pip._internal.models.link import Link +from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.compat import native_str +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + _make_build_dir, ask_path_exists, backup_dir, call_subprocess, + display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, + get_installed_version, redact_password_from_url, rmtree, +) +from pip._internal.utils.packaging import get_metadata +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs +from pip._internal.wheel import move_wheel_files + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Optional, Iterable, List, Union, Any, Text, Sequence, Dict + ) + from pip._internal.build_env import BuildEnvironment # noqa: F401 + from pip._internal.cache import WheelCache # noqa: F401 + from pip._internal.index import PackageFinder # noqa: F401 + from pip._vendor.pkg_resources import Distribution # noqa: F401 + from pip._vendor.packaging.specifiers import SpecifierSet # noqa: F401 + from pip._vendor.packaging.markers import Marker # noqa: F401 + + +logger = logging.getLogger(__name__) + + +class InstallRequirement(object): + """ + Represents something that may be installed later on, may have information + about where to fetch the relavant requirement and also contains logic for + installing the said requirement. + """ + + def __init__( + self, + req, # type: Optional[Requirement] + comes_from, # type: Optional[Union[str, InstallRequirement]] + source_dir=None, # type: Optional[str] + editable=False, # type: bool + link=None, # type: Optional[Link] + update=True, # type: bool + markers=None, # type: Optional[Marker] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + wheel_cache=None, # type: Optional[WheelCache] + constraint=False, # type: bool + extras=() # type: Iterable[str] + ): + # type: (...) -> None + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + if source_dir is not None: + self.source_dir = os.path.normpath(os.path.abspath(source_dir)) + else: + self.source_dir = None + self.editable = editable + + self._wheel_cache = wheel_cache + if link is None and req and req.url: + # PEP 508 URL requirement + link = Link(req.url) + self.link = self.original_link = link + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is None and req: + markers = req.marker + self.markers = markers + + self._egg_info_path = None # type: Optional[str] + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None + # This hold the pkg_resources.Distribution object if this requirement + # conflicts with another installed distribution: + self.conflicts_with = None + # Temporary build location + self._temp_build_dir = TempDirectory(kind="req-build") + # Used to store the global directory where the _temp_build_dir should + # have been created. Cf _correct_build_location method. + self._ideal_build_dir = None # type: Optional[str] + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None # type: Optional[bool] + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled_pathset = None + self.options = options if options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + self.is_direct = False + + self.isolated = isolated + self.build_env = NoOpBuildEnvironment() # type: BuildEnvironment + + # For PEP 517, the directory where we request the project metadata + # gets stored. We need this to pass to build_wheel, so the backend + # can ensure that the wheel matches the metadata (see the PEP for + # details). + self.metadata_directory = None # type: Optional[str] + + # The static build requirements (from pyproject.toml) + self.pyproject_requires = None # type: Optional[List[str]] + + # Build requirements that we will check are available + self.requirements_to_check = [] # type: List[str] + + # The PEP 517 backend we should use to build the project + self.pep517_backend = None # type: Optional[Pep517HookCaller] + + # Are we using PEP 517 for this requirement? + # After pyproject.toml has been loaded, the only valid values are True + # and False. Before loading, None is valid (meaning "use the default"). + # Setting an explicit value before loading pyproject.toml is supported, + # but after loading this flag should be treated as read only. + self.use_pep517 = use_pep517 + + def __str__(self): + if self.req: + s = str(self.req) + if self.link: + s += ' from %s' % redact_password_from_url(self.link.url) + elif self.link: + s = redact_password_from_url(self.link.url) + else: + s = '' + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def __repr__(self): + return '<%s object: %s editable=%r>' % ( + self.__class__.__name__, str(self), self.editable) + + def populate_link(self, finder, upgrade, require_hashes): + # type: (PackageFinder, bool, bool) -> None + """Ensure that if a link can be found for this, that it is found. + + Note that self.link may still be None - if Upgrade is False and the + requirement is already installed. + + If require_hashes is True, don't use the wheel cache, because cached + wheels, always built locally, have different hashes than the files + downloaded from the index server and thus throw false hash mismatches. + Furthermore, cached wheels at present have undeterministic contents due + to file modification times. + """ + if self.link is None: + self.link = finder.find_requirement(self, upgrade) + if self._wheel_cache is not None and not require_hashes: + old_link = self.link + self.link = self._wheel_cache.get(self.link, self.name) + if old_link != self.link: + logger.debug('Using cached wheel link: %s', self.link) + + # Things that are valid for all kinds of requirements? + @property + def name(self): + # type: () -> Optional[str] + if self.req is None: + return None + return native_str(pkg_resources.safe_name(self.req.name)) + + @property + def specifier(self): + # type: () -> SpecifierSet + return self.req.specifier + + @property + def is_pinned(self): + # type: () -> bool + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + @property + def installed_version(self): + return get_installed_version(self.name) + + def match_markers(self, extras_requested=None): + # type: (Optional[Iterable[str]]) -> bool + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + @property + def has_hash_options(self): + # type: () -> bool + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.options.get('hashes', {})) + + def hashes(self, trust_internet=True): + # type: (bool) -> Hashes + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.options.get('hashes', {}).copy() + link = self.link if trust_internet else self.original_link + if link and link.hash: + good_hashes.setdefault(link.hash_name, []).append(link.hash) + return Hashes(good_hashes) + + def from_path(self): + # type: () -> Optional[str] + """Format a nice indicator to show where this "comes from" + """ + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir): + # type: (str) -> Optional[str] + assert build_dir is not None + if self._temp_build_dir.path is not None: + return self._temp_build_dir.path + if self.req is None: + # for requirement via a path to a directory: the name of the + # package is not available yet so we create a temp directory + # Once run_egg_info will have run, we'll be able + # to fix it via _correct_build_location + # Some systems have /tmp as a symlink which confuses custom + # builds (such as numpy). Thus, we ensure that the real path + # is returned. + self._temp_build_dir.create() + self._ideal_build_dir = build_dir + + return self._temp_build_dir.path + if self.editable: + name = self.name.lower() + else: + name = self.name + # FIXME: Is there a better place to create the build_dir? (hg and bzr + # need this) + if not os.path.exists(build_dir): + logger.debug('Creating directory %s', build_dir) + _make_build_dir(build_dir) + return os.path.join(build_dir, name) + + def _correct_build_location(self): + # type: () -> None + """Move self._temp_build_dir to self._ideal_build_dir/self.req.name + + For some requirements (e.g. a path to a directory), the name of the + package is not available until we run egg_info, so the build_location + will return a temporary directory and store the _ideal_build_dir. + + This is only called by self.run_egg_info to fix the temporary build + directory. + """ + if self.source_dir is not None: + return + assert self.req is not None + assert self._temp_build_dir.path + assert (self._ideal_build_dir is not None and + self._ideal_build_dir.path) # type: ignore + old_location = self._temp_build_dir.path + self._temp_build_dir.path = None + + new_location = self.build_location(self._ideal_build_dir) + if os.path.exists(new_location): + raise InstallationError( + 'A package already exists in %s; please remove it to continue' + % display_path(new_location)) + logger.debug( + 'Moving package %s from %s to new location %s', + self, display_path(old_location), display_path(new_location), + ) + shutil.move(old_location, new_location) + self._temp_build_dir.path = new_location + self._ideal_build_dir = None + self.source_dir = os.path.normpath(os.path.abspath(new_location)) + self._egg_info_path = None + + # Correct the metadata directory, if it exists + if self.metadata_directory: + old_meta = self.metadata_directory + rel = os.path.relpath(old_meta, start=old_location) + new_meta = os.path.join(new_location, rel) + new_meta = os.path.normpath(os.path.abspath(new_meta)) + self.metadata_directory = new_meta + + def remove_temporary_source(self): + # type: () -> None + """Remove the source files from this requirement, if they are marked + for deletion""" + if self.source_dir and os.path.exists( + os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): + logger.debug('Removing source in %s', self.source_dir) + rmtree(self.source_dir) + self.source_dir = None + self._temp_build_dir.cleanup() + self.build_env.cleanup() + + def check_if_exists(self, use_user_site): + # type: (bool) -> bool + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with appropriately. + """ + if self.req is None: + return False + try: + # get_distribution() will resolve the entire list of requirements + # anyway, and we've already determined that we need the requirement + # in question, so strip the marker so that we don't try to + # evaluate it. + no_marker = Requirement(str(self.req)) + no_marker.marker = None + self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) + if self.editable and self.satisfied_by: + self.conflicts_with = self.satisfied_by + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + return True + except pkg_resources.DistributionNotFound: + return False + except pkg_resources.VersionConflict: + existing_dist = pkg_resources.get_distribution( + self.req.name + ) + if use_user_site: + if dist_in_usersite(existing_dist): + self.conflicts_with = existing_dist + elif (running_under_virtualenv() and + dist_in_site_packages(existing_dist)): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to %s in %s" % + (existing_dist.project_name, existing_dist.location) + ) + else: + self.conflicts_with = existing_dist + return True + + # Things valid for wheels + @property + def is_wheel(self): + # type: () -> bool + if not self.link: + return False + return self.link.is_wheel + + def move_wheel_files( + self, + wheeldir, # type: str + root=None, # type: Optional[str] + home=None, # type: Optional[str] + prefix=None, # type: Optional[str] + warn_script_location=True, # type: bool + use_user_site=False, # type: bool + pycompile=True # type: bool + ): + # type: (...) -> None + move_wheel_files( + self.name, self.req, wheeldir, + user=use_user_site, + home=home, + root=root, + prefix=prefix, + pycompile=pycompile, + isolated=self.isolated, + warn_script_location=warn_script_location, + ) + + # Things valid for sdists + @property + def setup_py_dir(self): + # type: () -> str + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py(self): + # type: () -> str + assert self.source_dir, "No source dir for %s" % self + + setup_py = os.path.join(self.setup_py_dir, 'setup.py') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(setup_py, six.text_type): + setup_py = setup_py.encode(sys.getfilesystemencoding()) + + return setup_py + + @property + def pyproject_toml(self): + # type: () -> str + assert self.source_dir, "No source dir for %s" % self + + return make_pyproject_path(self.setup_py_dir) + + def load_pyproject_toml(self): + # type: () -> None + """Load the pyproject.toml file. + + After calling this routine, all of the attributes related to PEP 517 + processing for this requirement have been set. In particular, the + use_pep517 attribute can be used to determine whether we should + follow the PEP 517 or legacy (setup.py) code path. + """ + pep517_data = load_pyproject_toml( + self.use_pep517, + self.pyproject_toml, + self.setup_py, + str(self) + ) + + if pep517_data is None: + self.use_pep517 = False + else: + self.use_pep517 = True + requires, backend, check = pep517_data + self.requirements_to_check = check + self.pyproject_requires = requires + self.pep517_backend = Pep517HookCaller(self.setup_py_dir, backend) + + # Use a custom function to call subprocesses + self.spin_message = "" + + def runner(cmd, cwd=None, extra_environ=None): + with open_spinner(self.spin_message) as spinner: + call_subprocess( + cmd, + cwd=cwd, + extra_environ=extra_environ, + show_stdout=False, + spinner=spinner + ) + self.spin_message = "" + + self.pep517_backend._subprocess_runner = runner + + def prepare_metadata(self): + # type: () -> None + """Ensure that project metadata is available. + + Under PEP 517, call the backend hook to prepare the metadata. + Under legacy processing, call setup.py egg-info. + """ + assert self.source_dir + + with indent_log(): + if self.use_pep517: + self.prepare_pep517_metadata() + else: + self.run_egg_info() + + if not self.req: + if isinstance(parse_version(self.metadata["Version"]), Version): + op = "==" + else: + op = "===" + self.req = Requirement( + "".join([ + self.metadata["Name"], + op, + self.metadata["Version"], + ]) + ) + self._correct_build_location() + else: + metadata_name = canonicalize_name(self.metadata["Name"]) + if canonicalize_name(self.req.name) != metadata_name: + logger.warning( + 'Generating metadata for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + def prepare_pep517_metadata(self): + # type: () -> None + assert self.pep517_backend is not None + + metadata_dir = os.path.join( + self.setup_py_dir, + 'pip-wheel-metadata' + ) + ensure_dir(metadata_dir) + + with self.build_env: + # Note that Pep517HookCaller implements a fallback for + # prepare_metadata_for_build_wheel, so we don't have to + # consider the possibility that this hook doesn't exist. + backend = self.pep517_backend + self.spin_message = "Preparing wheel metadata" + distinfo_dir = backend.prepare_metadata_for_build_wheel( + metadata_dir + ) + + self.metadata_directory = os.path.join(metadata_dir, distinfo_dir) + + def run_egg_info(self): + # type: () -> None + if self.name: + logger.debug( + 'Running setup.py (path:%s) egg_info for package %s', + self.setup_py, self.name, + ) + else: + logger.debug( + 'Running setup.py (path:%s) egg_info for package from %s', + self.setup_py, self.link, + ) + script = SETUPTOOLS_SHIM % self.setup_py + base_cmd = [sys.executable, '-c', script] + if self.isolated: + base_cmd += ["--no-user-cfg"] + egg_info_cmd = base_cmd + ['egg_info'] + # We can't put the .egg-info files at the root, because then the + # source code will be mistaken for an installed egg, causing + # problems + if self.editable: + egg_base_option = [] # type: List[str] + else: + egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') + ensure_dir(egg_info_dir) + egg_base_option = ['--egg-base', 'pip-egg-info'] + with self.build_env: + call_subprocess( + egg_info_cmd + egg_base_option, + cwd=self.setup_py_dir, + show_stdout=False, + command_desc='python setup.py egg_info') + + @property + def egg_info_path(self): + # type: () -> str + if self._egg_info_path is None: + if self.editable: + base = self.source_dir + else: + base = os.path.join(self.setup_py_dir, 'pip-egg-info') + filenames = os.listdir(base) + if self.editable: + filenames = [] + for root, dirs, files in os.walk(base): + for dir in vcs.dirnames: + if dir in dirs: + dirs.remove(dir) + # Iterate over a copy of ``dirs``, since mutating + # a list while iterating over it can cause trouble. + # (See https://github.com/pypa/pip/pull/462.) + for dir in list(dirs): + # Don't search in anything that looks like a virtualenv + # environment + if ( + os.path.lexists( + os.path.join(root, dir, 'bin', 'python') + ) or + os.path.exists( + os.path.join( + root, dir, 'Scripts', 'Python.exe' + ) + )): + dirs.remove(dir) + # Also don't search through tests + elif dir == 'test' or dir == 'tests': + dirs.remove(dir) + filenames.extend([os.path.join(root, dir) + for dir in dirs]) + filenames = [f for f in filenames if f.endswith('.egg-info')] + + if not filenames: + raise InstallationError( + "Files/directories not found in %s" % base + ) + # if we have more than one match, we pick the toplevel one. This + # can easily be the case if there is a dist folder which contains + # an extracted tarball for testing purposes. + if len(filenames) > 1: + filenames.sort( + key=lambda x: x.count(os.path.sep) + + (os.path.altsep and x.count(os.path.altsep) or 0) + ) + self._egg_info_path = os.path.join(base, filenames[0]) + return self._egg_info_path + + @property + def metadata(self): + if not hasattr(self, '_metadata'): + self._metadata = get_metadata(self.get_dist()) + + return self._metadata + + def get_dist(self): + # type: () -> Distribution + """Return a pkg_resources.Distribution for this requirement""" + if self.metadata_directory: + base_dir, distinfo = os.path.split(self.metadata_directory) + metadata = pkg_resources.PathMetadata( + base_dir, self.metadata_directory + ) + dist_name = os.path.splitext(distinfo)[0] + typ = pkg_resources.DistInfoDistribution + else: + egg_info = self.egg_info_path.rstrip(os.path.sep) + base_dir = os.path.dirname(egg_info) + metadata = pkg_resources.PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + # https://github.com/python/mypy/issues/1174 + typ = pkg_resources.Distribution # type: ignore + + return typ( + base_dir, + project_name=dist_name, + metadata=metadata, + ) + + def assert_source_matches_version(self): + # type: () -> None + assert self.source_dir + version = self.metadata['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + # For both source distributions and editables + def ensure_has_source_dir(self, parent_dir): + # type: (str) -> str + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.build_location(parent_dir) + return self.source_dir + + # For editable installations + def install_editable( + self, + install_options, # type: List[str] + global_options=(), # type: Sequence[str] + prefix=None # type: Optional[str] + ): + # type: (...) -> None + logger.info('Running setup.py develop for %s', self.name) + + if self.isolated: + global_options = list(global_options) + ["--no-user-cfg"] + + if prefix: + prefix_param = ['--prefix={}'.format(prefix)] + install_options = list(install_options) + prefix_param + + with indent_log(): + # FIXME: should we do --install-headers here too? + with self.build_env: + call_subprocess( + [ + sys.executable, + '-c', + SETUPTOOLS_SHIM % self.setup_py + ] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), + + cwd=self.setup_py_dir, + show_stdout=False, + ) + + self.install_succeeded = True + + def update_editable(self, obtain=True): + # type: (bool) -> None + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + if self.link.scheme == 'file': + # Static paths don't get updated + return + assert '+' in self.link.url, "bad url: %r" % self.link.url + if not self.update: + return + vc_type, url = self.link.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.link.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.link, vc_type)) + + # Top-level Actions + def uninstall(self, auto_confirm=False, verbose=False, + use_user_site=False): + # type: (bool, bool, bool) -> Optional[UninstallPathSet] + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(use_user_site): + logger.warning("Skipping %s as it is not installed.", self.name) + return None + dist = self.satisfied_by or self.conflicts_with + + uninstalled_pathset = UninstallPathSet.from_dist(dist) + uninstalled_pathset.remove(auto_confirm, verbose) + return uninstalled_pathset + + def _clean_zip_name(self, name, prefix): # only used by archive. + assert name.startswith(prefix + os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + + def _get_archive_name(self, path, parentdir, rootdir): + # type: (str, str, str) -> str + path = os.path.join(parentdir, path) + name = self._clean_zip_name(path, rootdir) + return self.name + '/' + name + + # TODO: Investigate if this should be kept in InstallRequirement + # Seems to be used only when VCS + downloads + def archive(self, build_dir): + # type: (str) -> None + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (self.name, self.metadata["version"]) + archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % + display_path(archive_path), ('i', 'w', 'b', 'a')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + shutil.move(archive_path, dest_file) + elif response == 'a': + sys.exit(-1) + if create_archive: + zip = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, + allowZip64=True + ) + dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) + for dirpath, dirnames, filenames in os.walk(dir): + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dir_arcname = self._get_archive_name(dirname, + parentdir=dirpath, + rootdir=dir) + zipdir = zipfile.ZipInfo(dir_arcname + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + file_arcname = self._get_archive_name(filename, + parentdir=dirpath, + rootdir=dir) + filename = os.path.join(dirpath, filename) + zip.write(filename, file_arcname) + zip.close() + logger.info('Saved %s', display_path(archive_path)) + + def install( + self, + install_options, # type: List[str] + global_options=None, # type: Optional[Sequence[str]] + root=None, # type: Optional[str] + home=None, # type: Optional[str] + prefix=None, # type: Optional[str] + warn_script_location=True, # type: bool + use_user_site=False, # type: bool + pycompile=True # type: bool + ): + # type: (...) -> None + global_options = global_options if global_options is not None else [] + if self.editable: + self.install_editable( + install_options, global_options, prefix=prefix, + ) + return + if self.is_wheel: + version = wheel.wheel_version(self.source_dir) + wheel.check_compatibility(version, self.name) + + self.move_wheel_files( + self.source_dir, root=root, prefix=prefix, home=home, + warn_script_location=warn_script_location, + use_user_site=use_user_site, pycompile=pycompile, + ) + self.install_succeeded = True + return + + # Extend the list of global and install options passed on to + # the setup.py call with the ones from the requirements file. + # Options specified in requirements file override those + # specified on the command line, since the last option given + # to setup.py is the one that is used. + global_options = list(global_options) + \ + self.options.get('global_options', []) + install_options = list(install_options) + \ + self.options.get('install_options', []) + + if self.isolated: + # https://github.com/python/mypy/issues/1174 + global_options = global_options + ["--no-user-cfg"] # type: ignore + + with TempDirectory(kind="record") as temp_dir: + record_filename = os.path.join(temp_dir.path, 'install-record.txt') + install_args = self.get_install_args( + global_options, record_filename, root, prefix, pycompile, + ) + msg = 'Running setup.py install for %s' % (self.name,) + with open_spinner(msg) as spinner: + with indent_log(): + with self.build_env: + call_subprocess( + install_args + install_options, + cwd=self.setup_py_dir, + show_stdout=False, + spinner=spinner, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + return + self.install_succeeded = True + + def prepend_root(path): + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + with open(record_filename) as f: + for line in f: + directory = os.path.dirname(line) + if directory.endswith('.egg-info'): + egg_info_dir = prepend_root(directory) + break + else: + logger.warning( + 'Could not find .egg-info directory in install record' + ' for %s', + self, + ) + # FIXME: put the record somewhere + # FIXME: should this be an error? + return + new_lines = [] + with open(record_filename) as f: + for line in f: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append( + os.path.relpath(prepend_root(filename), egg_info_dir) + ) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') + with open(inst_files_path, 'w') as f: + f.write('\n'.join(new_lines) + '\n') + + def get_install_args( + self, + global_options, # type: Sequence[str] + record_filename, # type: str + root, # type: Optional[str] + prefix, # type: Optional[str] + pycompile # type: bool + ): + # type: (...) -> List[str] + install_args = [sys.executable, "-u"] + install_args.append('-c') + install_args.append(SETUPTOOLS_SHIM % self.setup_py) + install_args += list(global_options) + \ + ['install', '--record', record_filename] + install_args += ['--single-version-externally-managed'] + + if root is not None: + install_args += ['--root', root] + if prefix is not None: + install_args += ['--prefix', prefix] + + if pycompile: + install_args += ["--compile"] + else: + install_args += ["--no-compile"] + + if running_under_virtualenv(): + py_ver_str = 'python' + sysconfig.get_python_version() + install_args += ['--install-headers', + os.path.join(sys.prefix, 'include', 'site', + py_ver_str, self.name)] + + return install_args diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_set.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_set.py new file mode 100755 index 0000000..d1410e9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_set.py @@ -0,0 +1,197 @@ +from __future__ import absolute_import + +import logging +from collections import OrderedDict + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.wheel import Wheel + +if MYPY_CHECK_RUNNING: + from typing import Optional, List, Tuple, Dict, Iterable # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + + +logger = logging.getLogger(__name__) + + +class RequirementSet(object): + + def __init__(self, require_hashes=False, check_supported_wheels=True): + # type: (bool, bool) -> None + """Create a RequirementSet. + """ + + self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] # noqa: E501 + self.require_hashes = require_hashes + self.check_supported_wheels = check_supported_wheels + + # Mapping of alias: real_name + self.requirement_aliases = {} # type: Dict[str, str] + self.unnamed_requirements = [] # type: List[InstallRequirement] + self.successfully_downloaded = [] # type: List[InstallRequirement] + self.reqs_to_cleanup = [] # type: List[InstallRequirement] + + def __str__(self): + reqs = [req for req in self.requirements.values() + if not req.comes_from] + reqs.sort(key=lambda req: req.name.lower()) + return ' '.join([str(req.req) for req in reqs]) + + def __repr__(self): + reqs = [req for req in self.requirements.values()] + reqs.sort(key=lambda req: req.name.lower()) + reqs_str = ', '.join([str(req.req) for req in reqs]) + return ('<%s object; %d requirement(s): %s>' + % (self.__class__.__name__, len(reqs), reqs_str)) + + def add_requirement( + self, + install_req, # type: InstallRequirement + parent_req_name=None, # type: Optional[str] + extras_requested=None # type: Optional[Iterable[str]] + ): + # type: (...) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]] # noqa: E501 + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + the requirement is not applicable, or [install_req] if the + requirement is applicable and has just been added. + """ + name = install_req.name + + # If the markers do not match, ignore this requirement. + if not install_req.match_markers(extras_requested): + logger.info( + "Ignoring %s: markers '%s' don't match your environment", + name, install_req.markers, + ) + return [], None + + # If the wheel is not supported, raise an error. + # Should check this after filtering out based on environment markers to + # allow specifying different wheels based on the environment/OS, in a + # single requirements file. + if install_req.link and install_req.link.is_wheel: + wheel = Wheel(install_req.link.filename) + if self.check_supported_wheels and not wheel.supported(): + raise InstallationError( + "%s is not a supported wheel on this platform." % + wheel.filename + ) + + # This next bit is really a sanity check. + assert install_req.is_direct == (parent_req_name is None), ( + "a direct req shouldn't have a parent and also, " + "a non direct req should have a parent" + ) + + # Unnamed requirements are scanned again and the requirement won't be + # added as a dependency until after scanning. + if not name: + # url or path requirement w/o an egg fragment + self.unnamed_requirements.append(install_req) + return [install_req], None + + try: + existing_req = self.get_requirement(name) + except KeyError: + existing_req = None + + has_conflicting_requirement = ( + parent_req_name is None and + existing_req and + not existing_req.constraint and + existing_req.extras == install_req.extras and + existing_req.req.specifier != install_req.req.specifier + ) + if has_conflicting_requirement: + raise InstallationError( + "Double requirement given: %s (already in %s, name=%r)" + % (install_req, existing_req, name) + ) + + # When no existing requirement exists, add the requirement as a + # dependency and it will be scanned again after. + if not existing_req: + self.requirements[name] = install_req + # FIXME: what about other normalizations? E.g., _ vs. -? + if name.lower() != name: + self.requirement_aliases[name.lower()] = name + # We'd want to rescan this requirements later + return [install_req], install_req + + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + if install_req.constraint or not existing_req.constraint: + return [], existing_req + + does_not_satisfy_constraint = ( + install_req.link and + not ( + existing_req.link and + install_req.link.path == existing_req.link.path + ) + ) + if does_not_satisfy_constraint: + self.reqs_to_cleanup.append(install_req) + raise InstallationError( + "Could not satisfy constraints for '%s': " + "installation from path or url cannot be " + "constrained to a version" % name, + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + existing_req.extras = tuple(sorted( + set(existing_req.extras) | set(install_req.extras) + )) + logger.debug( + "Setting %s extras to: %s", + existing_req, existing_req.extras, + ) + # Return the existing requirement for addition to the parent and + # scanning again. + return [existing_req], existing_req + + def has_requirement(self, project_name): + # type: (str) -> bool + name = project_name.lower() + if (name in self.requirements and + not self.requirements[name].constraint or + name in self.requirement_aliases and + not self.requirements[self.requirement_aliases[name]].constraint): + return True + return False + + @property + def has_requirements(self): + # type: () -> List[InstallRequirement] + return list(req for req in self.requirements.values() if not + req.constraint) or self.unnamed_requirements + + def get_requirement(self, project_name): + # type: (str) -> InstallRequirement + for name in project_name, project_name.lower(): + if name in self.requirements: + return self.requirements[name] + if name in self.requirement_aliases: + return self.requirements[self.requirement_aliases[name]] + raise KeyError("No project with the name %r" % project_name) + + def cleanup_files(self): + # type: () -> None + """Clean up files, remove builds.""" + logger.debug('Cleaning up...') + with indent_log(): + for req in self.reqs_to_cleanup: + req.remove_temporary_source() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_tracker.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_tracker.py new file mode 100755 index 0000000..82e084a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_tracker.py @@ -0,0 +1,88 @@ +from __future__ import absolute_import + +import contextlib +import errno +import hashlib +import logging +import os + +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Set, Iterator # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from pip._internal.models.link import Link # noqa: F401 + +logger = logging.getLogger(__name__) + + +class RequirementTracker(object): + + def __init__(self): + # type: () -> None + self._root = os.environ.get('PIP_REQ_TRACKER') + if self._root is None: + self._temp_dir = TempDirectory(delete=False, kind='req-tracker') + self._temp_dir.create() + self._root = os.environ['PIP_REQ_TRACKER'] = self._temp_dir.path + logger.debug('Created requirements tracker %r', self._root) + else: + self._temp_dir = None + logger.debug('Re-using requirements tracker %r', self._root) + self._entries = set() # type: Set[InstallRequirement] + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.cleanup() + + def _entry_path(self, link): + # type: (Link) -> str + hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() + return os.path.join(self._root, hashed) + + def add(self, req): + # type: (InstallRequirement) -> None + link = req.link + info = str(req) + entry_path = self._entry_path(link) + try: + with open(entry_path) as fp: + # Error, these's already a build in progress. + raise LookupError('%s is already being built: %s' + % (link, fp.read())) + except IOError as e: + if e.errno != errno.ENOENT: + raise + assert req not in self._entries + with open(entry_path, 'w') as fp: + fp.write(info) + self._entries.add(req) + logger.debug('Added %s to build tracker %r', req, self._root) + + def remove(self, req): + # type: (InstallRequirement) -> None + link = req.link + self._entries.remove(req) + os.unlink(self._entry_path(link)) + logger.debug('Removed %s from build tracker %r', req, self._root) + + def cleanup(self): + # type: () -> None + for req in set(self._entries): + self.remove(req) + remove = self._temp_dir is not None + if remove: + self._temp_dir.cleanup() + logger.debug('%s build tracker %r', + 'Removed' if remove else 'Cleaned', + self._root) + + @contextlib.contextmanager + def track(self, req): + # type: (InstallRequirement) -> Iterator[None] + self.add(req) + yield + self.remove(req) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_uninstall.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_uninstall.py new file mode 100755 index 0000000..c80959e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/req/req_uninstall.py @@ -0,0 +1,596 @@ +from __future__ import absolute_import + +import csv +import functools +import logging +import os +import sys +import sysconfig + +from pip._vendor import pkg_resources + +from pip._internal.exceptions import UninstallationError +from pip._internal.locations import bin_py, bin_user +from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, + normalize_path, renames, rmtree, +) +from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + @functools.wraps(fn) + def unique(*args, **kw): + seen = set() + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + """ + Yield all the uninstallation paths for dist based on RECORD-without-.py[co] + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc and .pyo in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .py[co]. + """ + r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + path = os.path.join(dn, base + '.pyo') + yield path + + +def compact(paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() + for path in sorted(paths, key=len): + should_skip = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_skip: + short_paths.add(path) + return short_paths + + +def compress_for_rename(paths): + """Returns a set containing the paths that need to be renamed. + + This set may include directories when the original sequence of paths + included every file on disk. + """ + case_map = dict((os.path.normcase(p), p) for p in paths) + remaining = set(case_map) + unchecked = sorted(set(os.path.split(p)[0] + for p in case_map.values()), key=len) + wildcards = set() + + def norm_join(*a): + return os.path.normcase(os.path.join(*a)) + + for root in unchecked: + if any(os.path.normcase(root).startswith(w) + for w in wildcards): + # This directory has already been handled. + continue + + all_files = set() + all_subdirs = set() + for dirname, subdirs, files in os.walk(root): + all_subdirs.update(norm_join(root, dirname, d) + for d in subdirs) + all_files.update(norm_join(root, dirname, f) + for f in files) + # If all the files we found are in our remaining set of files to + # remove, then remove them from the latter set and add a wildcard + # for the directory. + if not (all_files - remaining): + remaining.difference_update(all_files) + wildcards.add(root + os.sep) + + return set(map(case_map.__getitem__, remaining)) | wildcards + + +def compress_for_output_listing(paths): + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = list(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + _normcased_files = set(map(os.path.normcase, files)) + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.join(dirpath, fname) + if (os.path.isfile(file_) and + os.path.normcase(file_) not in _normcased_files): + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class StashedUninstallPathSet(object): + """A set of file rename operations to stash files while + tentatively uninstalling them.""" + def __init__(self): + # Mapping from source file root to [Adjacent]TempDirectory + # for files under that directory. + self._save_dirs = {} + # (old path, new path) tuples for each move that may need + # to be undone. + self._moves = [] + + def _get_directory_stash(self, path): + """Stashes a directory. + + Directories are stashed adjacent to their original location if + possible, or else moved/copied into the user's temp dir.""" + + try: + save_dir = AdjacentTempDirectory(path) + save_dir.create() + except OSError: + save_dir = TempDirectory(kind="uninstall") + save_dir.create() + self._save_dirs[os.path.normcase(path)] = save_dir + + return save_dir.path + + def _get_file_stash(self, path): + """Stashes a file. + + If no root has been provided, one will be created for the directory + in the user's temp directory.""" + path = os.path.normcase(path) + head, old_head = os.path.dirname(path), None + save_dir = None + + while head != old_head: + try: + save_dir = self._save_dirs[head] + break + except KeyError: + pass + head, old_head = os.path.dirname(head), head + else: + # Did not find any suitable root + head = os.path.dirname(path) + save_dir = TempDirectory(kind='uninstall') + save_dir.create() + self._save_dirs[head] = save_dir + + relpath = os.path.relpath(path, head) + if relpath and relpath != os.path.curdir: + return os.path.join(save_dir.path, relpath) + return save_dir.path + + def stash(self, path): + """Stashes the directory or file and returns its new location. + """ + if os.path.isdir(path): + new_path = self._get_directory_stash(path) + else: + new_path = self._get_file_stash(path) + + self._moves.append((path, new_path)) + if os.path.isdir(path) and os.path.isdir(new_path): + # If we're moving a directory, we need to + # remove the destination first or else it will be + # moved to inside the existing directory. + # We just created new_path ourselves, so it will + # be removable. + os.rmdir(new_path) + renames(path, new_path) + return new_path + + def commit(self): + """Commits the uninstall by removing stashed files.""" + for _, save_dir in self._save_dirs.items(): + save_dir.cleanup() + self._moves = [] + self._save_dirs = {} + + def rollback(self): + """Undoes the uninstall by moving stashed files back.""" + for p in self._moves: + logging.info("Moving to %s\n from %s", *p) + + for new_path, path in self._moves: + try: + logger.debug('Replacing %s from %s', new_path, path) + if os.path.isfile(new_path): + os.unlink(new_path) + elif os.path.isdir(new_path): + rmtree(new_path) + renames(path, new_path) + except OSError as ex: + logger.error("Failed to restore %s", new_path) + logger.debug("Exception: %s", ex) + + self.commit() + + @property + def can_rollback(self): + return bool(self._moves) + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self._moved_paths = StashedUninstallPathSet() + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def remove(self, auto_confirm=False, verbose=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + moved = self._moved_paths + + for_rename = compress_for_rename(self.paths) + + for path in sorted(compact(for_rename)): + moved.stash(path) + logger.debug('Removing file or directory %s', path) + + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = list(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + if verbose: + _display('Will actually move:', compress_for_rename(self.paths)) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + """Rollback the changes previously made by remove().""" + if not self._moved_paths.can_rollback: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return False + logger.info('Rolling back uninstall of %s', self.dist.project_name) + self._moved_paths.rollback() + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + self._moved_paths.commit() + + @classmethod + def from_dist(cls, dist): + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link %s does not match installed location of %s ' + '(at %s)' % (link_pointer, dist.project_name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + if not os.path.isfile(pth_file): + raise UninstallationError( + "Cannot remove entries from nonexistent file %s" % pth_file + ) + self.file = pth_file + self.entries = set() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.debug('Removing pth entries from %s:', self.file) + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/resolve.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/resolve.py new file mode 100755 index 0000000..33f572f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/resolve.py @@ -0,0 +1,393 @@ +"""Dependency Resolution + +The dependency resolution in pip is performed as follows: + +for top-level requirements: + a. only one spec allowed per project, regardless of conflicts or not. + otherwise a "double requirement" exception is raised + b. they override sub-dependency requirements. +for sub-dependencies + a. "first found, wins" (where the order is breadth first) +""" + +import logging +from collections import defaultdict +from itertools import chain + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + UnsupportedPythonVersion, +) +from pip._internal.req.constructors import install_req_from_req_string +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, ensure_dir +from pip._internal.utils.packaging import check_dist_requires_python +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, DefaultDict, List, Set # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from pip._internal.index import PackageFinder # noqa: F401 + from pip._internal.req.req_set import RequirementSet # noqa: F401 + from pip._internal.operations.prepare import ( # noqa: F401 + DistAbstraction, RequirementPreparer + ) + from pip._internal.cache import WheelCache # noqa: F401 + +logger = logging.getLogger(__name__) + + +class Resolver(object): + """Resolves which packages need to be installed/uninstalled to perform \ + the requested operation without breaking the requirements of any package. + """ + + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__( + self, + preparer, # type: RequirementPreparer + session, # type: PipSession + finder, # type: PackageFinder + wheel_cache, # type: Optional[WheelCache] + use_user_site, # type: bool + ignore_dependencies, # type: bool + ignore_installed, # type: bool + ignore_requires_python, # type: bool + force_reinstall, # type: bool + isolated, # type: bool + upgrade_strategy, # type: str + use_pep517=None # type: Optional[bool] + ): + # type: (...) -> None + super(Resolver, self).__init__() + assert upgrade_strategy in self._allowed_strategies + + self.preparer = preparer + self.finder = finder + self.session = session + + # NOTE: This would eventually be replaced with a cache that can give + # information about both sdist and wheels transparently. + self.wheel_cache = wheel_cache + + # This is set in resolve + self.require_hashes = None # type: Optional[bool] + + self.upgrade_strategy = upgrade_strategy + self.force_reinstall = force_reinstall + self.isolated = isolated + self.ignore_dependencies = ignore_dependencies + self.ignore_installed = ignore_installed + self.ignore_requires_python = ignore_requires_python + self.use_user_site = use_user_site + self.use_pep517 = use_pep517 + + self._discovered_dependencies = \ + defaultdict(list) # type: DefaultDict[str, List] + + def resolve(self, requirement_set): + # type: (RequirementSet) -> None + """Resolve what operations need to be done + + As a side-effect of this method, the packages (and their dependencies) + are downloaded, unpacked and prepared for installation. This + preparation is done by ``pip.operations.prepare``. + + Once PyPI has static dependency metadata available, it would be + possible to move the preparation to become a step separated from + dependency resolution. + """ + # make the wheelhouse + if self.preparer.wheel_download_dir: + ensure_dir(self.preparer.wheel_download_dir) + + # If any top-level requirement has a hash specified, enter + # hash-checking mode, which requires hashes from all. + root_reqs = ( + requirement_set.unnamed_requirements + + list(requirement_set.requirements.values()) + ) + self.require_hashes = ( + requirement_set.require_hashes or + any(req.has_hash_options for req in root_reqs) + ) + + # Display where finder is looking for packages + locations = self.finder.get_formatted_locations() + if locations: + logger.info(locations) + + # Actually prepare the files, and collect any exceptions. Most hash + # exceptions cannot be checked ahead of time, because + # req.populate_link() needs to be called before we can make decisions + # based on link type. + discovered_reqs = [] # type: List[InstallRequirement] + hash_errors = HashErrors() + for req in chain(root_reqs, discovered_reqs): + try: + discovered_reqs.extend( + self._resolve_one(requirement_set, req) + ) + except HashError as exc: + exc.req = req + hash_errors.append(exc) + + if hash_errors: + raise hash_errors + + def _is_upgrade_allowed(self, req): + # type: (InstallRequirement) -> bool + if self.upgrade_strategy == "to-satisfy-only": + return False + elif self.upgrade_strategy == "eager": + return True + else: + assert self.upgrade_strategy == "only-if-needed" + return req.is_direct + + def _set_req_to_reinstall(self, req): + # type: (InstallRequirement) -> None + """ + Set a requirement to be installed. + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. + if not self.use_user_site or dist_in_usersite(req.satisfied_by): + req.conflicts_with = req.satisfied_by + req.satisfied_by = None + + # XXX: Stop passing requirement_set for options + def _check_skip_installed(self, req_to_install): + # type: (InstallRequirement) -> Optional[str] + """Check if req_to_install should be skipped. + + This will check if the req is installed, and whether we should upgrade + or reinstall it, taking into account all the relevant user options. + + After calling this req_to_install will only have satisfied_by set to + None if the req_to_install is to be upgraded/reinstalled etc. Any + other value will be a dist recording the current thing installed that + satisfies the requirement. + + Note that for vcs urls and the like we can't assess skipping in this + routine - we simply identify that we need to pull the thing down, + then later on it is pulled down and introspected to assess upgrade/ + reinstalls etc. + + :return: A text reason for why it was skipped, or None. + """ + if self.ignore_installed: + return None + + req_to_install.check_if_exists(self.use_user_site) + if not req_to_install.satisfied_by: + return None + + if self.force_reinstall: + self._set_req_to_reinstall(req_to_install) + return None + + if not self._is_upgrade_allowed(req_to_install): + if self.upgrade_strategy == "only-if-needed": + return 'already satisfied, skipping upgrade' + return 'already satisfied' + + # Check for the possibility of an upgrade. For link-based + # requirements we have to pull the tree down and inspect to assess + # the version #, so it's handled way down. + if not req_to_install.link: + try: + self.finder.find_requirement(req_to_install, upgrade=True) + except BestVersionAlreadyInstalled: + # Then the best version is installed. + return 'already up-to-date' + except DistributionNotFound: + # No distribution found, so we squash the error. It will + # be raised later when we re-try later to do the install. + # Why don't we just raise here? + pass + + self._set_req_to_reinstall(req_to_install) + return None + + def _get_abstract_dist_for(self, req): + # type: (InstallRequirement) -> DistAbstraction + """Takes a InstallRequirement and returns a single AbstractDist \ + representing a prepared variant of the same. + """ + assert self.require_hashes is not None, ( + "require_hashes should have been set in Resolver.resolve()" + ) + + if req.editable: + return self.preparer.prepare_editable_requirement( + req, self.require_hashes, self.use_user_site, self.finder, + ) + + # satisfied_by is only evaluated by calling _check_skip_installed, + # so it must be None here. + assert req.satisfied_by is None + skip_reason = self._check_skip_installed(req) + + if req.satisfied_by: + return self.preparer.prepare_installed_requirement( + req, self.require_hashes, skip_reason + ) + + upgrade_allowed = self._is_upgrade_allowed(req) + abstract_dist = self.preparer.prepare_linked_requirement( + req, self.session, self.finder, upgrade_allowed, + self.require_hashes + ) + + # NOTE + # The following portion is for determining if a certain package is + # going to be re-installed/upgraded or not and reporting to the user. + # This should probably get cleaned up in a future refactor. + + # req.req is only avail after unpack for URL + # pkgs repeat check_if_exists to uninstall-on-upgrade + # (#14) + if not self.ignore_installed: + req.check_if_exists(self.use_user_site) + + if req.satisfied_by: + should_modify = ( + self.upgrade_strategy != "to-satisfy-only" or + self.force_reinstall or + self.ignore_installed or + req.link.scheme == 'file' + ) + if should_modify: + self._set_req_to_reinstall(req) + else: + logger.info( + 'Requirement already satisfied (use --upgrade to upgrade):' + ' %s', req, + ) + + return abstract_dist + + def _resolve_one( + self, + requirement_set, # type: RequirementSet + req_to_install # type: InstallRequirement + ): + # type: (...) -> List[InstallRequirement] + """Prepare a single requirements file. + + :return: A list of additional InstallRequirements to also install. + """ + # Tell user what we are doing for this requirement: + # obtain (editable), skipping, processing (local url), collecting + # (remote url or package name) + if req_to_install.constraint or req_to_install.prepared: + return [] + + req_to_install.prepared = True + + # register tmp src for cleanup in case something goes wrong + requirement_set.reqs_to_cleanup.append(req_to_install) + + abstract_dist = self._get_abstract_dist_for(req_to_install) + + # Parse and return dependencies + dist = abstract_dist.dist() + try: + check_dist_requires_python(dist) + except UnsupportedPythonVersion as err: + if self.ignore_requires_python: + logger.warning(err.args[0]) + else: + raise + + more_reqs = [] # type: List[InstallRequirement] + + def add_req(subreq, extras_requested): + sub_install_req = install_req_from_req_string( + str(subreq), + req_to_install, + isolated=self.isolated, + wheel_cache=self.wheel_cache, + use_pep517=self.use_pep517 + ) + parent_req_name = req_to_install.name + to_scan_again, add_to_parent = requirement_set.add_requirement( + sub_install_req, + parent_req_name=parent_req_name, + extras_requested=extras_requested, + ) + if parent_req_name and add_to_parent: + self._discovered_dependencies[parent_req_name].append( + add_to_parent + ) + more_reqs.extend(to_scan_again) + + with indent_log(): + # We add req_to_install before its dependencies, so that we + # can refer to it when adding dependencies. + if not requirement_set.has_requirement(req_to_install.name): + # 'unnamed' requirements will get added here + req_to_install.is_direct = True + requirement_set.add_requirement( + req_to_install, parent_req_name=None, + ) + + if not self.ignore_dependencies: + if req_to_install.extras: + logger.debug( + "Installing extra requirements: %r", + ','.join(req_to_install.extras), + ) + missing_requested = sorted( + set(req_to_install.extras) - set(dist.extras) + ) + for missing in missing_requested: + logger.warning( + '%s does not provide the extra \'%s\'', + dist, missing + ) + + available_requested = sorted( + set(dist.extras) & set(req_to_install.extras) + ) + for subreq in dist.requires(available_requested): + add_req(subreq, extras_requested=available_requested) + + if not req_to_install.editable and not req_to_install.satisfied_by: + # XXX: --no-install leads this to report 'Successfully + # downloaded' for only non-editable reqs, even though we took + # action on them. + requirement_set.successfully_downloaded.append(req_to_install) + + return more_reqs + + def get_installation_order(self, req_set): + # type: (RequirementSet) -> List[InstallRequirement] + """Create the installation order. + + The installation order is topological - requirements are installed + before the requiring thing. We break cycles at an arbitrary point, + and make no other guarantees. + """ + # The current implementation, which we may change at any point + # installs the user specified things in the order given, except when + # dependencies must come earlier to achieve topological order. + order = [] + ordered_reqs = set() # type: Set[InstallRequirement] + + def schedule(req): + if req.satisfied_by or req in ordered_reqs: + return + if req.constraint: + return + ordered_reqs.add(req) + for dep in self._discovered_dependencies[req.name]: + schedule(dep) + order.append(req) + + for install_req in req_set.requirements.values(): + schedule(install_req) + return order diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/appdirs.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/appdirs.py new file mode 100755 index 0000000..9af9fa7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/appdirs.py @@ -0,0 +1,270 @@ +""" +This code was taken from https://github.com/ActiveState/appdirs and modified +to suit our purposes. +""" +from __future__ import absolute_import + +import os +import sys + +from pip._vendor.six import PY2, text_type + +from pip._internal.utils.compat import WINDOWS, expanduser +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + List, Union + ) + + +def user_cache_dir(appname): + # type: (str) -> str + r""" + Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + + Typical user cache directories are: + macOS: ~/Library/Caches/ + Unix: ~/.cache/ (XDG default) + Windows: C:\Users\\AppData\Local\\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go + in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the + non-roaming app data dir (the default returned by `user_data_dir`). Apps + typically put cache data somewhere *under* the given dir here. Some + examples: + ...\Mozilla\Firefox\Profiles\\Cache + ...\Acme\SuperApp\Cache\1.0 + + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + """ + if WINDOWS: + # Get the base path + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if PY2 and isinstance(path, text_type): + path = _win_path_to_bytes(path) + + # Add our app name and Cache directory to it + path = os.path.join(path, appname, "Cache") + elif sys.platform == "darwin": + # Get the base path + path = expanduser("~/Library/Caches") + + # Add our app name to it + path = os.path.join(path, appname) + else: + # Get the base path + path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) + + # Add our app name to it + path = os.path.join(path, appname) + + return path + + +def user_data_dir(appname, roaming=False): + # type: (str, bool) -> str + r""" + Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: ~/Library/Application Support/ + if it exists, else ~/.config/ + Unix: ~/.local/share/ # or in + $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\ ... + ...Application Data\ + Win XP (roaming): C:\Documents and Settings\\Local ... + ...Settings\Application Data\ + Win 7 (not roaming): C:\\Users\\AppData\Local\ + Win 7 (roaming): C:\\Users\\AppData\Roaming\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + if WINDOWS: + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) + elif sys.platform == "darwin": + path = os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) if os.path.isdir(os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) + ) else os.path.join( + expanduser('~/.config/'), + appname, + ) + else: + path = os.path.join( + os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), + appname, + ) + + return path + + +def user_config_dir(appname, roaming=True): + # type: (str, bool) -> str + """Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default True) can be set False to not use the + Windows roaming appdata directory. That means that for users on a + Windows network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: same as user_data_dir + Unix: ~/.config/ + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + if WINDOWS: + path = user_data_dir(appname, roaming=roaming) + elif sys.platform == "darwin": + path = user_data_dir(appname) + else: + path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) + path = os.path.join(path, appname) + + return path + + +# for the discussion regarding site_config_dirs locations +# see +def site_config_dirs(appname): + # type: (str) -> List[str] + r"""Return a list of potential user-shared config dirs for this application. + + "appname" is the name of application. + + Typical user config directories are: + macOS: /Library/Application Support// + Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in + $XDG_CONFIG_DIRS + Win XP: C:\Documents and Settings\All Users\Application ... + ...Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory + on Vista.) + Win 7: Hidden, but writeable on Win 7: + C:\ProgramData\\ + """ + if WINDOWS: + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + pathlist = [os.path.join(path, appname)] + elif sys.platform == 'darwin': + pathlist = [os.path.join('/Library/Application Support', appname)] + else: + # try looking in $XDG_CONFIG_DIRS + xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + if xdg_config_dirs: + pathlist = [ + os.path.join(expanduser(x), appname) + for x in xdg_config_dirs.split(os.pathsep) + ] + else: + pathlist = [] + + # always look in /etc directly as well + pathlist.append('/etc') + + return pathlist + + +# -- Windows support functions -- + +def _get_win_folder_from_registry(csidl_name): + # type: (str) -> str + """ + This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + directory, _type = _winreg.QueryValueEx(key, shell_folder_name) + return directory + + +def _get_win_folder_with_ctypes(csidl_name): + # type: (str) -> str + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + + +if WINDOWS: + try: + import ctypes + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + . + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/compat.py new file mode 100755 index 0000000..2d8b3bf --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/compat.py @@ -0,0 +1,264 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" +from __future__ import absolute_import, division + +import codecs +import locale +import logging +import os +import shutil +import sys + +from pip._vendor.six import text_type + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Tuple, Text # noqa: F401 + +try: + import ipaddress +except ImportError: + try: + from pip._vendor import ipaddress # type: ignore + except ImportError: + import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress # type: ignore + ipaddress.ip_network = ipaddress.IPNetwork # type: ignore + + +__all__ = [ + "ipaddress", "uses_pycache", "console_to_str", "native_str", + "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", + "get_extension_suffixes", +] + + +logger = logging.getLogger(__name__) + +if sys.version_info >= (3, 4): + uses_pycache = True + from importlib.util import cache_from_source +else: + import imp + + try: + cache_from_source = imp.cache_from_source # type: ignore + except AttributeError: + # does not use __pycache__ + cache_from_source = None + + uses_pycache = cache_from_source is not None + + +if sys.version_info >= (3, 5): + backslashreplace_decode = "backslashreplace" +else: + # In version 3.4 and older, backslashreplace exists + # but does not support use for decoding. + # We implement our own replace handler for this + # situation, so that we can consistently use + # backslash replacement for all versions. + def backslashreplace_decode_fn(err): + raw_bytes = (err.object[i] for i in range(err.start, err.end)) + if sys.version_info[0] == 2: + # Python 2 gave us characters - convert to numeric bytes + raw_bytes = (ord(b) for b in raw_bytes) + return u"".join(u"\\x%x" % c for c in raw_bytes), err.end + codecs.register_error( + "backslashreplace_decode", + backslashreplace_decode_fn, + ) + backslashreplace_decode = "backslashreplace_decode" + + +def console_to_str(data): + # type: (bytes) -> Text + """Return a string, safe for output, of subprocess output. + + We assume the data is in the locale preferred encoding. + If it won't decode properly, we warn the user but decode as + best we can. + + We also ensure that the output can be safely written to + standard output without encoding errors. + """ + + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + decoded_data = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + "Subprocess output does not appear to be encoded as %s", + encoding, + ) + decoded_data = data.decode(encoding, errors=backslashreplace_decode) + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + output_encoded = decoded_data.encode( + output_encoding, + errors="backslashreplace" + ) + decoded_data = output_encoded.decode(output_encoding) + + return decoded_data + + +if sys.version_info >= (3,): + def native_str(s, replace=False): + # type: (str, bool) -> str + if isinstance(s, bytes): + return s.decode('utf-8', 'replace' if replace else 'strict') + return s + +else: + def native_str(s, replace=False): + # type: (str, bool) -> str + # Replace is ignored -- unicode to UTF-8 can't fail + if isinstance(s, text_type): + return s.encode('utf-8') + return s + + +def get_path_uid(path): + # type: (str) -> int + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "%s is a symlink; Will not return uid for symlinks" % path + ) + return file_uid + + +if sys.version_info >= (3, 4): + from importlib.machinery import EXTENSION_SUFFIXES + + def get_extension_suffixes(): + return EXTENSION_SUFFIXES +else: + from imp import get_suffixes + + def get_extension_suffixes(): + return [suffix[0] for suffix in get_suffixes()] + + +def expanduser(path): + # type: (str) -> str + """ + Expand ~ and ~user constructions. + + Includes a workaround for https://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith('~/') and expanded.startswith('//'): + expanded = expanded[1:] + return expanded + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) + + +def samefile(file1, file2): + # type: (str, str) -> bool + """Provide an alternative for os.path.samefile on Windows/Python2""" + if hasattr(os.path, 'samefile'): + return os.path.samefile(file1, file2) + else: + path1 = os.path.normcase(os.path.abspath(file1)) + path2 = os.path.normcase(os.path.abspath(file2)) + return path1 == path2 + + +if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): + # type: () -> Tuple[int, int] + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + return tuple(shutil.get_terminal_size()) # type: ignore +else: + def get_terminal_size(): + # type: () -> Tuple[int, int] + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack_from( + 'hh', + fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + ) + except Exception: + return None + if cr == (0, 0): + return None + return cr + 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 Exception: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/deprecation.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/deprecation.py new file mode 100755 index 0000000..0beaf74 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/deprecation.py @@ -0,0 +1,90 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" +from __future__ import absolute_import + +import logging +import warnings + +from pip._vendor.packaging.version import parse + +from pip import __version__ as current_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional # noqa: F401 + + +class PipDeprecationWarning(Warning): + pass + + +_original_showwarning = None # type: Any + + +# Warnings <-> Logging Integration +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _original_showwarning is not None: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + elif issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + logger.warning(message) + else: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # type: () -> None + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _original_showwarning + + if _original_showwarning is None: + _original_showwarning = warnings.showwarning + warnings.showwarning = _showwarning + + +def deprecated(reason, replacement, gone_in, issue=None): + # type: (str, Optional[str], Optional[str], Optional[int]) -> None + """Helper to deprecate existing functionality. + + reason: + Textual reason shown to the user about why this functionality has + been deprecated. + replacement: + Textual suggestion shown to the user about what alternative + functionality they can use. + gone_in: + The version of pip does this functionality should get removed in. + Raises errors if pip's current version is greater than or equal to + this. + issue: + Issue number on the tracker that would serve as a useful place for + users to find related discussion and provide feedback. + + Always pass replacement, gone_in and issue as keyword arguments for clarity + at the call site. + """ + + # Construct a nice message. + # This is purposely eagerly formatted as we want it to appear as if someone + # typed this entire message out. + message = "DEPRECATION: " + reason + if replacement is not None: + message += " A possible replacement is {}.".format(replacement) + if issue is not None: + url = "https://github.com/pypa/pip/issues/" + str(issue) + message += " You can find discussion regarding this at {}.".format(url) + + # Raise as an error if it has to be removed. + if gone_in is not None and parse(current_version) >= parse(gone_in): + raise PipDeprecationWarning(message) + warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/encoding.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/encoding.py new file mode 100755 index 0000000..d36defa --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/encoding.py @@ -0,0 +1,39 @@ +import codecs +import locale +import re +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Tuple, Text # noqa: F401 + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] # type: List[Tuple[bytes, Text]] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + # type: (bytes) -> Text + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # Lets check the first two lines as in PEP263 + for line in data.split(b'\n')[:2]: + if line[0:1] == b'#' and ENCODING_RE.search(line): + encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/filesystem.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/filesystem.py new file mode 100755 index 0000000..1e6b033 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/filesystem.py @@ -0,0 +1,30 @@ +import os +import os.path + +from pip._internal.utils.compat import get_path_uid + + +def check_path_owner(path): + # type: (str) -> bool + # If we don't have a way to check the effective uid of this process, then + # we'll just assume that we own the directory. + if not hasattr(os, "geteuid"): + return True + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) + return False # assume we don't own the path diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/glibc.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/glibc.py new file mode 100755 index 0000000..8a51f69 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/glibc.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import + +import ctypes +import re +import warnings + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple # noqa: F401 + + +def glibc_version_string(): + # type: () -> Optional[str] + "Returns glibc version string, or None if not using glibc." + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# Separated out from have_compatible_glibc for easier unit testing +def check_glibc_version(version_str, required_major, minimum_minor): + # type: (str, int, int) -> bool + # Parse string and check against requested version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return (int(m.group("major")) == required_major and + int(m.group("minor")) >= minimum_minor) + + +def have_compatible_glibc(required_major, minimum_minor): + # type: (int, int) -> bool + version_str = glibc_version_string() # type: Optional[str] + if version_str is None: + return False + return check_glibc_version(version_str, required_major, minimum_minor) + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + # type: () -> Tuple[str, str] + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/hashes.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/hashes.py new file mode 100755 index 0000000..c6df7a1 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/hashes.py @@ -0,0 +1,115 @@ +from __future__ import absolute_import + +import hashlib + +from pip._vendor.six import iteritems, iterkeys, itervalues + +from pip._internal.exceptions import ( + HashMismatch, HashMissing, InstallationError, +) +from pip._internal.utils.misc import read_chunks +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Dict, List, BinaryIO, NoReturn, Iterator + ) + from pip._vendor.six import PY3 + if PY3: + from hashlib import _Hash # noqa: F401 + else: + from hashlib import _hash as _Hash # noqa: F401 + + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes(object): + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + # type: (Dict[str, List[str]]) -> None + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + self._allowed = {} if hashes is None else hashes + + def check_against_chunks(self, chunks): + # type: (Iterator[bytes]) -> None + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in iterkeys(self._allowed): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError('Unknown hash name: %s' % hash_name) + + for chunk in chunks: + for hash in itervalues(gots): + hash.update(chunk) + + for hash_name, got in iteritems(gots): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + # type: (Dict[str, _Hash]) -> NoReturn + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + # type: (BinaryIO) -> None + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + # type: (str) -> None + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + # type: () -> bool + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + # type: () -> bool + return self.__nonzero__() + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + # type: () -> None + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + # type: (Dict[str, _Hash]) -> NoReturn + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/logging.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/logging.py new file mode 100755 index 0000000..579d696 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/logging.py @@ -0,0 +1,318 @@ +from __future__ import absolute_import + +import contextlib +import errno +import logging +import logging.handlers +import os +import sys + +from pip._vendor.six import PY2 + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +_log_state.indentation = 0 + + +class BrokenStdoutLoggingError(Exception): + """ + Raised if BrokenPipeError occurs for the stdout stream while logging. + """ + pass + + +# BrokenPipeError does not exist in Python 2 and, in addition, manifests +# differently in Windows and non-Windows. +if WINDOWS: + # In Windows, a broken pipe can show up as EINVAL rather than EPIPE: + # https://bugs.python.org/issue19612 + # https://bugs.python.org/issue30418 + if PY2: + def _is_broken_pipe_error(exc_class, exc): + """See the docstring for non-Windows Python 3 below.""" + return (exc_class is IOError and + exc.errno in (errno.EINVAL, errno.EPIPE)) + else: + # In Windows, a broken pipe IOError became OSError in Python 3. + def _is_broken_pipe_error(exc_class, exc): + """See the docstring for non-Windows Python 3 below.""" + return ((exc_class is BrokenPipeError) or # noqa: F821 + (exc_class is OSError and + exc.errno in (errno.EINVAL, errno.EPIPE))) +elif PY2: + def _is_broken_pipe_error(exc_class, exc): + """See the docstring for non-Windows Python 3 below.""" + return (exc_class is IOError and exc.errno == errno.EPIPE) +else: + # Then we are in the non-Windows Python 3 case. + def _is_broken_pipe_error(exc_class, exc): + """ + Return whether an exception is a broken pipe error. + + Args: + exc_class: an exception class. + exc: an exception instance. + """ + return (exc_class is BrokenPipeError) # noqa: F821 + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + def __init__(self, *args, **kwargs): + """ + A logging.Formatter obeying containing indent_log contexts. + + :param add_timestamp: A bool indicating output lines should be prefixed + with their record's timestamp. + """ + self.add_timestamp = kwargs.pop("add_timestamp", False) + super(IndentingFormatter, self).__init__(*args, **kwargs) + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log messages + by our current indentation level. + """ + formatted = super(IndentingFormatter, self).format(record) + prefix = '' + if self.add_timestamp: + prefix = self.formatTime(record, "%Y-%m-%dT%H:%M:%S ") + prefix += " " * get_indentation() + formatted = "".join([ + prefix + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + logging.StreamHandler.__init__(self, stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def _using_stdout(self): + """ + Return whether the handler is using sys.stdout. + """ + if WINDOWS and colorama: + # Then self.stream is an AnsiToWin32 object. + return self.stream.wrapped is sys.stdout + + return self.stream is sys.stdout + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ANSI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + # The logging module says handleError() can be customized. + def handleError(self, record): + exc_class, exc = sys.exc_info()[:2] + # If a broken pipe occurred while calling write() or flush() on the + # stdout stream in logging's Handler.emit(), then raise our special + # exception so we can handle it in main() instead of logging the + # broken pipe error and continuing. + if (exc_class and self._using_stdout() and + _is_broken_pipe_error(exc_class, exc)): + raise BrokenStdoutLoggingError() + + return super(ColorizedStreamHandler, self).handleError(record) + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(logging.Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level + + +def setup_logging(verbosity, no_color, user_log_file): + """Configures and sets up all of the logging + + Returns the requested logging level, as its integer value. + """ + + # Determine the level to be logging at. + if verbosity >= 1: + level = "DEBUG" + elif verbosity == -1: + level = "WARNING" + elif verbosity == -2: + level = "ERROR" + elif verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + level_number = getattr(logging, level) + + # The "root" logger should match the "console" level *unless* we also need + # to log to a user log file. + include_user_log = user_log_file is not None + if include_user_log: + additional_log_file = user_log_file + root_level = "DEBUG" + else: + additional_log_file = "/dev/null" + root_level = level + + # Disable any logging besides WARNING unless we have DEBUG level logging + # enabled for vendored libraries. + vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + + # Shorthands for clarity + log_streams = { + "stdout": "ext://sys.stdout", + "stderr": "ext://sys.stderr", + } + handler_classes = { + "stream": "pip._internal.utils.logging.ColorizedStreamHandler", + "file": "pip._internal.utils.logging.BetterRotatingFileHandler", + } + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + "indent_with_timestamp": { + "()": IndentingFormatter, + "format": "%(message)s", + "add_timestamp": True, + }, + }, + "handlers": { + "console": { + "level": level, + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stdout"], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stderr"], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_classes["file"], + "filename": additional_log_file, + "delay": True, + "formatter": "indent_with_timestamp", + }, + }, + "root": { + "level": root_level, + "handlers": ["console", "console_errors"] + ( + ["user_log"] if include_user_log else [] + ), + }, + "loggers": { + "pip._vendor": { + "level": vendored_log_level + } + }, + }) + + return level_number diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/misc.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/misc.py new file mode 100755 index 0000000..84605ee --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/misc.py @@ -0,0 +1,1040 @@ +from __future__ import absolute_import + +import contextlib +import errno +import io +import locale +# we have a submodule named 'logging' which would shadow this if we used the +# regular name: +import logging as std_logging +import os +import posixpath +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import zipfile +from collections import deque + +from pip._vendor import pkg_resources +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore +from pip._vendor.six import PY2 +from pip._vendor.six.moves import input +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote + +from pip._internal.exceptions import CommandError, InstallationError +from pip._internal.locations import ( + running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + write_delete_marker_file, +) +from pip._internal.utils.compat import ( + WINDOWS, console_to_str, expanduser, stdlib_pkgs, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if PY2: + from io import BytesIO as StringIO +else: + from io import StringIO + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Optional, Tuple, Iterable, List, Match, Union, Any, Mapping, Text, + AnyStr, Container + ) + from pip._vendor.pkg_resources import Distribution # noqa: F401 + from pip._internal.models.link import Link # noqa: F401 + from pip._internal.utils.ui import SpinnerInterface # noqa: F401 + + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'ask', 'splitext', + 'format_size', 'is_installable_dir', + 'is_svn_page', 'file_contents', + 'split_leading_dir', 'has_leading_dir', + 'normalize_path', + 'renames', 'get_prog', + 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', + 'captured_stdout', 'ensure_dir', + 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', 'WHEEL_EXTENSION', + 'get_installed_version', 'remove_auth_from_url'] + + +logger = std_logging.getLogger(__name__) + +WHEEL_EXTENSION = '.whl' +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') +ZIP_EXTENSIONS = ('.zip', WHEEL_EXTENSION) +TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') +ARCHIVE_EXTENSIONS = ( + ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) +SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS + +try: + import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS +except ImportError: + logger.debug('bz2 module is not available') + +try: + # Only for Python 3.3+ + import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS +except ImportError: + logger.debug('lzma module is not available') + + +def ensure_dir(path): + # type: (AnyStr) -> None + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + +def get_prog(): + # type: () -> str + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return "%s -m pip" % sys.executable + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + # type: (str, bool) -> None + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + # if file type currently read only + if os.stat(path).st_mode & stat.S_IREAD: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def display_path(path): + # type: (Union[str, Text]) -> str + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if sys.version_info[0] == 2: + path = path.decode(sys.getfilesystemencoding(), 'replace') + path = path.encode(sys.getdefaultencoding(), 'replace') + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + # type: (str, str) -> str + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + # type: (str, Iterable[str]) -> str + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def ask(message, options): + # type: (str, Iterable[str]) -> str + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: %s' % + message + ) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response (%r) was not one of the expected responses: ' + '%s' % (response, ', '.join(options)) + ) + else: + return response + + +def format_size(bytes): + # type: (float) -> str + if bytes > 1000 * 1000: + return '%.1fMB' % (bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '%ikB' % (bytes / 1000) + elif bytes > 1000: + return '%.1fkB' % (bytes / 1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + # type: (str) -> bool + """Is path is a directory containing setup.py or pyproject.toml? + """ + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + pyproject_toml = os.path.join(path, 'pyproject.toml') + if os.path.isfile(pyproject_toml): + return True + return False + + +def is_svn_page(html): + # type: (Union[str, Text]) -> Optional[Match[Union[str, Text]]] + """ + Returns true if the page appears to be the index page of an svn repository + """ + return (re.search(r'[^<]*Revision \d+:', html) and + re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + # type: (str) -> Text + with open(filename, 'rb') as fp: + return fp.read().decode('utf-8') + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + """Yield pieces of data from a file-like object until EOF.""" + while True: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def split_leading_dir(path): + # type: (Union[str, Text]) -> List[Union[str, Text]] + path = path.lstrip('/').lstrip('\\') + if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or + '\\' not in path): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return [path, ''] + + +def has_leading_dir(paths): + # type: (Iterable[Union[str, Text]]) -> bool + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def normalize_path(path, resolve_symlinks=True): + # type: (str, bool) -> str + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + # type: (str) -> Tuple[str, str] + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + # type: (str, str) -> None + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + # type: (str) -> bool + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def dist_in_usersite(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is installed in user site. + """ + norm_path = normalize_path(dist_location(dist)) + return norm_path.startswith(normalize_path(user_site)) + + +def dist_in_site_packages(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is installed in + sysconfig.get_python_lib(). + """ + return normalize_path( + dist_location(dist) + ).startswith(normalize_path(site_packages)) + + +def dist_is_editable(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is an editable install. + """ + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions(local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False): + # type: (bool, Container[str], bool, bool, bool) -> List[Distribution] + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + """ + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + # because of pkg_resources vendoring, mypy cannot find stub in typeshed + return [d for d in pkg_resources.working_set # type: ignore + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def egg_link_path(dist): + # type: (Distribution) -> Optional[str] + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + sites = [] + if running_under_virtualenv(): + if virtualenv_no_global(): + sites.append(site_packages) + else: + sites.append(site_packages) + if user_site: + sites.append(user_site) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + return None + + +def dist_location(dist): + # type: (Distribution) -> str + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if egg_link: + return egg_link + return dist.location + + +def current_umask(): + """Get the current umask which involves having to set it temporarily.""" + mask = os.umask(0) + os.umask(mask) + return mask + + +def unzip_file(filename, location, flatten=True): + # type: (str, str, bool) -> None + """ + Unzip the file (with path `filename`) to the destination `location`. All + files are written based on system defaults and umask (i.e. permissions are + not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp, allowZip64=True) + leading = has_leading_dir(zip.namelist()) and flatten + for info in zip.infolist(): + name = info.filename + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + ensure_dir(fn) + else: + ensure_dir(dir) + # Don't use read() to avoid allocating an arbitrarily large + # chunk of memory for the file's content + fp = zip.open(name) + try: + with open(fn, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + finally: + fp.close() + mode = info.external_attr >> 16 + # if mode and regular file and any execute permissions for + # user/group/world? + if mode and stat.S_ISREG(mode) and mode & 0o111: + # make dest file have execute for user/group/world + # (chmod +x) no-op on windows per python docs + os.chmod(fn, (0o777 - current_umask() | 0o111)) + finally: + zipfp.close() + + +def untar_file(filename, location): + # type: (str, str) -> None + """ + Untar the file (with path `filename`) to the destination `location`. + All files are written based on system defaults and umask (i.e. permissions + are not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith(BZ2_EXTENSIONS): + mode = 'r:bz2' + elif filename.lower().endswith(XZ_EXTENSIONS): + mode = 'r:xz' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warning( + 'Cannot determine compression type for file %s', filename, + ) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + leading = has_leading_dir([ + member.name for member in tar.getmembers() + ]) + for member in tar.getmembers(): + fn = member.name + if leading: + # https://github.com/python/mypy/issues/1174 + fn = split_leading_dir(fn)[1] # type: ignore + path = os.path.join(location, fn) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + # https://github.com/python/typeshed/issues/2673 + tar._extract_member(member, path) # type: ignore + except Exception as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError) as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + ensure_dir(os.path.dirname(path)) + with open(path, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + fp.close() + # Update the timestamp (useful for cython compiled files) + # https://github.com/python/typeshed/issues/2673 + tar.utime(member, path) # type: ignore + # member have any execute permissions for user/group/world? + if member.mode & 0o111: + # make dest file have execute for user/group/world + # no-op on windows per python docs + os.chmod(path, (0o777 - current_umask() | 0o111)) + finally: + tar.close() + + +def unpack_file( + filename, # type: str + location, # type: str + content_type, # type: Optional[str] + link # type: Optional[Link] +): + # type: (...) -> None + filename = os.path.realpath(filename) + if (content_type == 'application/zip' or + filename.lower().endswith(ZIP_EXTENSIONS) or + zipfile.is_zipfile(filename)): + unzip_file( + filename, + location, + flatten=not filename.endswith('.whl') + ) + elif (content_type == 'application/x-gzip' or + tarfile.is_tarfile(filename) or + filename.lower().endswith( + TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): + untar_file(filename, location) + elif (content_type and content_type.startswith('text/html') and + is_svn_page(file_contents(filename))): + # We don't really care about this + from pip._internal.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) + else: + # FIXME: handle? + # FIXME: magic signatures? + logger.critical( + 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' + 'cannot detect archive format', + filename, location, content_type, + ) + raise InstallationError( + 'Cannot determine archive format of %s' % location + ) + + +def call_subprocess( + cmd, # type: List[str] + show_stdout=True, # type: bool + cwd=None, # type: Optional[str] + on_returncode='raise', # type: str + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + command_desc=None, # type: Optional[str] + extra_environ=None, # type: Optional[Mapping[str, Any]] + unset_environ=None, # type: Optional[Iterable[str]] + spinner=None # type: Optional[SpinnerInterface] +): + # type: (...) -> Optional[Text] + """ + Args: + extra_ok_returncodes: an iterable of integer return codes that are + acceptable, in addition to 0. Defaults to None, which means []. + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + """ + if extra_ok_returncodes is None: + extra_ok_returncodes = [] + if unset_environ is None: + unset_environ = [] + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + logger.debug("Running command %s", command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + for name in unset_environ: + env.pop(name, None) + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, + stdout=stdout, cwd=cwd, env=env, + ) + proc.stdin.close() + except Exception as exc: + logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if stdout is not None: + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + if spinner is not None: + if proc.returncode: + spinner.finish("error") + else: + spinner.finish("done") + if proc.returncode and proc.returncode not in extra_ok_returncodes: + if on_returncode == 'raise': + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): + logger.info( + 'Complete output from command %s:', command_desc, + ) + logger.info( + ''.join(all_output) + + '\n----------------------------------------' + ) + raise InstallationError( + 'Command "%s" failed with error code %s in %s' + % (command_desc, proc.returncode, cwd)) + elif on_returncode == 'warn': + logger.warning( + 'Command "%s" had error code %s in %s', + command_desc, proc.returncode, cwd, + ) + elif on_returncode == 'ignore': + pass + else: + raise ValueError('Invalid value: on_returncode=%s' % + repr(on_returncode)) + if not show_stdout: + return ''.join(all_output) + return None + + +def read_text_file(filename): + # type: (str) -> str + """Return the contents of *filename*. + + Try to decode the file contents with utf-8, the preferred system encoding + (e.g., cp1252 on some Windows machines), and latin1, in that order. + Decoding a byte string with latin1 will never raise an error. In the worst + case, the returned string will contain some garbage characters. + + """ + with open(filename, 'rb') as fp: + data = fp.read() + + encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] + for enc in encodings: + try: + # https://github.com/python/mypy/issues/1174 + data = data.decode(enc) # type: ignore + except UnicodeDecodeError: + continue + break + + assert not isinstance(data, bytes) # Latin1 should have worked. + return data + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + write_delete_marker_file(build_dir) + + +class FakeFile(object): + """Wrap a list of lines in an object with readline() to make + ConfigParser happy.""" + def __init__(self, lines): + self._gen = (l for l in lines) + + def readline(self): + try: + try: + return next(self._gen) + except NameError: + return self._gen.next() + except StopIteration: + return '' + + def __iter__(self): + return self._gen + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +def captured_stderr(): + """ + See captured_stdout(). + """ + return captured_output('stderr') + + +class cached_property(object): + """A property that is only computed once per instance and then replaces + itself with an ordinary attribute. Deleting the attribute resets the + property. + + Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 + """ + + def __init__(self, func): + self.__doc__ = getattr(func, '__doc__') + self.func = func + + def __get__(self, obj, cls): + if obj is None: + # We're being accessed from the class itself, not from an object + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value + + +def get_installed_version(dist_name, working_set=None): + """Get the installed version of dist_name avoiding pkg_resources cache""" + # Create a requirement that we'll look for inside of setuptools. + req = pkg_resources.Requirement.parse(dist_name) + + if working_set is None: + # We want to avoid having this cached, so we need to construct a new + # working set each time. + working_set = pkg_resources.WorkingSet() + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +def consume(iterator): + """Consume an iterable at C speed.""" + deque(iterator, maxlen=0) + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) + + +def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): + """ + Return the URL for a VCS requirement. + + Args: + repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). + project_name: the (unescaped) project name. + """ + egg_project_name = pkg_resources.to_filename(project_name) + req = '{}@{}#egg={}'.format(repo_url, rev, egg_project_name) + if subdir: + req += '&subdirectory={}'.format(subdir) + + return req + + +def split_auth_from_netloc(netloc): + """ + Parse out and remove the auth information from a netloc. + + Returns: (netloc, (username, password)). + """ + if '@' not in netloc: + return netloc, (None, None) + + # Split from the right because that's how urllib.parse.urlsplit() + # behaves if more than one @ is present (which can be checked using + # the password attribute of urlsplit()'s return value). + auth, netloc = netloc.rsplit('@', 1) + if ':' in auth: + # Split from the left because that's how urllib.parse.urlsplit() + # behaves if more than one : is present (which again can be checked + # using the password attribute of the return value) + user_pass = auth.split(':', 1) + else: + user_pass = auth, None + + user_pass = tuple( + None if x is None else urllib_unquote(x) for x in user_pass + ) + + return netloc, user_pass + + +def redact_netloc(netloc): + # type: (str) -> str + """ + Replace the password in a netloc with "****", if it exists. + + For example, "user:pass@example.com" returns "user:****@example.com". + """ + netloc, (user, password) = split_auth_from_netloc(netloc) + if user is None: + return netloc + password = '' if password is None else ':****' + return '{user}{password}@{netloc}'.format(user=urllib_parse.quote(user), + password=password, + netloc=netloc) + + +def _transform_url(url, transform_netloc): + purl = urllib_parse.urlsplit(url) + netloc = transform_netloc(purl.netloc) + # stripped url + url_pieces = ( + purl.scheme, netloc, purl.path, purl.query, purl.fragment + ) + surl = urllib_parse.urlunsplit(url_pieces) + return surl + + +def _get_netloc(netloc): + return split_auth_from_netloc(netloc)[0] + + +def remove_auth_from_url(url): + # type: (str) -> str + # Return a copy of url with 'username:password@' removed. + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + return _transform_url(url, _get_netloc) + + +def redact_password_from_url(url): + # type: (str) -> str + """Replace the password in a given url with ****.""" + return _transform_url(url, redact_netloc) + + +def protect_pip_from_modification_on_windows(modifying_pip): + """Protection of pip.exe from modification on Windows + + On Windows, any operation modifying pip should be run as: + python -m pip ... + """ + pip_names = [ + "pip.exe", + "pip{}.exe".format(sys.version_info[0]), + "pip{}.{}.exe".format(*sys.version_info[:2]) + ] + + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + modifying_pip and + WINDOWS and + os.path.basename(sys.argv[0]) in pip_names + ) + + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/models.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/models.py new file mode 100755 index 0000000..d5cb80a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/models.py @@ -0,0 +1,40 @@ +"""Utilities for defining models +""" + +import operator + + +class KeyBasedCompareMixin(object): + """Provides comparision capabilities that is based on a key + """ + + def __init__(self, key, defining_class): + self._compare_key = key + self._defining_class = defining_class + + def __hash__(self): + return hash(self._compare_key) + + def __lt__(self, other): + return self._compare(other, operator.__lt__) + + def __le__(self, other): + return self._compare(other, operator.__le__) + + def __gt__(self, other): + return self._compare(other, operator.__gt__) + + def __ge__(self, other): + return self._compare(other, operator.__ge__) + + def __eq__(self, other): + return self._compare(other, operator.__eq__) + + def __ne__(self, other): + return self._compare(other, operator.__ne__) + + def _compare(self, other, method): + if not isinstance(other, self._defining_class): + return NotImplemented + + return method(self._compare_key, other._compare_key) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/outdated.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/outdated.py new file mode 100755 index 0000000..37c47a4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/outdated.py @@ -0,0 +1,164 @@ +from __future__ import absolute_import + +import datetime +import json +import logging +import os.path +import sys + +from pip._vendor import lockfile, pkg_resources +from pip._vendor.packaging import version as packaging_version + +from pip._internal.index import PackageFinder +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + import optparse # noqa: F401 + from typing import Any, Dict # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +class SelfCheckState(object): + def __init__(self, cache_dir): + # type: (str) -> None + self.state = {} # type: Dict[str, Any] + self.statefile_path = None + + # Try to load the existing state + if cache_dir: + self.statefile_path = os.path.join(cache_dir, "selfcheck.json") + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile)[sys.prefix] + except (IOError, ValueError, KeyError): + # Explicitly suppressing exceptions, since we don't want to + # error out if the cache file is invalid. + pass + + def save(self, pypi_version, current_time): + # type: (str, datetime.datetime) -> None + # If we do not have a path to cache in, don't bother saving. + if not self.statefile_path: + return + + # Check to make sure that we own the directory + if not check_path_owner(os.path.dirname(self.statefile_path)): + return + + # Now that we've ensured the directory is owned by this user, we'll go + # ahead and make sure that all our directories are created. + ensure_dir(os.path.dirname(self.statefile_path)) + + # Attempt to write out our version check file + with lockfile.LockFile(self.statefile_path): + if os.path.exists(self.statefile_path): + with open(self.statefile_path) as statefile: + state = json.load(statefile) + else: + state = {} + + state[sys.prefix] = { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + } + + with open(self.statefile_path, "w") as statefile: + json.dump(state, statefile, sort_keys=True, + separators=(",", ":")) + + +def was_installed_by_pip(pkg): + # type: (str) -> bool + """Checks whether pkg was installed by pip + + This is used not to display the upgrade message when pip is in fact + installed by system package manager, such as dnf on Fedora. + """ + try: + dist = pkg_resources.get_distribution(pkg) + return (dist.has_metadata('INSTALLER') and + 'pip' in dist.get_metadata_lines('INSTALLER')) + except pkg_resources.DistributionNotFound: + return False + + +def pip_version_check(session, options): + # type: (PipSession, optparse.Values) -> None + """Check for an update for pip. + + Limit the frequency of checks to once per week. State is stored either in + the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix + of the pip script path. + """ + installed_version = get_installed_version("pip") + if not installed_version: + return + + pip_version = packaging_version.parse(installed_version) + pypi_version = None + + try: + state = SelfCheckState(cache_dir=options.cache_dir) + + current_time = datetime.datetime.utcnow() + # Determine if we need to refresh the state + if "last_check" in state.state and "pypi_version" in state.state: + last_check = datetime.datetime.strptime( + state.state["last_check"], + SELFCHECK_DATE_FMT + ) + if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: + pypi_version = state.state["pypi_version"] + + # Refresh the version if we need to or just see if we need to warn + if pypi_version is None: + # Lets use PackageFinder to see what the latest pip version is + finder = PackageFinder( + find_links=options.find_links, + index_urls=[options.index_url] + options.extra_index_urls, + allow_all_prereleases=False, # Explicitly set to False + trusted_hosts=options.trusted_hosts, + session=session, + ) + all_candidates = finder.find_all_candidates("pip") + if not all_candidates: + return + pypi_version = str( + max(all_candidates, key=lambda c: c.version).version + ) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + # Determine if our pypi_version is older + if (pip_version < remote_version and + pip_version.base_version != remote_version.base_version and + was_installed_by_pip('pip')): + # Advise "python -m pip" on Windows to avoid issues + # with overwriting pip.exe. + if WINDOWS: + pip_cmd = "python -m pip" + else: + pip_cmd = "pip" + logger.warning( + "You are using pip version %s, however version %s is " + "available.\nYou should consider upgrading via the " + "'%s install --upgrade pip' command.", + pip_version, pypi_version, pip_cmd + ) + except Exception: + logger.debug( + "There was an error checking the latest version of pip", + exc_info=True, + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/packaging.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/packaging.py new file mode 100755 index 0000000..7aaf7b5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/packaging.py @@ -0,0 +1,85 @@ +from __future__ import absolute_import + +import logging +import sys +from email.parser import FeedParser + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal import exceptions +from pip._internal.utils.misc import display_path +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional # noqa: F401 + from email.message import Message # noqa: F401 + from pip._vendor.pkg_resources import Distribution # noqa: F401 + + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python): + # type: (Optional[str]) -> bool + """ + Check if the python version in use match the `requires_python` specifier. + + Returns `True` if the version of python in use matches the requirement. + Returns `False` if the version of python in use does not matches the + requirement. + + Raises an InvalidSpecifier if `requires_python` have an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + # We only use major.minor.micro + python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + # type: (Distribution) -> Message + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata('METADATA')): + metadata = dist.get_metadata('METADATA') + elif dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + else: + logger.warning("No metadata found in %s", display_path(dist.location)) + metadata = '' + + feed_parser = FeedParser() + feed_parser.feed(metadata) + return feed_parser.close() + + +def check_dist_requires_python(dist): + pkg_info_dict = get_metadata(dist) + requires_python = pkg_info_dict.get('Requires-Python') + try: + if not check_requires_python(requires_python): + raise exceptions.UnsupportedPythonVersion( + "%s requires Python '%s' but the running Python is %s" % ( + dist.project_name, + requires_python, + '.'.join(map(str, sys.version_info[:3])),) + ) + except specifiers.InvalidSpecifier as e: + logger.warning( + "Package %s has an invalid Requires-Python entry %s - %s", + dist.project_name, requires_python, e, + ) + return + + +def get_installer(dist): + # type: (Distribution) -> str + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/setuptools_build.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/setuptools_build.py new file mode 100755 index 0000000..03973e9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,8 @@ +# Shim to wrap setup.py invocation with setuptools +SETUPTOOLS_SHIM = ( + "import setuptools, tokenize;__file__=%r;" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/temp_dir.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/temp_dir.py new file mode 100755 index 0000000..2c81ad5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/temp_dir.py @@ -0,0 +1,155 @@ +from __future__ import absolute_import + +import errno +import itertools +import logging +import os.path +import tempfile + +from pip._internal.utils.misc import rmtree + +logger = logging.getLogger(__name__) + + +class TempDirectory(object): + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory or None + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + Methods: + create() + Creates a temporary directory and stores its path in the path + attribute. + cleanup() + Deletes the temporary directory and sets path attribute to None + + When used as a context manager, a temporary directory is created on + entering the context and, if the delete attribute is True, on exiting the + context the created directory is deleted. + """ + + def __init__(self, path=None, delete=None, kind="temp"): + super(TempDirectory, self).__init__() + + if path is None and delete is None: + # If we were not given an explicit directory, and we were not given + # an explicit delete option, then we'll default to deleting. + delete = True + + self.path = path + self.delete = delete + self.kind = kind + + def __repr__(self): + return "<{} {!r}>".format(self.__class__.__name__, self.path) + + def __enter__(self): + self.create() + return self + + def __exit__(self, exc, value, tb): + if self.delete: + self.cleanup() + + def create(self): + """Create a temporary directory and store its path in self.path + """ + if self.path is not None: + logger.debug( + "Skipped creation of temporary directory: {}".format(self.path) + ) + return + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + self.path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) + + def cleanup(self): + """Remove the temporary directory created and reset state + """ + if self.path is not None and os.path.exists(self.path): + rmtree(self.path) + self.path = None + + +class AdjacentTempDirectory(TempDirectory): + """Helper class that creates a temporary directory adjacent to a real one. + + Attributes: + original + The original directory to create a temp directory for. + path + After calling create() or entering, contains the full + path to the temporary directory. + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + """ + # The characters that may be used to name the temp directory + # We always prepend a ~ and then rotate through these until + # a usable name is found. + # pkg_resources raises a different error for .dist-info folder + # with leading '-' and invalid metadata + LEADING_CHARS = "-~.=%0123456789" + + def __init__(self, original, delete=None): + super(AdjacentTempDirectory, self).__init__(delete=delete) + self.original = original.rstrip('/\\') + + @classmethod + def _generate_names(cls, name): + """Generates a series of temporary names. + + The algorithm replaces the leading characters in the name + with ones that are valid filesystem characters, but are not + valid package names (for both Python and pip definitions of + package). + """ + for i in range(1, len(name)): + for candidate in itertools.combinations_with_replacement( + cls.LEADING_CHARS, i - 1): + new_name = '~' + ''.join(candidate) + name[i:] + if new_name != name: + yield new_name + + # If we make it this far, we will have to make a longer name + for i in range(len(cls.LEADING_CHARS)): + for candidate in itertools.combinations_with_replacement( + cls.LEADING_CHARS, i): + new_name = '~' + ''.join(candidate) + name + if new_name != name: + yield new_name + + def create(self): + root, name = os.path.split(self.original) + for candidate in self._generate_names(name): + path = os.path.join(root, candidate) + try: + os.mkdir(path) + except OSError as ex: + # Continue if the name exists already + if ex.errno != errno.EEXIST: + raise + else: + self.path = os.path.realpath(path) + break + + if not self.path: + # Final fallback on the default behavior. + self.path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/typing.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/typing.py new file mode 100755 index 0000000..e085cdf --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/typing.py @@ -0,0 +1,29 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip._internal.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... # noqa: F401 + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/ui.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/ui.py new file mode 100755 index 0000000..433675d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/utils/ui.py @@ -0,0 +1,441 @@ +from __future__ import absolute_import, division + +import contextlib +import itertools +import logging +import sys +import time +from signal import SIGINT, default_int_handler, signal + +from pip._vendor import six +from pip._vendor.progress.bar import ( + Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + ShadyBar, +) +from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin +from pip._vendor.progress.spinner import Spinner + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Iterator, IO # noqa: F401 + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + +logger = logging.getLogger(__name__) + + +def _select_progress_class(preferred, fallback): + encoding = getattr(preferred.file, "encoding", None) + + # If we don't know what encoding this file is in, then we'll just assume + # that it doesn't support unicode and use the ASCII bar. + if not encoding: + return fallback + + # Collect all of the possible characters we want to use with the preferred + # bar. + characters = [ + getattr(preferred, "empty_fill", six.text_type()), + getattr(preferred, "fill", six.text_type()), + ] + characters += list(getattr(preferred, "phases", [])) + + # Try to decode the characters we're using for the bar using the encoding + # of the given file, if this works then we'll assume that we can use the + # fancier bar and if not we'll fall back to the plaintext bar. + try: + six.text_type().join(characters).encode(encoding) + except UnicodeEncodeError: + return fallback + else: + return preferred + + +_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any + + +class InterruptibleMixin(object): + """ + Helper to ensure that self.finish() gets called on keyboard interrupt. + + This allows downloads to be interrupted without leaving temporary state + (like hidden cursors) behind. + + This class is similar to the progress library's existing SigIntMixin + helper, but as of version 1.2, that helper has the following problems: + + 1. It calls sys.exit(). + 2. It discards the existing SIGINT handler completely. + 3. It leaves its own handler in place even after an uninterrupted finish, + which will have unexpected delayed effects if the user triggers an + unrelated keyboard interrupt some time after a progress-displaying + download has already completed, for example. + """ + + def __init__(self, *args, **kwargs): + """ + Save the original SIGINT handler for later. + """ + super(InterruptibleMixin, self).__init__(*args, **kwargs) + + self.original_handler = signal(SIGINT, self.handle_sigint) + + # If signal() returns None, the previous handler was not installed from + # Python, and we cannot restore it. This probably should not happen, + # but if it does, we must restore something sensible instead, at least. + # The least bad option should be Python's default SIGINT handler, which + # just raises KeyboardInterrupt. + if self.original_handler is None: + self.original_handler = default_int_handler + + def finish(self): + """ + Restore the original SIGINT handler after finishing. + + This should happen regardless of whether the progress display finishes + normally, or gets interrupted. + """ + super(InterruptibleMixin, self).finish() + signal(SIGINT, self.original_handler) + + def handle_sigint(self, signum, frame): + """ + Call self.finish() before delegating to the original SIGINT handler. + + This handler should only be in place while the progress display is + active. + """ + self.finish() + self.original_handler(signum, frame) + + +class SilentBar(Bar): + + def update(self): + pass + + +class BlueEmojiBar(IncrementalBar): + + suffix = "%(percent)d%%" + bar_prefix = " " + bar_suffix = " " + phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any + + +class DownloadProgressMixin(object): + + def __init__(self, *args, **kwargs): + super(DownloadProgressMixin, self).__init__(*args, **kwargs) + self.message = (" " * (get_indentation() + 2)) + self.message + + @property + def downloaded(self): + return format_size(self.index) + + @property + def download_speed(self): + # Avoid zero division errors... + if self.avg == 0.0: + return "..." + return format_size(1 / self.avg) + "/s" + + @property + def pretty_eta(self): + if self.eta: + return "eta %s" % self.eta_td + return "" + + def iter(self, it, n=1): + for x in it: + yield x + self.next(n) + self.finish() + + +class WindowsMixin(object): + + def __init__(self, *args, **kwargs): + # The Windows terminal does not support the hide/show cursor ANSI codes + # even with colorama. So we'll ensure that hide_cursor is False on + # Windows. + # This call neds to go before the super() call, so that hide_cursor + # is set in time. The base progress bar class writes the "hide cursor" + # code to the terminal in its init, so if we don't set this soon + # enough, we get a "hide" with no corresponding "show"... + if WINDOWS and self.hide_cursor: + self.hide_cursor = False + + super(WindowsMixin, self).__init__(*args, **kwargs) + + # Check if we are running on Windows and we have the colorama module, + # if we do then wrap our file with it. + if WINDOWS and colorama: + self.file = colorama.AnsiToWin32(self.file) + # The progress code expects to be able to call self.file.isatty() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.isatty = lambda: self.file.wrapped.isatty() + # The progress code expects to be able to call self.file.flush() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.flush = lambda: self.file.wrapped.flush() + + +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin): + + file = sys.stdout + message = "%(percent)d%%" + suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + +# NOTE: The "type: ignore" comments on the following classes are there to +# work around https://github.com/python/typing/issues/241 + + +class DefaultDownloadProgressBar(BaseDownloadProgressBar, + _BaseBar): + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore + pass + + +class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore + IncrementalBar): + pass + + +class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore + ChargingBar): + pass + + +class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore + pass + + +class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore + FillingSquaresBar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, WritelnMixin, Spinner): + + file = sys.stdout + suffix = "%(downloaded)s %(download_speed)s" + + def next_phase(self): + if not hasattr(self, "_phaser"): + self._phaser = itertools.cycle(self.phases) + return next(self._phaser) + + def update(self): + message = self.message % self + phase = self.next_phase() + suffix = self.suffix % self + line = ''.join([ + message, + " " if message else "", + phase, + " " if suffix else "", + suffix, + ]) + + self.writeln(line) + + +BAR_TYPES = { + "off": (DownloadSilentBar, DownloadSilentBar), + "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), + "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), + "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) +} + + +def DownloadProgressProvider(progress_bar, max=None): + if max is None or max == 0: + return BAR_TYPES[progress_bar][1]().iter + else: + return BAR_TYPES[progress_bar][0](max=max).iter + + +################################################################ +# Generic "something is happening" spinners +# +# We don't even try using progress.spinner.Spinner here because it's actually +# simpler to reimplement from scratch than to coerce their code into doing +# what we need. +################################################################ + +@contextlib.contextmanager +def hidden_cursor(file): + # type: (IO) -> Iterator[None] + # The Windows terminal does not support the hide/show cursor ANSI codes, + # even via colorama. So don't even try. + if WINDOWS: + yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield + else: + file.write(HIDE_CURSOR) + try: + yield + finally: + file.write(SHOW_CURSOR) + + +class RateLimiter(object): + def __init__(self, min_update_interval_seconds): + # type: (float) -> None + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 # type: float + + def ready(self): + # type: () -> bool + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + # type: () -> None + self._last_update = time.time() + + +class SpinnerInterface(object): + def spin(self): + # type: () -> None + raise NotImplementedError() + + def finish(self, final_status): + # type: (str) -> None + raise NotImplementedError() + + +class InteractiveSpinner(SpinnerInterface): + def __init__(self, message, file=None, spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125): + self._message = message + if file is None: + file = sys.stdout + self._file = file + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._finished = False + + self._spin_cycle = itertools.cycle(spin_chars) + + self._file.write(" " * get_indentation() + self._message + " ... ") + self._width = 0 + + def _write(self, status): + assert not self._finished + # Erase what we wrote before by backspacing to the beginning, writing + # spaces to overwrite the old text, and then backspacing again + backup = "\b" * self._width + self._file.write(backup + " " * self._width + backup) + # Now we have a blank slate to add our status + self._file.write(status) + self._width = len(status) + self._file.flush() + self._rate_limiter.reset() + + def spin(self): + # type: () -> None + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + # type: (str) -> None + if self._finished: + return + self._write(final_status) + self._file.write("\n") + self._file.flush() + self._finished = True + + +# Used for dumb terminals, non-interactive installs (no tty), etc. +# We still print updates occasionally (once every 60 seconds by default) to +# act as a keep-alive for systems like Travis-CI that take lack-of-output as +# an indication that a task has frozen. +class NonInteractiveSpinner(SpinnerInterface): + def __init__(self, message, min_update_interval_seconds=60): + # type: (str, float) -> None + self._message = message + self._finished = False + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._update("started") + + def _update(self, status): + assert not self._finished + self._rate_limiter.reset() + logger.info("%s: %s", self._message, status) + + def spin(self): + # type: () -> None + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + # type: (str) -> None + if self._finished: + return + self._update("finished with status '%s'" % (final_status,)) + self._finished = True + + +@contextlib.contextmanager +def open_spinner(message): + # type: (str) -> Iterator[SpinnerInterface] + # Interactive spinner goes directly to sys.stdout rather than being routed + # through the logging system, but it acts like it has level INFO, + # i.e. it's only displayed if we're at level INFO or better. + # Non-interactive spinner goes through the logging system, so it is always + # in sync with logging configuration. + if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: + spinner = InteractiveSpinner(message) # type: SpinnerInterface + else: + spinner = NonInteractiveSpinner(message) + try: + with hidden_cursor(sys.stdout): + yield spinner + except KeyboardInterrupt: + spinner.finish("canceled") + raise + except Exception: + spinner.finish("error") + raise + else: + spinner.finish("done") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/__init__.py new file mode 100755 index 0000000..9cba764 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/__init__.py @@ -0,0 +1,534 @@ +"""Handles all VCS (version control) support""" +from __future__ import absolute_import + +import errno +import logging +import os +import shutil +import sys + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import ( + display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Any, Dict, Iterable, List, Mapping, Optional, Text, Tuple, Type + ) + from pip._internal.utils.ui import SpinnerInterface # noqa: F401 + + AuthInfo = Tuple[Optional[str], Optional[str]] + +__all__ = ['vcs'] + + +logger = logging.getLogger(__name__) + + +class RemoteNotFoundError(Exception): + pass + + +class RevOptions(object): + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__(self, vcs, rev=None, extra_args=None): + # type: (VersionControl, Optional[str], Optional[List[str]]) -> None + """ + Args: + vcs: a VersionControl object. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vcs = vcs + + def __repr__(self): + return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) + + @property + def arg_rev(self): + # type: () -> Optional[str] + if self.rev is None: + return self.vcs.default_arg_rev + + return self.rev + + def to_args(self): + # type: () -> List[str] + """ + Return the VCS-specific command arguments. + """ + args = [] # type: List[str] + rev = self.arg_rev + if rev is not None: + args += self.vcs.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + # type: () -> str + if not self.rev: + return '' + + return ' (to revision {})'.format(self.rev) + + def make_new(self, rev): + # type: (str) -> RevOptions + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vcs.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport(object): + _registry = {} # type: Dict[str, Type[VersionControl]] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # type: () -> None + # Register more schemes with urlparse for various version control + # systems + urllib_parse.uses_netloc.extend(self.schemes) + # Python >= 2.7.4, 3.3 doesn't have uses_fragment + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + # type: () -> List[Type[VersionControl]] + return list(self._registry.values()) + + @property + def dirnames(self): + # type: () -> List[str] + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + # type: () -> List[str] + schemes = [] # type: List[str] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + # type: (Type[VersionControl]) -> None + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, cls=None, name=None): + # type: (Optional[Type[VersionControl]], Optional[str]) -> None + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warning('Cannot unregister because no class or name given') + + def get_backend_type(self, location): + # type: (str) -> Optional[Type[VersionControl]] + """ + Return the type of the version control backend if found at given + location, e.g. vcs.get_backend_type('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + if vc_type.controls_location(location): + logger.debug('Determine that %s uses VCS: %s', + location, vc_type.name) + return vc_type + return None + + def get_backend(self, name): + # type: (str) -> Optional[Type[VersionControl]] + name = name.lower() + if name in self._registry: + return self._registry[name] + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + repo_name = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + def __init__(self, url=None, *args, **kwargs): + self.url = url + super(VersionControl, self).__init__(*args, **kwargs) + + def get_base_rev_args(self, rev): + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def make_rev_options(self, rev=None, extra_args=None): + # type: (Optional[str], Optional[List[str]]) -> RevOptions + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(self, rev, extra_args=extra_args) + + @classmethod + def _is_local_repository(cls, repo): + # type: (str) -> bool + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or bool(drive) + + def export(self, location): + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + """ + raise NotImplementedError + + def get_netloc_and_auth(self, netloc, scheme): + """ + Parse the repository URL's netloc, and return the new netloc to use + along with auth information. + + Args: + netloc: the original repository URL netloc. + scheme: the repository URL's scheme without the vcs prefix. + + This is mainly for the Subversion class to override, so that auth + information can be provided via the --username and --password options + instead of through the URL. For other subclasses like Git without + such an option, auth information must stay in the URL. + + Returns: (netloc, (username, password)). + """ + return netloc, (None, None) + + def get_url_rev_and_auth(self, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] + """ + Parse the repository URL to use, and return the URL, revision, + and auth info to use. + + Returns: (url, rev, (username, password)). + """ + scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) + if '+' not in scheme: + raise ValueError( + "Sorry, {!r} is a malformed VCS url. " + "The format is <vcs>+<protocol>://<url>, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) + ) + # Remove the vcs prefix. + scheme = scheme.split('+', 1)[1] + netloc, user_pass = self.get_netloc_and_auth(netloc, scheme) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev, user_pass + + def make_rev_args(self, username, password): + """ + Return the RevOptions "extra arguments" to use in obtain(). + """ + return [] + + def get_url_rev_options(self, url): + # type: (str) -> Tuple[str, RevOptions] + """ + Return the URL and RevOptions object to use in obtain() and in + some cases export(), as a tuple (url, rev_options). + """ + url, rev, user_pass = self.get_url_rev_and_auth(url) + username, password = user_pass + extra_args = self.make_rev_args(username, password) + rev_options = self.make_rev_options(rev, extra_args=extra_args) + + return url, rev_options + + def normalize_url(self, url): + # type: (str) -> str + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib_parse.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + # type: (str, str) -> bool + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def fetch_new(self, dest, url, rev_options): + """ + Fetch a revision from a repository, in the case that this is the + first fetch from the repository. + + Args: + dest: the directory to fetch the repository to. + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, url, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def is_commit_id_equal(self, dest, name): + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def obtain(self, dest): + # type: (str) -> None + """ + Install or update in editable mode the package represented by this + VersionControl object. + + Args: + dest: the repository directory in which to install or update. + """ + url, rev_options = self.get_url_rev_options(self.url) + + if not os.path.exists(dest): + self.fetch_new(dest, url, rev_options) + return + + rev_display = rev_options.to_display() + if self.is_repository_directory(dest): + existing_url = self.get_remote_url(dest) + if self.compare_urls(existing_url, url): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, url, rev_options) + else: + logger.info('Skipping because already up-to-date.') + return + + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + # https://github.com/python/mypy/issues/1174 + prompt = ('(i)gnore, (w)ipe, (b)ackup ', # type: ignore + ('i', 'w', 'b')) + + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) + + if response == 'a': + sys.exit(-1) + + if response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + self.fetch_new(dest, url, rev_options) + return + + if response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + self.fetch_new(dest, url, rev_options) + return + + # Do nothing if the response is "i". + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + + def unpack(self, location): + # type: (str) -> None + """ + Clean up current location and download the url repository + (and vcs infos) into location + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location) + + @classmethod + def get_src_requirement(cls, location, project_name): + """ + Return a string representing the requirement needed to + redownload the files currently present in location, something + like: + {repository_url}@{revision}#egg={project_name}-{version_identifier} + """ + raise NotImplementedError + + @classmethod + def get_remote_url(cls, location): + """ + Return the url used at location + + Raises RemoteNotFoundError if the repository does not have a remote + url configured. + """ + raise NotImplementedError + + @classmethod + def get_revision(cls, location): + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + @classmethod + def run_command( + cls, + cmd, # type: List[str] + show_stdout=True, # type: bool + cwd=None, # type: Optional[str] + on_returncode='raise', # type: str + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + command_desc=None, # type: Optional[str] + extra_environ=None, # type: Optional[Mapping[str, Any]] + spinner=None # type: Optional[SpinnerInterface] + ): + # type: (...) -> Optional[Text] + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = [cls.name] + cmd + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode=on_returncode, + extra_ok_returncodes=extra_ok_returncodes, + command_desc=command_desc, + extra_environ=extra_environ, + unset_environ=cls.unset_environ, + spinner=spinner) + except OSError as e: + # errno.ENOENT = no such file or directory + # In other words, the VCS executable isn't available + if e.errno == errno.ENOENT: + raise BadCommand( + 'Cannot find command %r - do you have ' + '%r installed and in your ' + 'PATH?' % (cls.name, cls.name)) + else: + raise # re-raise exception if a different error occurred + + @classmethod + def is_repository_directory(cls, path): + # type: (str) -> bool + """ + Return whether a directory path is a repository directory. + """ + logger.debug('Checking in %s for %s (%s)...', + path, cls.dirname, cls.name) + return os.path.exists(os.path.join(path, cls.dirname)) + + @classmethod + def controls_location(cls, location): + # type: (str) -> bool + """ + Check if a location is controlled by the vcs. + It is meant to be overridden to implement smarter detection + mechanisms for specific vcs. + + This can do more than is_repository_directory() alone. For example, + the Git override checks that Git is actually available. + """ + return cls.is_repository_directory(location) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/bazaar.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/bazaar.py new file mode 100755 index 0000000..4c6ac79 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/bazaar.py @@ -0,0 +1,114 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', + ) + + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + # This is only needed for python <2.7.5 + # Register lp but do not expose as a scheme to support bzr+lp. + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(['lp']) + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['export', location], + cwd=temp_dir.path, show_stdout=False, + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + self.run_command(['switch', url], cwd=dest) + + def update(self, dest, url, rev_options): + cmd_args = ['pull', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev, user_pass = super(Bazaar, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev, user_pass + + @classmethod + def get_remote_url(cls, location): + urls = cls.run_command(['info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if cls._is_local_repository(repo): + return path_to_url(repo) + return repo + return None + + @classmethod + def get_revision(cls, location): + revision = cls.run_command( + ['revno'], show_stdout=False, cwd=location, + ) + return revision.splitlines()[-1] + + @classmethod + def get_src_requirement(cls, location, project_name): + repo = cls.get_remote_url(location) + if not repo: + return None + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + current_rev = cls.get_revision(location) + return make_vcs_requirement_url(repo, current_rev, project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/git.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/git.py new file mode 100755 index 0000000..dd2bd61 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/git.py @@ -0,0 +1,369 @@ +from __future__ import absolute_import + +import logging +import os.path +import re + +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.compat import samefile +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, redact_password_from_url, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import RemoteNotFoundError, VersionControl, vcs + +urlsplit = urllib_parse.urlsplit +urlunsplit = urllib_parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('[a-fA-F0-9]{40}') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see https://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib_request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + super(Git, self).__init__(url, *args, **kwargs) + + def get_base_rev_args(self, rev): + return [rev] + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command(['version'], show_stdout=False) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version becasue + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + def get_current_branch(self, location): + """ + Return the current branch, or None if HEAD isn't at a branch + (e.g. detached HEAD). + """ + # git-symbolic-ref exits with empty stdout if "HEAD" is a detached + # HEAD rather than a symbolic ref. In addition, the -q causes the + # command to exit with status code 1 instead of 128 in this case + # and to suppress the message to stderr. + args = ['symbolic-ref', '-q', 'HEAD'] + output = self.run_command( + args, extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, + ) + ref = output.strip() + + if ref.startswith('refs/heads/'): + return ref[len('refs/heads/'):] + + return None + + def export(self, location): + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + def get_revision_sha(self, dest, rev): + """ + Return (sha_or_none, is_branch), where sha_or_none is a commit hash + if the revision names a remote branch or tag, otherwise None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = self.run_command(['show-ref', rev], cwd=dest, + show_stdout=False, on_returncode='ignore') + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError('unexpected show-ref line: {!r}'.format(line)) + + refs[ref] = sha + + branch_ref = 'refs/remotes/origin/{}'.format(rev) + tag_ref = 'refs/tags/{}'.format(rev) + + sha = refs.get(branch_ref) + if sha is not None: + return (sha, True) + + sha = refs.get(tag_ref) + + return (sha, False) + + def resolve_revision(self, dest, url, rev_options): + """ + Resolve a revision to a new RevOptions object with the SHA1 of the + branch, tag, or ref if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + sha, is_branch = self.get_revision_sha(dest, rev) + + if sha is not None: + rev_options = rev_options.make_new(sha) + rev_options.branch_name = rev if is_branch else None + + return rev_options + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + + if not rev.startswith('refs/'): + return rev_options + + # If it looks like a ref, we have to fetch it explicitly. + self.run_command( + ['fetch', '-q', url] + rev_options.to_args(), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + sha = self.get_revision(dest, rev='FETCH_HEAD') + rev_options = rev_options.make_new(sha) + + return rev_options + + def is_commit_id_equal(self, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return self.get_revision(dest) == name + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning %s%s to %s', redact_password_from_url(url), + rev_display, display_path(dest), + ) + self.run_command(['clone', '-q', url, dest]) + + if rev_options.rev: + # Then a specific revision was requested. + rev_options = self.resolve_revision(dest, url, rev_options) + branch_name = getattr(rev_options, 'branch_name', None) + if branch_name is None: + # Only do a checkout if the current commit id doesn't match + # the requested revision. + if not self.is_commit_id_equal(dest, rev_options.rev): + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + elif self.get_current_branch(dest) != branch_name: + # Then a specific branch was requested, and that branch + # is not yet checked out. + track_branch = 'origin/{}'.format(branch_name) + cmd_args = [ + 'checkout', '-b', branch_name, '--track', track_branch, + ] + self.run_command(cmd_args, cwd=dest) + + #: repo may contain submodules + self.update_submodules(dest) + + def switch(self, dest, url, rev_options): + self.run_command(['config', 'remote.origin.url', url], cwd=dest) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, url, rev_options): + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + self.run_command(['fetch', '-q'], cwd=dest) + # Then reset to wanted revision (maybe even origin/master) + rev_options = self.resolve_revision(dest, url, rev_options) + cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + @classmethod + def get_remote_url(cls, location): + """ + Return URL of the first remote encountered. + + Raises RemoteNotFoundError if the repository does not have a remote + url configured. + """ + # We need to pass 1 for extra_ok_returncodes since the command + # exits with return code 1 if there are no matching lines. + stdout = cls.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, + ) + remotes = stdout.splitlines() + try: + found_remote = remotes[0] + except IndexError: + raise RemoteNotFoundError + + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + @classmethod + def get_revision(cls, location, rev=None): + if rev is None: + rev = 'HEAD' + current_rev = cls.run_command( + ['rev-parse', rev], show_stdout=False, cwd=location, + ) + return current_rev.strip() + + @classmethod + def _get_subdirectory(cls, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = cls.run_command(['rev-parse', '--git-dir'], + show_stdout=False, cwd=location).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + root_dir = os.path.join(git_dir, '..') + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + # relative path of setup.py to repo root + if samefile(root_dir, location): + return None + return os.path.relpath(location, root_dir) + + @classmethod + def get_src_requirement(cls, location, project_name): + repo = cls.get_remote_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + current_rev = cls.get_revision(location) + subdir = cls._get_subdirectory(location) + req = make_vcs_requirement_url(repo, current_rev, project_name, + subdir=subdir) + + return req + + def get_url_rev_and_auth(self, url): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes don't + work with a ssh:// scheme (e.g. GitHub). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if '://' not in url: + assert 'file:' not in url + url = url.replace('git+', 'git+ssh://') + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + url = url.replace('ssh://', '') + else: + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + + return url, rev, user_pass + + def update_submodules(self, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + self.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def controls_location(cls, location): + if super(Git, cls).controls_location(location): + return True + try: + r = cls.run_command(['rev-parse'], + cwd=location, + show_stdout=False, + on_returncode='ignore') + return not r + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return False + + +vcs.register(Git) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/mercurial.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/mercurial.py new file mode 100755 index 0000000..26e75de --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/mercurial.py @@ -0,0 +1,103 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves import configparser + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path, make_vcs_requirement_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + + def get_base_rev_args(self, rev): + return [rev] + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + rev_display, + display_path(dest), + ) + self.run_command(['clone', '--noupdate', '-q', url, dest]) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, url, rev_options): + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + @classmethod + def get_remote_url(cls, location): + url = cls.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if cls._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + @classmethod + def get_revision(cls, location): + current_revision = cls.run_command( + ['parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + @classmethod + def get_revision_hash(cls, location): + current_rev_hash = cls.run_command( + ['parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + @classmethod + def get_src_requirement(cls, location, project_name): + repo = cls.get_remote_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + current_rev_hash = cls.get_revision_hash(location) + return make_vcs_requirement_url(repo, current_rev_hash, project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Mercurial) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/subversion.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/subversion.py new file mode 100755 index 0000000..42ac5ac --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/vcs/subversion.py @@ -0,0 +1,200 @@ +from __future__ import absolute_import + +import logging +import os +import re + +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, split_auth_from_netloc, +) +from pip._internal.vcs import VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev_options = self.get_url_rev_options(self.url) + + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # Subversion doesn't like to check out over an existing + # directory --force fixes this, but was only added in svn 1.5 + rmtree(location) + cmd_args = ['export'] + rev_options.to_args() + [url, location] + self.run_command(cmd_args, show_stdout=False) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + cmd_args = ['switch'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def update(self, dest, url, rev_options): + cmd_args = ['update'] + rev_options.to_args() + [dest] + self.run_command(cmd_args) + + @classmethod + def get_revision(cls, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if cls.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(cls.dirname) + entries_fn = os.path.join(base, cls.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = cls._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_netloc_and_auth(self, netloc, scheme): + """ + This override allows the auth information to be passed to svn via the + --username and --password options instead of via the URL. + """ + if scheme == 'ssh': + # The --username and --password options can't be used for + # svn+ssh URLs, so keep the auth information in the URL. + return super(Subversion, self).get_netloc_and_auth( + netloc, scheme) + + return split_auth_from_netloc(netloc) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev, user_pass = super(Subversion, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev, user_pass + + def make_rev_args(self, username, password): + extra_args = [] + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return extra_args + + @classmethod + def get_remote_url(cls, location): + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + return cls._get_svn_url_rev(location)[0] + + @classmethod + def _get_svn_url_rev(cls, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, cls.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] + else: + try: + # subversion >= 1.7 + xml = cls.run_command( + ['info', '--xml', location], + show_stdout=False, + ) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [ + int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) + ] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + @classmethod + def get_src_requirement(cls, location, project_name): + repo = cls.get_remote_url(location) + if repo is None: + return None + repo = 'svn+' + repo + rev = cls.get_revision(location) + return make_vcs_requirement_url(repo, rev, project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Subversion) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/wheel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/wheel.py new file mode 100755 index 0000000..67bcc7f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_internal/wheel.py @@ -0,0 +1,1095 @@ +""" +Support for installing and building the "wheel" binary package format. +""" +from __future__ import absolute_import + +import collections +import compileall +import csv +import hashlib +import logging +import os.path +import re +import shutil +import stat +import sys +import warnings +from base64 import urlsafe_b64encode +from email.parser import Parser + +from pip._vendor import pkg_resources +from pip._vendor.distlib.scripts import ScriptMaker +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.six import StringIO + +from pip._internal import pep425tags +from pip._internal.download import path_to_url, unpack_url +from pip._internal.exceptions import ( + InstallationError, InvalidWheelFilename, UnsupportedWheel, +) +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, distutils_scheme, +) +from pip._internal.models.link import Link +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, captured_stdout, ensure_dir, read_chunks, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Dict, List, Optional, Sequence, Mapping, Tuple, IO, Text, Any, + Union, Iterable + ) + from pip._vendor.packaging.requirements import Requirement # noqa: F401 + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from pip._internal.download import PipSession # noqa: F401 + from pip._internal.index import FormatControl, PackageFinder # noqa: F401 + from pip._internal.operations.prepare import ( # noqa: F401 + RequirementPreparer + ) + from pip._internal.cache import WheelCache # noqa: F401 + from pip._internal.pep425tags import Pep425Tag # noqa: F401 + + InstalledCSVRow = Tuple[str, ...] + + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +def normpath(src, p): + return os.path.relpath(src, p).replace(os.path.sep, '/') + + +def rehash(path, blocksize=1 << 20): + # type: (str, int) -> Tuple[str, str] + """Return (hash, length) for path using hashlib.sha256()""" + h = hashlib.sha256() + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + # unicode/str python2 issues + return (digest, str(length)) # type: ignore + + +def open_for_csv(name, mode): + # type: (str, Text) -> IO + if sys.version_info[0] < 3: + nl = {} # type: Dict[str, Any] + bin = 'b' + else: + nl = {'newline': ''} # type: Dict[str, Any] + bin = '' + return open(name, mode + bin, **nl) + + +def replace_python_tag(wheelname, new_tag): + # type: (str, str) -> str + """Replace the Python tag in a wheel file name with a new value. + """ + parts = wheelname.split('-') + parts[-3] = new_tag + return '-'.join(parts) + + +def fix_script(path): + # type: (str) -> Optional[bool] + """Replace #!python with #!/path/to/python + Return True if file was changed.""" + # XXX RECORD hashes will need to be updated + if os.path.isfile(path): + with open(path, 'rb') as script: + firstline = script.readline() + if not firstline.startswith(b'#!python'): + return False + exename = sys.executable.encode(sys.getfilesystemencoding()) + firstline = b'#!' + exename + os.linesep.encode("ascii") + rest = script.read() + with open(path, 'wb') as script: + script.write(firstline) + script.write(rest) + return True + return None + + +dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", re.VERBOSE) + + +def root_is_purelib(name, wheeldir): + # type: (str, str) -> bool + """ + Return True if the extracted wheel in wheeldir should go into purelib. + """ + name_folded = name.replace("-", "_") + for item in os.listdir(wheeldir): + match = dist_info_re.match(item) + if match and match.group('name') == name_folded: + with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: + for line in wheel: + line = line.lower().rstrip() + if line == "root-is-purelib: true": + return True + return False + + +def get_entrypoints(filename): + # type: (str) -> Tuple[Dict[str, str], Dict[str, str]] + if not os.path.exists(filename): + return {}, {} + + # This is done because you can pass a string to entry_points wrappers which + # means that they may or may not be valid INI files. The attempt here is to + # strip leading and trailing whitespace in order to make them valid INI + # files. + with open(filename) as fp: + data = StringIO() + for line in fp: + data.write(line.strip()) + data.write("\n") + data.seek(0) + + # get the entry points and then the script names + entry_points = pkg_resources.EntryPoint.parse_map(data) + console = entry_points.get('console_scripts', {}) + gui = entry_points.get('gui_scripts', {}) + + def _split_ep(s): + """get the string representation of EntryPoint, remove space and split + on '='""" + return str(s).replace(" ", "").split("=") + + # convert the EntryPoint objects into strings with module:function + console = dict(_split_ep(v) for v in console.values()) + gui = dict(_split_ep(v) for v in gui.values()) + return console, gui + + +def message_about_scripts_not_on_PATH(scripts): + # type: (Sequence[str]) -> Optional[str] + """Determine if any scripts are not on PATH and format a warning. + + Returns a warning message if one or more scripts are not on PATH, + otherwise None. + """ + if not scripts: + return None + + # Group scripts by the path they were installed in + grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] + for destfile in scripts: + parent_dir = os.path.dirname(destfile) + script_name = os.path.basename(destfile) + grouped_by_dir[parent_dir].add(script_name) + + # We don't want to warn for directories that are on PATH. + not_warn_dirs = [ + os.path.normcase(i).rstrip(os.sep) for i in + os.environ.get("PATH", "").split(os.pathsep) + ] + # If an executable sits with sys.executable, we don't warn for it. + # This covers the case of venv invocations without activating the venv. + not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + warn_for = { + parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + if os.path.normcase(parent_dir) not in not_warn_dirs + } + if not warn_for: + return None + + # Format a message + msg_lines = [] + for parent_dir, scripts in warn_for.items(): + scripts = sorted(scripts) + if len(scripts) == 1: + start_text = "script {} is".format(scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(scripts[:-1]) + " and " + scripts[-1] + ) + + msg_lines.append( + "The {} installed in '{}' which is not on PATH." + .format(start_text, parent_dir) + ) + + last_line_fmt = ( + "Consider adding {} to PATH or, if you prefer " + "to suppress this warning, use --no-warn-script-location." + ) + if len(msg_lines) == 1: + msg_lines.append(last_line_fmt.format("this directory")) + else: + msg_lines.append(last_line_fmt.format("these directories")) + + # Returns the formatted multiline message + return "\n".join(msg_lines) + + +def sorted_outrows(outrows): + # type: (Iterable[InstalledCSVRow]) -> List[InstalledCSVRow] + """ + Return the given rows of a RECORD file in sorted order. + + Each row is a 3-tuple (path, hash, size) and corresponds to a record of + a RECORD file (see PEP 376 and PEP 427 for details). For the rows + passed to this function, the size can be an integer as an int or string, + or the empty string. + """ + # Normally, there should only be one row per path, in which case the + # second and third elements don't come into play when sorting. + # However, in cases in the wild where a path might happen to occur twice, + # we don't want the sort operation to trigger an error (but still want + # determinism). Since the third element can be an int or string, we + # coerce each element to a string to avoid a TypeError in this case. + # For additional background, see-- + # https://github.com/pypa/pip/issues/5868 + return sorted(outrows, key=lambda row: tuple(str(x) for x in row)) + + +def get_csv_rows_for_installed( + old_csv_rows, # type: Iterable[List[str]] + installed, # type: Dict[str, str] + changed, # type: set + generated, # type: List[str] + lib_dir, # type: str +): + # type: (...) -> List[InstalledCSVRow] + """ + :param installed: A map from archive RECORD path to installation RECORD + path. + """ + installed_rows = [] # type: List[InstalledCSVRow] + for row in old_csv_rows: + if len(row) > 3: + logger.warning( + 'RECORD line has more than three elements: {}'.format(row) + ) + # Make a copy because we are mutating the row. + row = list(row) + old_path = row[0] + new_path = installed.pop(old_path, old_path) + row[0] = new_path + if new_path in changed: + digest, length = rehash(new_path) + row[1] = digest + row[2] = length + installed_rows.append(tuple(row)) + for f in generated: + digest, length = rehash(f) + installed_rows.append((normpath(f, lib_dir), digest, str(length))) + for f in installed: + installed_rows.append((installed[f], '', '')) + return installed_rows + + +def move_wheel_files( + name, # type: str + req, # type: Requirement + wheeldir, # type: str + user=False, # type: bool + home=None, # type: Optional[str] + root=None, # type: Optional[str] + pycompile=True, # type: bool + scheme=None, # type: Optional[Mapping[str, str]] + isolated=False, # type: bool + prefix=None, # type: Optional[str] + warn_script_location=True # type: bool +): + # type: (...) -> None + """Install a wheel""" + # TODO: Investigate and break this up. + # TODO: Look into moving this into a dedicated class for representing an + # installation. + + if not scheme: + scheme = distutils_scheme( + name, user=user, home=home, root=root, isolated=isolated, + prefix=prefix, + ) + + if root_is_purelib(name, wheeldir): + lib_dir = scheme['purelib'] + else: + lib_dir = scheme['platlib'] + + info_dir = [] # type: List[str] + data_dirs = [] + source = wheeldir.rstrip(os.path.sep) + os.path.sep + + # Record details of the files moved + # installed = files copied from the wheel to the destination + # changed = files changed while installing (scripts #! line typically) + # generated = files newly generated during the install (script wrappers) + installed = {} # type: Dict[str, str] + changed = set() + generated = [] # type: List[str] + + # Compile all of the pyc files that we're going to be installing + if pycompile: + with captured_stdout() as stdout: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + compileall.compile_dir(source, force=True, quiet=True) + logger.debug(stdout.getvalue()) + + def record_installed(srcfile, destfile, modified=False): + """Map archive RECORD paths to installation RECORD paths.""" + oldpath = normpath(srcfile, wheeldir) + newpath = normpath(destfile, lib_dir) + installed[oldpath] = newpath + if modified: + changed.add(destfile) + + def clobber(source, dest, is_base, fixer=None, filter=None): + ensure_dir(dest) # common for the 'include' path + + for dir, subdirs, files in os.walk(source): + basedir = dir[len(source):].lstrip(os.path.sep) + destdir = os.path.join(dest, basedir) + if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): + continue + for s in subdirs: + destsubdir = os.path.join(dest, basedir, s) + if is_base and basedir == '' and destsubdir.endswith('.data'): + data_dirs.append(s) + continue + elif (is_base and + s.endswith('.dist-info') and + canonicalize_name(s).startswith( + canonicalize_name(req.name))): + assert not info_dir, ('Multiple .dist-info directories: ' + + destsubdir + ', ' + + ', '.join(info_dir)) + info_dir.append(destsubdir) + for f in files: + # Skip unwanted files + if filter and filter(f): + continue + srcfile = os.path.join(dir, f) + destfile = os.path.join(dest, basedir, f) + # directory creation is lazy and after the file filtering above + # to ensure we don't install empty dirs; empty dirs can't be + # uninstalled. + ensure_dir(destdir) + + # copyfile (called below) truncates the destination if it + # exists and then writes the new contents. This is fine in most + # cases, but can cause a segfault if pip has loaded a shared + # object (e.g. from pyopenssl through its vendored urllib3) + # Since the shared object is mmap'd an attempt to call a + # symbol in it will then cause a segfault. Unlinking the file + # allows writing of new contents while allowing the process to + # continue to use the old copy. + if os.path.exists(destfile): + os.unlink(destfile) + + # We use copyfile (not move, copy, or copy2) to be extra sure + # that we are not moving directories over (copyfile fails for + # directories) as well as to ensure that we are not copying + # over any metadata because we want more control over what + # metadata we actually copy over. + shutil.copyfile(srcfile, destfile) + + # Copy over the metadata for the file, currently this only + # includes the atime and mtime. + st = os.stat(srcfile) + if hasattr(os, "utime"): + os.utime(destfile, (st.st_atime, st.st_mtime)) + + # If our file is executable, then make our destination file + # executable. + if os.access(srcfile, os.X_OK): + st = os.stat(srcfile) + permissions = ( + st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + ) + os.chmod(destfile, permissions) + + changed = False + if fixer: + changed = fixer(destfile) + record_installed(srcfile, destfile, changed) + + clobber(source, lib_dir, True) + + assert info_dir, "%s .dist-info directory not found" % req + + # Get the defined entry points + ep_file = os.path.join(info_dir[0], 'entry_points.txt') + console, gui = get_entrypoints(ep_file) + + def is_entrypoint_wrapper(name): + # EP, EP.exe and EP-script.py are scripts generated for + # entry point EP by setuptools + if name.lower().endswith('.exe'): + matchname = name[:-4] + elif name.lower().endswith('-script.py'): + matchname = name[:-10] + elif name.lower().endswith(".pya"): + matchname = name[:-4] + else: + matchname = name + # Ignore setuptools-generated scripts + return (matchname in console or matchname in gui) + + for datadir in data_dirs: + fixer = None + filter = None + for subdir in os.listdir(os.path.join(wheeldir, datadir)): + fixer = None + if subdir == 'scripts': + fixer = fix_script + filter = is_entrypoint_wrapper + source = os.path.join(wheeldir, datadir, subdir) + dest = scheme[subdir] + clobber(source, dest, False, fixer=fixer, filter=filter) + + maker = ScriptMaker(None, scheme['scripts']) + + # Ensure old scripts are overwritten. + # See https://github.com/pypa/pip/issues/1800 + maker.clobber = True + + # Ensure we don't generate any variants for scripts because this is almost + # never what somebody wants. + # See https://bitbucket.org/pypa/distlib/issue/35/ + maker.variants = {''} + + # This is required because otherwise distlib creates scripts that are not + # executable. + # See https://bitbucket.org/pypa/distlib/issue/32/ + maker.set_mode = True + + # Simplify the script and fix the fact that the default script swallows + # every single stack trace. + # See https://bitbucket.org/pypa/distlib/issue/34/ + # See https://bitbucket.org/pypa/distlib/issue/33/ + def _get_script_text(entry): + if entry.suffix is None: + raise InstallationError( + "Invalid script entry point: %s for req: %s - A callable " + "suffix is required. Cf https://packaging.python.org/en/" + "latest/distributing.html#console-scripts for more " + "information." % (entry, req) + ) + return maker.script_template % { + "module": entry.prefix, + "import_name": entry.suffix.split(".")[0], + "func": entry.suffix, + } + # ignore type, because mypy disallows assigning to a method, + # see https://github.com/python/mypy/issues/2427 + maker._get_script_text = _get_script_text # type: ignore + maker.script_template = r"""# -*- coding: utf-8 -*- +import re +import sys + +from %(module)s import %(import_name)s + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(%(func)s()) +""" + + # Special case pip and setuptools to generate versioned wrappers + # + # The issue is that some projects (specifically, pip and setuptools) use + # code in setup.py to create "versioned" entry points - pip2.7 on Python + # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into + # the wheel metadata at build time, and so if the wheel is installed with + # a *different* version of Python the entry points will be wrong. The + # correct fix for this is to enhance the metadata to be able to describe + # such versioned entry points, but that won't happen till Metadata 2.0 is + # available. + # In the meantime, projects using versioned entry points will either have + # incorrect versioned entry points, or they will not be able to distribute + # "universal" wheels (i.e., they will need a wheel per Python version). + # + # Because setuptools and pip are bundled with _ensurepip and virtualenv, + # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we + # override the versioned entry points in the wheel and generate the + # correct ones. This code is purely a short-term measure until Metadata 2.0 + # is available. + # + # To add the level of hack in this section of code, in order to support + # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment + # variable which will control which version scripts get installed. + # + # ENSUREPIP_OPTIONS=altinstall + # - Only pipX.Y and easy_install-X.Y will be generated and installed + # ENSUREPIP_OPTIONS=install + # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note + # that this option is technically if ENSUREPIP_OPTIONS is set and is + # not altinstall + # DEFAULT + # - The default behavior is to install pip, pipX, pipX.Y, easy_install + # and easy_install-X.Y. + pip_script = console.pop('pip', None) + if pip_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'pip = ' + pip_script + generated.extend(maker.make(spec)) + + if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": + spec = 'pip%s = %s' % (sys.version[:1], pip_script) + generated.extend(maker.make(spec)) + + spec = 'pip%s = %s' % (sys.version[:3], pip_script) + generated.extend(maker.make(spec)) + # Delete any other versioned pip entry points + pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] + for k in pip_ep: + del console[k] + easy_install_script = console.pop('easy_install', None) + if easy_install_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'easy_install = ' + easy_install_script + generated.extend(maker.make(spec)) + + spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) + generated.extend(maker.make(spec)) + # Delete any other versioned easy_install entry points + easy_install_ep = [ + k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) + ] + for k in easy_install_ep: + del console[k] + + # Generate the console and GUI entry points specified in the wheel + if len(console) > 0: + generated_console_scripts = maker.make_multiple( + ['%s = %s' % kv for kv in console.items()] + ) + generated.extend(generated_console_scripts) + + if warn_script_location: + msg = message_about_scripts_not_on_PATH(generated_console_scripts) + if msg is not None: + logger.warning(msg) + + if len(gui) > 0: + generated.extend( + maker.make_multiple( + ['%s = %s' % kv for kv in gui.items()], + {'gui': True} + ) + ) + + # Record pip as the installer + installer = os.path.join(info_dir[0], 'INSTALLER') + temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') + with open(temp_installer, 'wb') as installer_file: + installer_file.write(b'pip\n') + shutil.move(temp_installer, installer) + generated.append(installer) + + # Record details of all files installed + record = os.path.join(info_dir[0], 'RECORD') + temp_record = os.path.join(info_dir[0], 'RECORD.pip') + with open_for_csv(record, 'r') as record_in: + with open_for_csv(temp_record, 'w+') as record_out: + reader = csv.reader(record_in) + outrows = get_csv_rows_for_installed( + reader, installed=installed, changed=changed, + generated=generated, lib_dir=lib_dir, + ) + writer = csv.writer(record_out) + # Sort to simplify testing. + for row in sorted_outrows(outrows): + writer.writerow(row) + shutil.move(temp_record, record) + + +def wheel_version(source_dir): + # type: (Optional[str]) -> Optional[Tuple[int, ...]] + """ + Return the Wheel-Version of an extracted wheel, if possible. + + Otherwise, return None if we couldn't parse / extract it. + """ + try: + dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] + + wheel_data = dist.get_metadata('WHEEL') + wheel_data = Parser().parsestr(wheel_data) + + version = wheel_data['Wheel-Version'].strip() + version = tuple(map(int, version.split('.'))) + return version + except Exception: + return None + + +def check_compatibility(version, name): + # type: (Optional[Tuple[int, ...]], str) -> None + """ + Raises errors or warns if called with an incompatible Wheel-Version. + + Pip should refuse to install a Wheel-Version that's a major series + ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when + installing a version only minor version ahead (e.g 1.2 > 1.1). + + version: a 2-tuple representing a Wheel-Version (Major, Minor) + name: name of wheel or package to raise exception about + + :raises UnsupportedWheel: when an incompatible Wheel-Version is given + """ + if not version: + raise UnsupportedWheel( + "%s is in an unsupported or invalid wheel" % name + ) + if version[0] > VERSION_COMPATIBLE[0]: + raise UnsupportedWheel( + "%s's Wheel-Version (%s) is not compatible with this version " + "of pip" % (name, '.'.join(map(str, version))) + ) + elif version > VERSION_COMPATIBLE: + logger.warning( + 'Installing from a newer Wheel-Version (%s)', + '.'.join(map(str, version)), + ) + + +class Wheel(object): + """A wheel file""" + + # TODO: Maybe move the class into the models sub-package + # TODO: Maybe move the install code into this class + + wheel_file_re = re.compile( + r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) + ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) + \.whl|\.dist-info)$""", + re.VERBOSE + ) + + def __init__(self, filename): + # type: (str) -> None + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename( + "%s is not a valid wheel filename." % filename + ) + self.filename = filename + self.name = wheel_info.group('name').replace('_', '-') + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group('ver').replace('_', '-') + self.build_tag = wheel_info.group('build') + self.pyversions = wheel_info.group('pyver').split('.') + self.abis = wheel_info.group('abi').split('.') + self.plats = wheel_info.group('plat').split('.') + + # All the tag combinations from this file + self.file_tags = { + (x, y, z) for x in self.pyversions + for y in self.abis for z in self.plats + } + + def support_index_min(self, tags=None): + # type: (Optional[List[Pep425Tag]]) -> Optional[int] + """ + Return the lowest index that one of the wheel's file_tag combinations + achieves in the supported_tags list e.g. if there are 8 supported tags, + and one of the file tags is first in the list, then return 0. Returns + None is the wheel is not supported. + """ + if tags is None: # for mock + tags = pep425tags.get_supported() + indexes = [tags.index(c) for c in self.file_tags if c in tags] + return min(indexes) if indexes else None + + def supported(self, tags=None): + # type: (Optional[List[Pep425Tag]]) -> bool + """Is this wheel supported on this system?""" + if tags is None: # for mock + tags = pep425tags.get_supported() + return bool(set(tags).intersection(self.file_tags)) + + +def _contains_egg_info( + s, _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + """Determine whether the string looks like an egg_info. + + :param s: The string to parse. E.g. foo-2.1 + """ + return bool(_egg_info_re.search(s)) + + +def should_use_ephemeral_cache( + req, # type: InstallRequirement + format_control, # type: FormatControl + autobuilding, # type: bool + cache_available # type: bool +): + # type: (...) -> Optional[bool] + """ + Return whether to build an InstallRequirement object using the + ephemeral cache. + + :param cache_available: whether a cache directory is available for the + autobuilding=True case. + + :return: True or False to build the requirement with ephem_cache=True + or False, respectively; or None not to build the requirement. + """ + if req.constraint: + return None + if req.is_wheel: + if not autobuilding: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + return None + if not autobuilding: + return False + + if req.editable or not req.source_dir: + return None + + if req.link and not req.link.is_artifact: + # VCS checkout. Build wheel just for this run. + return True + + if "binary" not in format_control.get_allowed_formats( + canonicalize_name(req.name)): + logger.info( + "Skipping bdist_wheel for %s, due to binaries " + "being disabled for it.", req.name, + ) + return None + + link = req.link + base, ext = link.splitext() + if cache_available and _contains_egg_info(base): + return False + + # Otherwise, build the wheel just for this run using the ephemeral + # cache since we are either in the case of e.g. a local directory, or + # no cache directory is available to use. + return True + + +def format_command( + command_args, # type: List[str] + command_output, # type: str +): + # type: (...) -> str + """ + Format command information for logging. + """ + text = 'Command arguments: {}\n'.format(command_args) + + if not command_output: + text += 'Command output: None' + elif logger.getEffectiveLevel() > logging.DEBUG: + text += 'Command output: [use --verbose to show]' + else: + if not command_output.endswith('\n'): + command_output += '\n' + text += ( + 'Command output:\n{}' + '-----------------------------------------' + ).format(command_output) + + return text + + +def get_legacy_build_wheel_path( + names, # type: List[str] + temp_dir, # type: str + req, # type: InstallRequirement + command_args, # type: List[str] + command_output, # type: str +): + # type: (...) -> Optional[str] + """ + Return the path to the wheel in the temporary build directory. + """ + # Sort for determinism. + names = sorted(names) + if not names: + msg = ( + 'Legacy build of wheel for {!r} created no files.\n' + ).format(req.name) + msg += format_command(command_args, command_output) + logger.warning(msg) + return None + + if len(names) > 1: + msg = ( + 'Legacy build of wheel for {!r} created more than one file.\n' + 'Filenames (choosing first): {}\n' + ).format(req.name, names) + msg += format_command(command_args, command_output) + logger.warning(msg) + + return os.path.join(temp_dir, names[0]) + + +class WheelBuilder(object): + """Build wheels from a RequirementSet.""" + + def __init__( + self, + finder, # type: PackageFinder + preparer, # type: RequirementPreparer + wheel_cache, # type: WheelCache + build_options=None, # type: Optional[List[str]] + global_options=None, # type: Optional[List[str]] + no_clean=False # type: bool + ): + # type: (...) -> None + self.finder = finder + self.preparer = preparer + self.wheel_cache = wheel_cache + + self._wheel_dir = preparer.wheel_download_dir + + self.build_options = build_options or [] + self.global_options = global_options or [] + self.no_clean = no_clean + + def _build_one(self, req, output_dir, python_tag=None): + """Build one wheel. + + :return: The filename of the built wheel, or None if the build failed. + """ + # Install build deps into temporary directory (PEP 518) + with req.build_env: + return self._build_one_inside_env(req, output_dir, + python_tag=python_tag) + + def _build_one_inside_env(self, req, output_dir, python_tag=None): + with TempDirectory(kind="wheel") as temp_dir: + if req.use_pep517: + builder = self._build_one_pep517 + else: + builder = self._build_one_legacy + wheel_path = builder(req, temp_dir.path, python_tag=python_tag) + if wheel_path is not None: + wheel_name = os.path.basename(wheel_path) + dest_path = os.path.join(output_dir, wheel_name) + try: + shutil.move(wheel_path, dest_path) + logger.info('Stored in directory: %s', output_dir) + return dest_path + except Exception: + pass + # Ignore return, we can't do anything else useful. + self._clean_one(req) + return None + + def _base_setup_args(self, req): + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + return [ + sys.executable, '-u', '-c', + SETUPTOOLS_SHIM % req.setup_py + ] + list(self.global_options) + + def _build_one_pep517(self, req, tempd, python_tag=None): + """Build one InstallRequirement using the PEP 517 build process. + + Returns path to wheel if successfully built. Otherwise, returns None. + """ + assert req.metadata_directory is not None + try: + req.spin_message = 'Building wheel for %s (PEP 517)' % (req.name,) + logger.debug('Destination directory: %s', tempd) + wheel_name = req.pep517_backend.build_wheel( + tempd, + metadata_directory=req.metadata_directory + ) + if python_tag: + # General PEP 517 backends don't necessarily support + # a "--python-tag" option, so we rename the wheel + # file directly. + new_name = replace_python_tag(wheel_name, python_tag) + os.rename( + os.path.join(tempd, wheel_name), + os.path.join(tempd, new_name) + ) + # Reassign to simplify the return at the end of function + wheel_name = new_name + except Exception: + logger.error('Failed building wheel for %s', req.name) + return None + return os.path.join(tempd, wheel_name) + + def _build_one_legacy(self, req, tempd, python_tag=None): + """Build one InstallRequirement using the "legacy" build process. + + Returns path to wheel if successfully built. Otherwise, returns None. + """ + base_args = self._base_setup_args(req) + + spin_message = 'Building wheel for %s (setup.py)' % (req.name,) + with open_spinner(spin_message) as spinner: + logger.debug('Destination directory: %s', tempd) + wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ + + self.build_options + + if python_tag is not None: + wheel_args += ["--python-tag", python_tag] + + try: + output = call_subprocess(wheel_args, cwd=req.setup_py_dir, + show_stdout=False, spinner=spinner) + except Exception: + spinner.finish("error") + logger.error('Failed building wheel for %s', req.name) + return None + names = os.listdir(tempd) + wheel_path = get_legacy_build_wheel_path( + names=names, + temp_dir=tempd, + req=req, + command_args=wheel_args, + command_output=output, + ) + return wheel_path + + def _clean_one(self, req): + base_args = self._base_setup_args(req) + + logger.info('Running setup.py clean for %s', req.name) + clean_args = base_args + ['clean', '--all'] + try: + call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False) + return True + except Exception: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + def build( + self, + requirements, # type: Iterable[InstallRequirement] + session, # type: PipSession + autobuilding=False # type: bool + ): + # type: (...) -> List[InstallRequirement] + """Build wheels. + + :param unpack: If True, replace the sdist we built from with the + newly built wheel, in preparation for installation. + :return: True if all the wheels built correctly. + """ + buildset = [] + format_control = self.finder.format_control + # Whether a cache directory is available for autobuilding=True. + cache_available = bool(self._wheel_dir or self.wheel_cache.cache_dir) + + for req in requirements: + ephem_cache = should_use_ephemeral_cache( + req, format_control=format_control, autobuilding=autobuilding, + cache_available=cache_available, + ) + if ephem_cache is None: + continue + + buildset.append((req, ephem_cache)) + + if not buildset: + return [] + + # Is any wheel build not using the ephemeral cache? + if any(not ephem_cache for _, ephem_cache in buildset): + have_directory_for_build = self._wheel_dir or ( + autobuilding and self.wheel_cache.cache_dir + ) + assert have_directory_for_build + + # TODO by @pradyunsg + # Should break up this method into 2 separate methods. + + # Build the wheels. + logger.info( + 'Building wheels for collected packages: %s', + ', '.join([req.name for (req, _) in buildset]), + ) + _cache = self.wheel_cache # shorter name + with indent_log(): + build_success, build_failure = [], [] + for req, ephem in buildset: + python_tag = None + if autobuilding: + python_tag = pep425tags.implementation_tag + if ephem: + output_dir = _cache.get_ephem_path_for_link(req.link) + else: + output_dir = _cache.get_path_for_link(req.link) + try: + ensure_dir(output_dir) + except OSError as e: + logger.warning("Building wheel for %s failed: %s", + req.name, e) + build_failure.append(req) + continue + else: + output_dir = self._wheel_dir + wheel_file = self._build_one( + req, output_dir, + python_tag=python_tag, + ) + if wheel_file: + build_success.append(req) + if autobuilding: + # XXX: This is mildly duplicative with prepare_files, + # but not close enough to pull out to a single common + # method. + # The code below assumes temporary source dirs - + # prevent it doing bad things. + if req.source_dir and not os.path.exists(os.path.join( + req.source_dir, PIP_DELETE_MARKER_FILENAME)): + raise AssertionError( + "bad source dir - missing marker") + # Delete the source we built the wheel from + req.remove_temporary_source() + # set the build directory again - name is known from + # the work prepare_files did. + req.source_dir = req.build_location( + self.preparer.build_dir + ) + # Update the link for this. + req.link = Link(path_to_url(wheel_file)) + assert req.link.is_wheel + # extract the wheel into the dir + unpack_url( + req.link, req.source_dir, None, False, + session=session, + ) + else: + build_failure.append(req) + + # notify success/failure + if build_success: + logger.info( + 'Successfully built %s', + ' '.join([req.name for req in build_success]), + ) + if build_failure: + logger.info( + 'Failed to build %s', + ' '.join([req.name for req in build_failure]), + ) + # Return a list of requirements that failed to build + return build_failure diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/__init__.py new file mode 100755 index 0000000..b919b54 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/__init__.py @@ -0,0 +1,111 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(vendored_name, globals(), locals(), level=0) + except ImportError: + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("cachecontrol") + vendored("colorama") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("lockfile") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pep517") + vendored("pkg_resources") + vendored("progress") + vendored("pytoml") + vendored("retrying") + vendored("requests") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") + vendored("urllib3") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/appdirs.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/appdirs.py new file mode 100755 index 0000000..2bd3911 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/appdirs.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version_info__ = (1, 4, 3) +__version__ = '.'.join(map(str, __version_info__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/<AppName> + Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> + Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/__init__.py new file mode 100755 index 0000000..8fdee66 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = "Eric Larson" +__email__ = "eric@ionrock.org" +__version__ = "0.12.5" + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py new file mode 100755 index 0000000..f1e0ad9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,57 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), cache_etags=True, serializer=None, heuristic=None + ) + sess = requests.Session() + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument("url", help="The URL to try and cache") + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print("Cached!") + else: + print("Not cached :(") + + +if __name__ == "__main__": + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/adapter.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/adapter.py new file mode 100755 index 0000000..780eb28 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,133 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = {"PUT", "DELETE"} + + def __init__( + self, + cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, + **kw + ): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = cache or DictCache() + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ("GET",) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, cache_etags=cache_etags, serializer=serializer + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update(self.controller.conditional_headers(request)) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response( + self, request, response, from_cache=False, cacheable_methods=None + ): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, request, response + ), + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + + response._update_chunk_length = types.MethodType( + _update_chunk_length, response + ) + + resp = super(CacheControlAdapter, self).build_response(request, response) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/cache.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/cache.py new file mode 100755 index 0000000..94e0773 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplementedError() + + def set(self, key, value): + raise NotImplementedError() + + def delete(self, key): + raise NotImplementedError() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100755 index 0000000..0e1658f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100755 index 0000000..1ba0080 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,146 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = (IOError, OSError) + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + + def __init__( + self, + directory, + forever=False, + filemode=0o0600, + dirmode=0o0700, + use_dir_lock=None, + lock_class=None, + ): + + if use_dir_lock is not None and lock_class is not None: + raise ValueError("Cannot use use_dir_lock and lock_class together") + + try: + from pip._vendor.lockfile import LockFile + from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile + except ImportError: + notice = dedent( + """ + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """ + ) + raise ImportError(notice) + + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + try: + with open(name, "rb") as fh: + return fh.read() + + except FileNotFoundError: + return None + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100755 index 0000000..ed705ce --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,33 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, int(expires.total_seconds()), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/compat.py new file mode 100755 index 0000000..33b5aed --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/controller.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/controller.py new file mode 100755 index 0000000..1b2b943 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,367 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + + def __init__( + self, cache=None, cache_etags=True, serializer=None, status_codes=None + ): + self.cache = cache or DictCache() + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + "max-age": (int, True), + "max-stale": (int, False), + "min-fresh": (int, True), + "no-cache": (None, False), + "no-store": (None, False), + "no-transform": (None, False), + "only-if-cached": (None, False), + "must-revalidate": (None, False), + "public": (None, False), + "private": (None, False), + "proxy-revalidate": (None, False), + "s-maxage": (int, True), + } + + cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) + + retval = {} + + for cc_directive in cc_headers.split(","): + if not cc_directive.strip(): + continue + + parts = cc_directive.split("=", 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug("Ignoring unknown cache-control directive: %s", directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug( + "Missing value for cache-control " "directive: %s", + directive, + ) + except ValueError: + logger.debug( + "Invalid value for cache-control directive " "%s, must be %s", + directive, + typ.__name__, + ) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if "no-cache" in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if "max-age" in cc and cc["max-age"] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug("No cache entry available") + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning("Cache entry deserialization failed, entry ignored") + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ( + 'Returning cached "301 Moved Permanently" response ' + "(ignoring date and etag information)" + ) + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or "date" not in headers: + if "etag" not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug("Purging cached response: no date or etag") + self.cache.delete(cache_url) + logger.debug("Ignoring cached response: no date") + return False + + now = time.time() + date = calendar.timegm(parsedate_tz(headers["date"])) + current_age = max(0, now - date) + logger.debug("Current age based on date: %i", current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if "max-age" in resp_cc: + freshness_lifetime = resp_cc["max-age"] + logger.debug("Freshness lifetime from max-age: %i", freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif "expires" in headers: + expires = parsedate_tz(headers["expires"]) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if "max-age" in cc: + freshness_lifetime = cc["max-age"] + logger.debug( + "Freshness lifetime from request max-age: %i", freshness_lifetime + ) + + if "min-fresh" in cc: + min_fresh = cc["min-fresh"] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug("Adjusted current age from min-fresh: %i", current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug("%i > %i", freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if "etag" not in headers: + logger.debug('The cached response is "stale" with no etag, purging') + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if "etag" in headers: + new_headers["If-None-Match"] = headers["ETag"] + + if "last-modified" in headers: + new_headers["If-Modified-Since"] = headers["Last-Modified"] + + return new_headers + + def cache_response(self, request, response, body=None, status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + "Status code %s not in %s", response.status, cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if ( + body is not None + and "content-length" in response_headers + and response_headers["content-length"].isdigit() + and int(response_headers["content-length"]) != len(body) + ): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if "no-store" in cc: + no_store = True + logger.debug('Response header has "no-store"') + if "no-store" in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + if no_store: + return + + # If we've been given an etag, then keep the response + if self.cache_etags and "etag" in response_headers: + logger.debug("Caching due to etag") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug("Caching permanant redirect") + self.cache.set(cache_url, self.serializer.dumps(request, response)) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif "date" in response_headers: + # cache when there is a max-age > 0 + if "max-age" in cc and cc["max-age"] > 0: + logger.debug("Caching b/c date exists and max-age > 0") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif "expires" in response_headers: + if response_headers["expires"]: + logger.debug("Caching b/c of expires header") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads(request, self.cache.get(cache_url)) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = ["content-length"] + + cached_response.headers.update( + dict( + (k, v) + for k, v in response.headers.items() + if k.lower() not in excluded_headers + ) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set(cache_url, self.serializer.dumps(request, cached_response)) + + return cached_response diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py new file mode 100755 index 0000000..30ed4c5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,80 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__("_CallbackFileWrapper__fp") + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + + except AttributeError: + pass + + try: + return self.__fp.closed + + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b"\r\n": + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py new file mode 100755 index 0000000..6c0e979 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,135 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({"Warning": warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + + def update_headers(self, response): + headers = {} + + if "expires" not in response.headers: + date = parsedate(response.headers["date"]) + expires = expire_after(timedelta(days=1), date=datetime(*date[:6])) + headers["expires"] = datetime_to_header(expires) + headers["cache-control"] = "public" + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return {"expires": datetime_to_header(expires), "cache-control": "public"} + + def warning(self, response): + tmpl = "110 - Automatically cached for %s. Response might be stale" + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = { + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + } + + def update_headers(self, resp): + headers = resp.headers + + if "expires" in headers: + return {} + + if "cache-control" in headers and headers["cache-control"] != "public": + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if "date" not in headers or "last-modified" not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers["date"])) + last_modified = parsedate(headers["last-modified"]) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {"expires": time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/serialize.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/serialize.py new file mode 100755 index 0000000..ec43ff2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,186 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + } + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u"vary"].split(",") + for header in varied_headers: + header = text_type(header).strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{}".format(ver))(request, data) + + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached["response"]["headers"]) + if headers.get("transfer-encoding", "") == "chunked": + headers.pop("transfer-encoding") + + cached["response"]["headers"] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode("utf8")) + + return HTTPResponse(body=body, preload_content=False, **cached["response"]) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, encoding="utf-8") + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py new file mode 100755 index 0000000..265bfc8 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,29 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl( + sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None, +): + + cache = cache or DictCache() + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods, + ) + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + return sess diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__init__.py new file mode 100755 index 0000000..ef71f3a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import where + +__version__ = "2018.11.29" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__main__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__main__.py new file mode 100755 index 0000000..ae2aff5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/__main__.py @@ -0,0 +1,2 @@ +from pip._vendor.certifi import where +print(where()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/cacert.pem b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/cacert.pem new file mode 100755 index 0000000..db68797 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4512 @@ + +# 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=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 3 Public Primary Certification Authority - G3" +# Serial: 206684696279472310254277870180966723415 +# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 +# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 +# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----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=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Label: "AddTrust External Root" +# Serial: 1 +# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f +# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 +# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----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=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----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 Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----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=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----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: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----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=Class 2 Primary CA O=Certplus +# Subject: CN=Class 2 Primary CA O=Certplus +# Label: "Certplus Class 2 Primary CA" +# Serial: 177770208045934040241468760488327595043 +# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b +# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb +# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----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=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----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=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----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=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----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: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Label: "Deutsche Telekom Root CA 2" +# Serial: 38 +# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 +# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf +# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----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=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----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=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G2" +# Serial: 10000012 +# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a +# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 +# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----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=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----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=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----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: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----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=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----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 - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----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=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----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=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----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=LuxTrust Global Root 2 O=LuxTrust S.A. +# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Label: "LuxTrust Global Root 2" +# Serial: 59914338225734147123941058376788110305822489521 +# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c +# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f +# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 +-----BEGIN CERTIFICATE----- +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 +-----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=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----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=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----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: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----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: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----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: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----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----- diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/core.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/core.py new file mode 100755 index 0000000..2d02ea4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/certifi/core.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem. +""" +import os + + +def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, 'cacert.pem') + + +if __name__ == '__main__': + print(where()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/__init__.py new file mode 100755 index 0000000..0f9f820 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/__init__.py @@ -0,0 +1,39 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .compat import PY2, PY3 +from .universaldetector import UniversalDetector +from .version import __version__, VERSION + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{0}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5freq.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5freq.py new file mode 100755 index 0000000..38f3251 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# <http://www.edu.tw:81/mandr/> +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5prober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5prober.py new file mode 100755 index 0000000..98f9970 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/chardistribution.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/chardistribution.py new file mode 100755 index 0000000..c0395f4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py new file mode 100755 index 0000000..8b3738e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,106 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetprober.py new file mode 100755 index 0000000..eac4e59 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/__init__.py new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py new file mode 100755 index 0000000..c61136b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) + else: + return '{0}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py new file mode 100755 index 0000000..68fba44 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/compat.py new file mode 100755 index 0000000..ddd7468 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/compat.py @@ -0,0 +1,34 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + base_str = (str, unicode) + text_type = unicode +else: + PY2 = False + PY3 = True + base_str = (bytes, str) + text_type = str diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cp949prober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cp949prober.py new file mode 100755 index 0000000..efd793a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/enums.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/enums.py new file mode 100755 index 0000000..0451207 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escprober.py new file mode 100755 index 0000000..c70493f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escsm.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escsm.py new file mode 100755 index 0000000..0069523 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/eucjpprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/eucjpprober.py new file mode 100755 index 0000000..20ce8f7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrfreq.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrfreq.py new file mode 100755 index 0000000..b68078c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrprober.py new file mode 100755 index 0000000..345a060 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwfreq.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwfreq.py new file mode 100755 index 0000000..ed7a995 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# <http:#www.edu.tw:81/mandr/> + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwprober.py new file mode 100755 index 0000000..35669cc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312freq.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312freq.py new file mode 100755 index 0000000..697837b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312prober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312prober.py new file mode 100755 index 0000000..8446d2d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/hebrewprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/hebrewprober.py new file mode 100755 index 0000000..b0e1bf4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jisfreq.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jisfreq.py new file mode 100755 index 0000000..83fc082 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jpcntx.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jpcntx.py new file mode 100755 index 0000000..20044e4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100755 index 0000000..2aa4fb2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,228 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +# this table is modified base on win1251BulgarianCharToOrderMap, so +# only number <64 is sure valid + +Latin5_BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 +) + +win1251BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 96.9392% +# first 1024 sequences:3.0618% +# rest sequences: 0.2992% +# negative sequences: 0.0020% +BulgarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +) + +Latin5BulgarianModel = { + 'char_to_order_map': Latin5_BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Bulgairan', +} + +Win1251BulgarianModel = { + 'char_to_order_map': win1251BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Bulgarian', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py new file mode 100755 index 0000000..e5f9a1f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py @@ -0,0 +1,333 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# KOI8-R language model +# Character Mapping Table: +KOI8R_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 +) + +win1251_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +) + +latin5_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +macCyrillic_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +) + +IBM855_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +) + +IBM866_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 97.6601% +# first 1024 sequences: 2.3389% +# rest sequences: 0.1237% +# negative sequences: 0.0009% +RussianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +) + +Koi8rModel = { + 'char_to_order_map': KOI8R_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "KOI8-R", + 'language': 'Russian', +} + +Win1251CyrillicModel = { + 'char_to_order_map': win1251_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Russian', +} + +Latin5CyrillicModel = { + 'char_to_order_map': latin5_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Russian', +} + +MacCyrillicModel = { + 'char_to_order_map': macCyrillic_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "MacCyrillic", + 'language': 'Russian', +} + +Ibm866Model = { + 'char_to_order_map': IBM866_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM866", + 'language': 'Russian', +} + +Ibm855Model = { + 'char_to_order_map': IBM855_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM855", + 'language': 'Russian', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py new file mode 100755 index 0000000..5332221 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin7_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +win1253_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.2851% +# first 1024 sequences:1.7001% +# rest sequences: 0.0359% +# negative sequences: 0.0148% +GreekLangModel = ( +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin7GreekModel = { + 'char_to_order_map': Latin7_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-7", + 'language': 'Greek', +} + +Win1253GreekModel = { + 'char_to_order_map': win1253_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "windows-1253", + 'language': 'Greek', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py new file mode 100755 index 0000000..58f4c87 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,200 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Simon Montagu +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Shoshannah Forbes - original C code (?) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Windows-1255 language model +# Character Mapping Table: +WIN1255_CHAR_TO_ORDER_MAP = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.4004% +# first 1024 sequences: 1.5981% +# rest sequences: 0.087% +# negative sequences: 0.0015% +HEBREW_LANG_MODEL = ( +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +) + +Win1255HebrewModel = { + 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, + 'precedence_matrix': HEBREW_LANG_MODEL, + 'typical_positive_ratio': 0.984004, + 'keep_english_letter': False, + 'charset_name': "windows-1255", + 'language': 'Hebrew', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py new file mode 100755 index 0000000..bb7c095 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin2_HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +win1250HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 94.7368% +# first 1024 sequences:5.2623% +# rest sequences: 0.8894% +# negative sequences: 0.0009% +HungarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +) + +Latin2HungarianModel = { + 'char_to_order_map': Latin2_HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-2", + 'language': 'Hungarian', +} + +Win1250HungarianModel = { + 'char_to_order_map': win1250HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "windows-1250", + 'language': 'Hungarian', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langthaimodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langthaimodel.py new file mode 100755 index 0000000..15f94c2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,199 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# The following result for thai was collected from a limited sample (1M). + +# Character Mapping Table: +TIS620CharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 92.6386% +# first 1024 sequences:7.3177% +# rest sequences: 1.0230% +# negative sequences: 0.0436% +ThaiLangModel = ( +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +TIS620ThaiModel = { + 'char_to_order_map': TIS620CharToOrderMap, + 'precedence_matrix': ThaiLangModel, + 'typical_positive_ratio': 0.926386, + 'keep_english_letter': False, + 'charset_name': "TIS-620", + 'language': 'Thai', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py new file mode 100755 index 0000000..a427a45 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Özgür Baskın - Turkish Language Model +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin5_TurkishCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, + 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, +255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, + 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, +180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, +164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, +150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, + 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, +124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, + 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, + 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, + 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, +) + +TurkishLangModel = ( +3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, +3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, +3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, +3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, +3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, +3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, +2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, +3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, +1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, +3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, +3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, +2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, +2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, +3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, +0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, +3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, +3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, +0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, +1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, +3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, +1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, +3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, +0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, +3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, +1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, +1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, +2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, +2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, +3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, +1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, +0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, +3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, +0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, +3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, +1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, +2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, +0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, +3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, +0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, +0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, +3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, +0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, +0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, +3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, +0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, +3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, +0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, +0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, +3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, +0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, +3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, +0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, +0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, +0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, +0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, +0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, +0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, +1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, +0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, +0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, +3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, +0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, +2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, +2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, +0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, +0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin5TurkishModel = { + 'char_to_order_map': Latin5_TurkishCharToOrderMap, + 'precedence_matrix': TurkishLangModel, + 'typical_positive_ratio': 0.970290, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-9", + 'language': 'Turkish', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/latin1prober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/latin1prober.py new file mode 100755 index 0000000..7d1e8c2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py new file mode 100755 index 0000000..6256ecf --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100755 index 0000000..530abe7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcssm.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcssm.py new file mode 100755 index 0000000..8360d0f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py new file mode 100755 index 0000000..0adb51d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,132 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model['charset_name'] + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.get('language') + + def feed(self, byte_str): + if not self._model['keep_english_letter']: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model['char_to_order_map'] + for i, c in enumerate(byte_str): + # XXX: Order is in range 1-64, so one would think we want 0-63 here, + # but that leads to 27 more test failures than before. + order = char_to_order_map[c] + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + i = (self._last_order * self.SAMPLE_SIZE) + order + model = self._model['precedence_matrix'][i] + else: # reverse the order of the letters in the lookup + i = (order * self.SAMPLE_SIZE) + self._last_order + model = self._model['precedence_matrix'][i] + self._seq_counters[model] += 1 + self._last_order = order + + charset_name = self._model['charset_name'] + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model['typical_positive_ratio']) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100755 index 0000000..98e95dc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,73 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .sbcharsetprober import SingleByteCharSetProber +from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, + Latin5CyrillicModel, MacCyrillicModel, + Ibm866Model, Ibm855Model) +from .langgreekmodel import Latin7GreekModel, Win1253GreekModel +from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel +# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel +from .langthaimodel import TIS620ThaiModel +from .langhebrewmodel import Win1255HebrewModel +from .hebrewprober import HebrewProber +from .langturkishmodel import Latin5TurkishModel + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + self.probers = [ + SingleByteCharSetProber(Win1251CyrillicModel), + SingleByteCharSetProber(Koi8rModel), + SingleByteCharSetProber(Latin5CyrillicModel), + SingleByteCharSetProber(MacCyrillicModel), + SingleByteCharSetProber(Ibm866Model), + SingleByteCharSetProber(Ibm855Model), + SingleByteCharSetProber(Latin7GreekModel), + SingleByteCharSetProber(Win1253GreekModel), + SingleByteCharSetProber(Latin5BulgarianModel), + SingleByteCharSetProber(Win1251BulgarianModel), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(Latin2HungarianModel), + # SingleByteCharSetProber(Win1250HungarianModel), + SingleByteCharSetProber(TIS620ThaiModel), + SingleByteCharSetProber(Latin5TurkishModel), + ] + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, + False, hebrew_prober) + visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, + hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) + self.probers.extend([hebrew_prober, logical_hebrew_prober, + visual_hebrew_prober]) + + self.reset() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sjisprober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sjisprober.py new file mode 100755 index 0000000..9e29623 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/universaldetector.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/universaldetector.py new file mode 100755 index 0000000..7b4e92d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() == logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + return self.result diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/utf8prober.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/utf8prober.py new file mode 100755 index 0000000..6c3196c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/version.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/version.py new file mode 100755 index 0000000..bb2a34a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "3.0.4" +VERSION = __version__.split('.') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/__init__.py new file mode 100755 index 0000000..2a3bf47 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/__init__.py @@ -0,0 +1,6 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.4.1' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansi.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansi.py new file mode 100755 index 0000000..7877658 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansitowin32.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansitowin32.py new file mode 100755 index 0000000..359c92b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,257 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def __enter__(self, *args, **kwargs): + # special method lookup bypasses __getattr__/__getattribute__, see + # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit + # thus, contextlib magic methods are not proxied via __getattr__ + return self.__wrapped.__enter__(*args, **kwargs) + + def __exit__(self, *args, **kwargs): + return self.__wrapped.__exit__(*args, **kwargs) + + def write(self, text): + self.__convertor.write(text) + + def isatty(self): + stream = self.__wrapped + if 'PYCHARM_HOSTED' in os.environ: + if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): + return True + try: + stream_isatty = stream.isatty + except AttributeError: + return False + else: + return stream_isatty() + + @property + def closed(self): + stream = self.__wrapped + try: + return stream.closed + except AttributeError: + return True + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not self.stream.closed and not self.stream.isatty()) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not self.stream.closed and self.stream.isatty() + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not self.stream.closed: + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/initialise.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/initialise.py new file mode 100755 index 0000000..430d066 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/initialise.py @@ -0,0 +1,80 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/win32.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/win32.py new file mode 100755 index 0000000..c2d8360 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/win32.py @@ -0,0 +1,152 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in + (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = _GetStdHandle(stream_id) + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = _GetStdHandle(stream_id) + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = _GetStdHandle(stream_id) + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = _GetStdHandle(stream_id) + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = _GetStdHandle(stream_id) + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/winterm.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/winterm.py new file mode 100755 index 0000000..0fdb4ec --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/colorama/winterm.py @@ -0,0 +1,169 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + self._light = 0 + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + elif mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + elif mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/__init__.py new file mode 100755 index 0000000..a786b4d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.2.8' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py new file mode 100755 index 0000000..f7dbf4c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/misc.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/misc.py new file mode 100755 index 0000000..cfb318d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py new file mode 100755 index 0000000..159e49e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +import collections +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, collections.Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100755 index 0000000..1746bd0 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100755 index 0000000..1df3aba --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_expand_globals(_SCHEMES) + + # FIXME don't rely on sys.version here, its format is an implementation detail + # of CPython, use sys.version_info or sys.hexversion +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' + r'<string>(.*?)</string>', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py new file mode 100755 index 0000000..d66d856 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> +# All rights reserved. +# +# 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. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", int(time.time())) + self.__write(b"\037\213\010\010" + timestamp + b"\002\377") + if self.name.endswith(".gz"): + self.name = self.name[:-3] + # RFC1952 says we must use ISO-8859-1 for the FNAME field. + self.__write(self.name.encode("iso-8859-1", "replace") + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = b"" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != b"\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != b"\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/compat.py new file mode 100755 index 0000000..ff328c8 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/database.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/database.py new file mode 100755 index 0000000..b13cdac --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/database.py @@ -0,0 +1,1339 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, + LEGACY_METADATA_FILENAME) +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, + WHEEL_METADATA_FILENAME, + LEGACY_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find('METADATA') + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read() + self.modules = data.splitlines() + + def __repr__(self): + return '<InstalledDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '<EggInfoDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/index.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/index.py new file mode 100755 index 0000000..2406be2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/locators.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/locators.py new file mode 100755 index 0000000..5c655c3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/locators.py @@ -0,0 +1,1295 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.python.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.python.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if not is_compatible(wheel, self.wheel_tags): + logger.debug('Wheel not compatible: %s', path) + else: + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at keys of the form + 'algo_digest'. + + Returns a 2-tuple (algo, digest) if found, else None. Currently + looks only for SHA256, then MD5. + """ + result = None + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + self.platform_check = False # See issue #112 + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux_(i\d86|x86_64|arm\w+)|' + r'win(32|_amd64)|macosx_?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self.platform_check and self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile('<a href=[^>]*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.python.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' + r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/manifest.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/manifest.py new file mode 100755 index 0000000..ca0fe44 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects <pattern1> <pattern2> ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects <dir> <pattern1> <pattern2> ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single <dir_pattern>' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/markers.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/markers.py new file mode 100755 index 0000000..ee1f3e2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/markers.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Parser for the environment markers micro-language defined in PEP 508. +""" + +# Note: In PEP 345, the micro-language was Python compatible, so the ast +# module could be used to parse it. However, PEP 508 introduced operators such +# as ~= and === which aren't in Python, necessitating a different approach. + +import os +import sys +import platform +import re + +from .compat import python_implementation, urlparse, string_types +from .util import in_venv, parse_marker + +__all__ = ['interpret'] + +def _is_literal(o): + if not isinstance(o, string_types) or not o: + return False + return o[0] in '\'"' + +class Evaluator(object): + """ + This class is used to evaluate marker expessions. + """ + + operations = { + '==': lambda x, y: x == y, + '===': lambda x, y: x == y, + '~=': lambda x, y: x == y or x > y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/metadata.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/metadata.py new file mode 100755 index 0000000..77eed7f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1094 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +# See issue #106: Sometimes 'Requires' occurs wrongly in the metadata. Include +# it in the tuple literal below to allow it (for now) +_566_FIELDS = _426_FIELDS + ('Description-Content-Type', 'Requires') + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +_ATTR2FIELD = { + 'metadata_version': 'Metadata-Version', + 'name': 'Name', + 'version': 'Version', + 'platform': 'Platform', + 'supported_platform': 'Supported-Platform', + 'summary': 'Summary', + 'description': 'Description', + 'keywords': 'Keywords', + 'home_page': 'Home-page', + 'author': 'Author', + 'author_email': 'Author-email', + 'maintainer': 'Maintainer', + 'maintainer_email': 'Maintainer-email', + 'license': 'License', + 'classifier': 'Classifier', + 'download_url': 'Download-URL', + 'obsoletes_dist': 'Obsoletes-Dist', + 'provides_dist': 'Provides-Dist', + 'requires_dist': 'Requires-Dist', + 'setup_requires_dist': 'Setup-Requires-Dist', + 'requires_python': 'Requires-Python', + 'requires_external': 'Requires-External', + 'requires': 'Requires', + 'provides': 'Provides', + 'obsoletes': 'Obsoletes', + 'project_url': 'Project-URL', + 'private_version': 'Private-Version', + 'obsoleted_by': 'Obsoleted-By', + 'extension': 'Extension', + 'provides_extra': 'Provides-Extra', +} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can + instantiate the class with one of these arguments (or none): + - *path*, the path to a metadata file + - *fileobj* give a file-like object with metadata as content + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + # logger.debug('Attempting to set metadata for %s', self) + # self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + """ + self.set_metadata_version() + + mapping_1_0 = ( + ('metadata_version', 'Metadata-Version'), + ('name', 'Name'), + ('version', 'Version'), + ('summary', 'Summary'), + ('home_page', 'Home-page'), + ('author', 'Author'), + ('author_email', 'Author-email'), + ('license', 'License'), + ('description', 'Description'), + ('keywords', 'Keywords'), + ('platform', 'Platform'), + ('classifiers', 'Classifier'), + ('download_url', 'Download-URL'), + ) + + data = {} + for key, field_name in mapping_1_0: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + if self['Metadata-Version'] == '1.2': + mapping_1_2 = ( + ('requires_dist', 'Requires-Dist'), + ('requires_python', 'Requires-Python'), + ('requires_external', 'Requires-External'), + ('provides_dist', 'Provides-Dist'), + ('obsoletes_dist', 'Obsoletes-Dist'), + ('project_url', 'Project-URL'), + ('maintainer', 'Maintainer'), + ('maintainer_email', 'Maintainer-email'), + ) + for key, field_name in mapping_1_2: + if not skip_missing or field_name in self._fields: + if key != 'project_url': + data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] + + elif self['Metadata-Version'] == '1.1': + mapping_1_1 = ( + ('provides', 'Provides'), + ('requires', 'Requires'), + ('obsoletes', 'Obsoletes'), + ) + for key, field_name in mapping_1_1: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' +LEGACY_METADATA_FILENAME = 'METADATA' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + 'license': 'License', + 'summary': 'Summary', + 'description': 'Description', + 'classifiers': 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + for nk, ok in self.LEGACY_MAPPING.items(): + if nk in nmd: + result[ok] = nmd[nk] + r1 = process_entries(self.run_requires + self.meta_requires) + r2 = process_entries(self.build_requires + self.dev_requires) + if self.extras: + result['Provides-Extra'] = sorted(self.extras) + result['Requires-Dist'] = sorted(r1) + result['Setup-Requires-Dist'] = sorted(r2) + # TODO: other fields such as contacts + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/resources.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/resources.py new file mode 100755 index 0000000..1884016 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/scripts.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/scripts.py new file mode 100755 index 0000000..8e22cb9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/scripts.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%s" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly>'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +if __name__ == '__main__': + import sys, re + + def _resolve(module, func): + __import__(module) + mod = sys.modules[module] + parts = func.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + try: + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + + func = _resolve('%(module)s', '%(func)s') + rc = func() # None interpreted as 0 + except Exception as e: # only supporting Python >= 2.6 + sys.stderr.write('%%s\n' %% e) + rc = 1 + sys.exit(rc) +''' + + +def _enquote_executable(executable): + if ' ' in executable: + # make sure we quote only the executable in case of env + # for example /usr/bin/env "/dir with spaces/bin/jython" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + # Normalise case for Windows + executable = os.path.normcase(executable) + # If the user didn't specify an executable, it may be necessary to + # cater for executable paths with spaces (not uncommon on Windows) + if enquote: + executable = _enquote_executable(executable) + # Issue #51: don't use fsencode, since we later try to + # check that the shebang is decodable using utf-8. + executable = executable.encode('utf-8') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not shebang.endswith(linesep): + shebang += linesep + if not use_launcher: + script_bytes = shebang + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, sys.version[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s' % (name, sys.version[:3])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # Issue 31: don't hardcode an absolute package name, but + # determine it relative to the current package + distlib_package = __name__.rsplit('.', 1)[0] + result = finder(distlib_package).find(name).bytes + return result + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t32.exe b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t32.exe new file mode 100755 index 0000000000000000000000000000000000000000..a09d926872d84ae22a617dfe9ebb560d420b37de GIT binary patch literal 92672 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t64.exe b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/t64.exe new file mode 100755 index 0000000000000000000000000000000000000000..9da9b40de922fb203df6b9a1d0ad4139af536850 GIT binary patch literal 102400 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�vlnW`{LoXpTySn$@;x8yoz96jn?+Kk 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�?dYNUd4WaURX_A__M4W}D0!0n z7SR(e=lh+Vr^EqKYQV(ghEpn%^81ij&>v^w)H{5^yoQ|?r%v<sP^T5es?%n4SEmv0 zX=C~|^=(XQNOVLh$GB+a7-Pz==`viY{(Nr*)9KSq^(l%W&(V@+O(XGl?g;kT_=5hz z9Nm<oh`7c9iSOIW6HfSShL$G29d<e&gGY>NH+Pk{cX9uSFPLU`P2cV+c3QVkzP3P% zS)-Nul6VD%p~E{aEK!9y<CL=~Q8{NMDCfAI%2_#}_0*>1##0*lRD=zPQv-?|YQT)1 zY5;XPU|MqPDNTJEdo?6fB<gZ?r(7}0F|D0Wubj^@OPc)yEfj`dzmd?kXb1G&u1*Vk zQuS<ztLS0#LX$8vzcB6(M~D4V*Qd}>zJ8;+tJA%YsMCucR;Q19NSz+GStZ!vDhQXT z%NVU<$F!I6j0~l&=j$6xdti)87{~gnvYnrV2c=i~wtA5C*SeJ&m(?CuVz+SBZA^G- zke@#DF!#z<YK)zh$xpXXexxoR$9)H1uI=YFa1Je~g|^wW0~02(cO>m4TJ;{|&~+x^ z^DpJpJ6|yTufbp83x)3$sd|lzSG{iSkr$?U*5<JRv8LXr&jFR~br#I~lqpJG4K3HU zkO;qiBYLR*MN?J(8F{MzxGAcC*komD*|gaVG7~nShZ^8bh8Oz63#X_7VZBsRQ}4#a z2Hd2LdTE=qhki4nX`|g#zcEP-Vac&7nf8@T`$~pSlE-{I@0@;xQn&I2c}LfgH;#B| z|MVBM`&LO&$|3YQ$jP76uj273yBxp4d_LwQwmB>*MkRUqXn#rMDQQe%Lzt<@yu=gT z8iVxddo^=FzFr>+btqr|So*XCXhh!zP5a-f%aIor8KxrV;ohk&X!~B+_l=<+?5_IG z08+Po$Mmky@kyMTHgV9V2eg4k(+q9G26R^g?xLJciH(ki_=>pv9;va^Rifm9ez`yW za{n=XTMg|EuL!>$Ek}+^?5V*#Cv;N@-e~wAI3}(ktb4fXJ|-%)Uuq9Ea9oiZ7<Q#P zzNa;Hy&J-6+K>+PYBD20Y<`e7+g2#`8DA)!KJ<Y_Jyo9>@$`jps?V(n6`CG1V(A;` zALttr6T7KI%9uDtMw9lq9;#L9RlZMxdDd|eA3W5Dd`rI?rtKIT;GsU_aGPew4^KFV zQ{p%L7Z0DnE6`K(N+tZK`-m9bCc8^rO>7?z`u>Qf$d^aj0>cK!s=?#>slop|wKciv zl*T>{y($v(6Y?~_ObgF5?c0o5L0VkR0<oH}(#}8QU)DfxFX}0g`c6>2Gke||+Zxl< ztueA8IR4RX*!+@6{u7kr#U2%U+_d?tFZ|VeY|qNh;Zj549E9ts9Dk<VViy}O<x36g z8LoPciA}ZnTfFOj^klFzJ)YmB)P6pRQ($7>Sa_Floc^WnwBD^jP6(F0_;>ID-(T#q zo3`3vj2>e+H0b}8-z&A@0i|9G(&}`^jaz#(b#IJrh^mOpkH`y8mA+Z%)9<_<YRI_j zB8G&OM0CZYPUaoo#-nd<RjT*n?L2x?{=?4^z7YQ<(?`*VCBuKo@E`qE#kZw1a~HQw z_=0Vr-=G-PYlee9xu@z?sYkkeDU+@{X}|W|s6TU~{<IbP5yM}V;dZ;ck9N7C%XZlq zY4Z(vJAN)fzw4#nrH`}w-KHSTFMeIAxqLAnK~#RGj(XykwnF;-D%<Nw`qQi5P^y;i zOxu4X_`Pp3-?YtPN%W!cY|@{5R>bGW<(YOzd!vu<NBgwrW~SfAAAMSDucm}XLy6eD zlgznVWzH2A6|SPju_MquOm&w&wU^K`7Fq(wm>6`wy4t2gu>DukeujsuQ^V@a{1Q6# z8$w^}9S84@Rei%!RdBu`4JItEn~I~~h?{2Smth0r)Ie{d8d#J-zvxf{+sDhieq-X5 z)4PQE(PHLDKITX4iiTAvGfOo6Wd%YQoiF;9rqiVLm|wRuz+087aJJhyv0MMoppO$_ zwe9ym=erHf{&T+D(Bc1<^W6i(Iv!`N4?}L4Y2-0EtZ-+kVUg2|ML?EU;9W3Ft-#b# z+KAN4NFdcFm8s=Q_QA+mJQbzm@>N!{_zoVIjES06Q0kpjUOAmbe_62|b|F3&6<4yn z&MaS4RbEz{>8&iwVzJIy)>D+Ls;YGUB0Gi|<?TtT_az0%ekKyCU=r%oaBOqSi+p9p zlMvipR<Mv_sQV+PibSr1q_jPv(uiDNnYVP}_1@wc<+DnQiZd4!RH~oaB?|d-DRr&H zJ>6U6L0%;?!5A@%oHa`Xlt=@GJ{<~S{8g$CmD`r=7283lsm!wSs-Wr8tZA2J<%}IO zvZ$;K8AjN2Zzcb;$@g?m&Ma46wsv?m+*4doF{!eclwZ=gOT-fDpDJq+;+@ROQZK^8 zvgrs8L`1C8BXWuh78jpjUtvm7Ngd3%zCx&TbEkTDsTU%HlB#yfz7sif(E?raqO7Hb z96Tl!NKDd7JtQSRsdIQlc9pw$o^SsA;>x_r;wq`yvm&Q?%Pudi^!f_QW-dYsRHW2E zvCAnhzt&eV2|=$UK+#0Rk}NKn1r?k&7B2A?FZHS+VrPP8EmbYy*^3}RL0Rbyor~;R zR5ZP!bWvuxk90qVS|Z=dD=!tQspsUZbqDk7nzG09IkE_$+2sgmG-dy${TPnth=QhG zp754hB)BUxPpOL~#FVUD!Q&|Z<>ahLb1L$7b!FJ3vMPzPpo|mFSBZ%vjp+(8>1wVP zs&?S7=X6S@P0d&!66$QIHe37~R!}*Ts<Z`HQ4xejUV6INnD$_JkNO@LH4A3Z?L#e- zG>nTOkornek+vh;p?)CY*><3!Dx`?B)QeE8teDo?iQyU|r<WCTW_(mcPG)XF1sn{A zk=pi%Y2;KQWPFv>1Pzj3%@32JX0?l6O}MIA>TStKR}QLQdzmCIY2&m`XH>B9&L|JH zX!Tpu^7D!-wRC<_A^Za$Q1ic#SZ0(KUTc?oR|o3a-3jEa*5$vxievUON=c_mQwB`^ z*zO_3VwQ46<dhc_<&@5=<XAnWKB#$QTCu5^jXG|-dxInX+`&xcK$)wlMPJndiEN^; zqy$z|>NcTPhyJFB^XCgI3Mz|3v@I4N9cXlUL1n23EoZ3$<5D!GM50t`s+7Ynmh>a6 zn+&JZUbyRQIKu9`$o_wR|05Kr&Nt`kf{6vq$L;DT1YJ)KWv*{#7AN=9(M9~r_n+T? zDDWQ&{MRWEY;$AodTYcT!<2gdYUhh3FN@L#^Aq<|_=4?C_V)#6Nvo3iqWI$ZI47z1 z{iA_#d@(lcZo^ohxb@%*x=FkeR-l7V;+3vK?Btv+;!6FA{UAQEKbKF;F58@Gn;DXH zm}$2CbQ{V@An_x@)oC+5)$uF@I{6qz6x&7Y{F?krImCZ8pX7O!4OauDEH!-MUdt!> z;rxU?F?y$M{tZy_cMqSG^?p9__ZXj)=><M<f0a+%lOc-GD@ZfYf8#IVq(76W^Q6Cj zW2XKGqdxiJER%_o9}fB-%;dj0sgtsRJxZUH1)TrpjQ#IK|Nl5k<eh8gUt!^q(ygj{ z=%DjgU%z^gP0jn>GRSZ4HE`9hn~n;Wv7%bTP59q-_rbfJ#`%Q5tBx6~3>!Z3J^j0E z|BvE--(839I#s=Qmvt8#VV!=V_*eW!hnUKMGWFm!2c2r}!5<tP)5$me@k<B(-t?tX zqgR-asJ#hfcJP&A-%A*5L#GV~*f80KeQcOu!x$SX8@3%b_Z=)79<bqF8#dVR2^(&) z;lnoEY{Lg^xXFh1*l?o_H`wrY8{THa^)_5<!=*MXvtf}9gYnO?%`<G6W5Wy^rr9vX zhRHTeuwk4Hl?|;gO!*JkusZ{OSO+>c+V;C`*kHpgHr#B(O*Y(U!}T_-wqb=0XWKBt zhN(78wqb$|V{E8w*!H=}XR8e@8#dYSfDIdMxZ8#eHr!&vO*UL_!)hB=*f1D>zHQF4 zVTKJ;Y?y3AWkc&TlfO4?__7TfY<Rm3t8Lhk#vRE0e;lp7@c4CG=LG(@-GvU{MvILT zyUu?`q_J;|F)%OI!1Z={^Tr!9-G-jyy1N;3u>4{#ziOHM{TqLs%huW4IqA;soz4HM z|9>_7zdQcU`RQ!#oc@2z|8G*@yY88Uclt%xzhG$(gq!xd+lImRKGAN+Bk?F-uzy%@ z_Y-B)O}PIqTxtJqv*WF><Na5m@VDf%GoL^34>Ml;pMtX1l%LF#<fkr;k|pl{xgV>B zO1@<FnK>?^UgvwbcbIwu_yP;~8Q3=hxAx`?BKQ-)p?#16fTsX+_-+Rmcrgp>6z~k- zaD)q+PYKg7zCY`9>=S^e@`?Xc;1s_6USTQ^ID$od5qK)FhHvnxVd@^>+kAb%4*`d8 znL_MSfO~9wFYuky$$vlm0GACk@e3T|G-bI6IAD+oD=?E!^56#EZ`*GIzGmY^XOOqS z@Sx-k_)EUs;P(J`^1Tec8yGkX88)~YN<4g@gKq*p!?(UKet?HlNEdpx0k1jRlqDZH z@Enr|C-4>IHaYk?08AaO)B<pU@9;GxQ!d~&BiJRwJ|Ea0#*;c406d*DnmfRqz+dn+ zCWWaD!0=RLJbgHy1iX>6nJM7QfIs4svabiq^gIW9Iot8tIO<w(;MVi0FYqUTy)PhL z@BzU27m_ac0^l8d63+%;k95jTKI4Gr@JZRdz}xu5kHCj*T;NxHQjZB2u@l61fH*UN zv-z69^MM6?hrla<*YR24Uf{EQ66aoE$#_%V1;EewgjNC%O;GAX{0qD@1KA8T*$7N^ zQFr~JE%06z9jVxF0^XDb9l+5grZ)3Q{7sXPIe847=Kvq#lRQ5RJUbgc!+#p^YCiFw z4@{cOc_i$U1@h^-05<SRSb?8i3eVu@bD%HB*e?a<<{~?zy@(E`IzI7#Gw?1Oe*ze= zaW1H+v3vvYKMuH%PtvLY4xD0eC-6^s)H{AGV9%*0&WnI|AY7Y`{RZG$e3E|)*nfuc zGXVJU<&+UWt-wXI@B>}}{LIEb2VOth*e?S{BA}D@F7S_hyTLaD&%V;oa5!)&pOi~r z(N!E}kvM^$^QFQw0&kpS>hU(<4Odey*e?S%@JSg3-ggagVZRC3Iv0K$Kt6#z^9}DM z0IT>UEidpEJ}KjEz<_PfC3JN)-|fV+9{6{@P2f$yg@u#_yc+m}BFX|@2E3`*q`MaQ zw-WS~Vt)X5&H}rPz$xYMANF~`Yb!WIDPe)P^65MP`(J1L4*-6|Hyplg1rDv`zC3se za1o#6A9YtMs>;wd2KexD`eFPCoV>!slLH*Kl70jG;lLTyv^{Wv7N4XWxr#oMZxi-= zfnha<Zjrz`K508Q13k5d&H{U^;jts^<A9lbk{>s44WGoh7P!&I1y=mf#3OLyTGJ;8 zEMI5(w+dj1pRt3!dI50G&8FWLcpIP8ufV-FE^uW%yn+9OA0b!Zy9j&+@aRto4=(V9 zpTVo(jll4q8y-jnesu@=5I?|Me?dKh-v<2WFX?l@KL=KBPz*}&0C2~zX@lSb|9m&? z3;bcA^B&W03q0puV?P{N&nGn52+X^We1hi#WA5iXIJgt|555d=4ydR{_&nfSfUooA zfWHC!l27P4{I~S;zgMaZd-NHqhxjD^hk;K%K%WBM0DP5C{2u`J{DYxe0x<bc&<;NW zf5oTs1}xuf@Cx8&J_#$Z=0U?hwZPav8$1qJwiUi19)XuWPX9@tnFBoYFO&;>Fwn=B z555$5$xg$Q9^jjNQjbl*?Yr1-$IlL6-`yq;$-pIil82>&KT93qXFV`#uToEdCje*i zNnbr1_-h;A2z-@K%5?yE_VXqW!+|^br2p9sJmWR`Si%kl?&lNUei^vpAazY&Q4Rc@ zPx2t}j@PMo>~{e7zDa$73taye`v~9y@8OeiP2l7v({^%z(TAv7{KNoj_+(ymJ23Tq z`Yh}P9^-ohT>V3-QGAkaDzL)F1^(8?w*V6@`Vjp00p8urSO$I%u-^xSB@Y9Dv-r6D zpwMfnZV-ELxrZWmR^0dzDEB?Q@VP*_$04{txvwF91j@Yz!3D~_1HlE#{Q$uQF0gUA zBOvGd#a^JCsTW+}E*ls4iH*ydc{%Scegw*yR>1{k+jt&O&N_>|Ksoy>`4lMUdc|I# zoTn9BpqxDwT%epQ6<pxOHZEsNud#8c^q=4Npg^Sd6QLr2DX@J{U<FY22-gAu`e*z_ z>vhjY>}7qj1t{Sff#MF^R!0HxRNW0g^Q(>qrUC)_XW|LdH#j|A*wb26ei!x<c&Rwr zzhFFKTzeAx+fQP@=_K}BPGZ0NB=!eRVsCX}FLKy6>|<_a&IR!fnF6TR+Zgw;51NyI z#{4Fx-P~{|V<tomx~JTO`;c~X;~vZj?dGKi@lV`A|4o0#42^<j&s$-f0c$s>;O6AZ z;A6JH-;@7FjvT2jx#SWxYt}4PT3V`nKA)-<@72}(uU5C;e!IH={`=L|ty@(?LxXzt z)mPQAW5<*%U&WX9jG<Lbaq7o=tGUy+Ysr#*+PE+9$<gY#qf3@7TP7Yp3G6+(FR=Fr z&bu(jVEBZvn3pUOv$YQ;+}ez7K*jLqlfcmu?Y?ALYs`lP4(zneOZLUIN%)cy;+Nk_ z@xOOpNy$Fa*Jd4mNeNF_2k^5};y;SJ{P3gwOL+N}9l?B*^!M%5W)hM3-;(t8?+EFm z;C~<aBes$f$=}g^U%rLuuz1k<Uww4l-lKaDOB`Z8Hf>He9*&j~Kjx?>_VhV>!`^)q zp+x8tbKnoFdJ6&gwTbzgHDeNU_U^;S&3GsN-~M8Bn(?5`ZO`w!=ZpvTYQN%6xDQ<y z1=<K6r~U8S`@-Eb_O>0}SKT0H=o9#6=2LA)wX^t#zRerj0@_*AU!t&#v-sCa&<_}A z9ly?-L@x2IwSNuTsE!V7SlJX&J)xSVN{253Jd97X#z~;Ki@%QHB%ZFmmDmTWRTy6c zUo@YCZ(u<9Jb};2_g#EGZrnK5WoRUwK3&~#!woubK^|Yfe!cqL?|!Eqe)wU{<FCB( zihA$8_d<MLA;$wY(}!+;ELu4I#)=yQkCr^8RzCH~Qzh4ytCdty$y2<y_EgJUIN{or zAAd3TQIM5)zQ_AuUzaT3^WMyvGoLES8TWhO+-oOaHzg2wWNu(Z-O#75nmJdk4BY+H zBQqtwtv{0ZR|Wzf9XYaDX)eBzxz50WfrRLR0Tp3?lpWG_{RRDqfB77SPC}y$O(!~{ zZ}|-wGDHm<HVpj>scQWA@yg{wA8dBErrp%3Q`O~{U#_mW;tF;3)mN((MU&M0`SaBe ze((deaN$B#S&5!e`j6$ym#g3SCaB-vFkU^hB3;$Y&r&yEo2hOqcd1`iW~jfcx={V0 zI$Ql>)jajs?G<Y0k1th?cVDYgo(!nrPY2ZKodGprM?jtXY(QP~LO{)VKA<vRMqG9< zpr*bRP*r?0-wCLz{t-}xD36=>VL+`~wMy01)u~%<xkdf_=Ra3>+;NB6uwjGRxN)Pp z_uhMT{cdKW{KzAZ=)UZUC!SC*ZQra`e;QDav<B2O&pe~{?AfE9fBt#3fB$~<^2;x) zg9i_)H{X0yee&J`_0m5B>g~7R)_l?2+^jzT<OB8YmjTt<+NzEmIih(*$QnM1^>ZF) zaA2C4^~}XL!#p(ho~`g{pqCmS7_F`fOjXwhu2Z)MZc&c}9#k&}_6Pe@)ratB<T1Wh zC^ddP>x#|DE(kxrm9a9AsMZmF1L6Nj_y)qiNcck?!k<O>j69{TtYGf79vRVQ=A(pv zx|R7e;SUi0?}UGs@Xdt(gz$$ugdcSl>mL`qeiid#FY|ELXZu*ov~H&nzL=;22S%&F zn^RTb&~+;C!7VD#`k)FN-XF^Us6K>0gYc<@znJj3geR`nQo>)Kr~>OotH7_Os=%MF zQ-N)_5a)v`@ZSFR@Jv4PA_?D(@ZAX?OL+R9Rwgk4XD=1Fc(e-4nW_ReT&Ds*zeNQe zeNY8n-rpWx^;CJPFY}#2YCXE{HluxXADrKc?%qJ+l`1g0LItMYqypD%P=Q<itO5`2 zR)PI*bqMby{CR}WA^beTFD3ks2!9XZA0qsdgx^JY(!Avj!oNrO)=>E2XsfuC7)puZ zhs1C%G3+3Qw~3)OF`)iAI-owE8c>I?3#cQv1k{%g2GrO41EKK!2|t4H69_+z@P&k5 zO!&2gzaufA?i(FY4^IuKr>_gBeYXVE8xICl%l`K8F@zTiBoV$p;Rg}^EW!^b{Kbg@ zHG6bGT{ktLZoZDVZV9NT9t^01``g1G-!;rNzmArfnG;<TU2biab56>T!DpOt)+Hei zu8EVgv)%5=nG+_s+;c~y3>`XT@Fka=IoI~!&c>Pl*&uHB++k;nhf6MT+U}EcGqWa7 zAo{FK*My0#xx>Z7kRfLbvfZ<DGhCBhneI%&OU_0PA2#e_JCEXJa_;2dZ&Lr{zH>+7 zL1Gwu#vtdJWHMXgpFBBx!sNN9_3oF9J04PO4`<CK`~;UokU4p7|K7d(8F!t>!Dl$h zWOgY2xk-I`_r7$zj$oKB<sjV2zgxn)Cga|x_i2~fdCNIRvOxH`6I{8MO`e=JdG4ta zLBHg_eNTytiyM$5c@%e1>Yhs~b5A|a!(1VQxMybNW>21+o0U88I1jiFJx9ksG1omg zE7zSn>GV^R>?BBG?%63LawxyVpQ)1wQf=-<$z(xH&`-xdIz1N>=VndL)rHV`4AP(c z&vlQ^kSt8j&7FJdq)EMd_ofgb_qpeFo0~BzizF_?{q#wbbSVdf+%p|fj<lYsS(Dwl zP<hfoUCPrY+3YdlLYHeygd-|-!ra`sx!GB{CYN*}=9is0Zer%B$gtSUYzLuLwwvzC zcAtB}sD$p_!om_g<WRDhJ9z?()b8#&|J>BE-6LXpW#gDR5ndiQE;F;;eeT?et|{p~ zqod9vh0M7Ud$zkh{kfUKcT>{i!=p3AJ#zx=Iyo2|`u%_Hoe6Z6)wRbjRi1!VV&7{G z6q^tf0(lygA^`#k5-K=BwMB}y8ZinAVTepmAYrJWAVaklp-2V_n0phM1O#Q0D#cb2 zL~$rVM2#SVGBhf(-~V@VPrQTx0eo-0x0YwEopZl?zwewqpMCZ|_Xhq*!BWq^=)$gd zbi6U8t#qy8V}0&h=ctQX-`GKX>=N-Y{7-Xt=>1kLI<}RmM1JhXmwc~FlOlHM)Ur*b zk0ZvHpu2QvbL`Wyk7L`7#|$q2YHPB~>gJ^EP;jwEkW&t46VGL9jLKkD#d0};luGg3 z$>S6s&)t0U%`P4pm2quF>@jax`@n=godVMbbqp*S(<!iE#;8E64T>q`=Q_V-f$oYO zh#7{df8vQJ0yAgM49uD}E0C9$7nn0=j*Ar*FJA28!4)f31c(*3u9+8@sd!_7VukhV z*9TsG^;H)e?Alop*tv6OVArl)fjxWn1U~)r)4&&>?{l%ip+koP-+c2;VA{Vduu!qW z>t9Fs*~Erg=vrx^lU+{jrG;*|7P=`~=;j74vL%5lZB^ixwjnUkwgjfxdx3@aq1Nwj z*O@?~7Q}ARdR~j|)c@4;SL^vyJ%62^zfI2%)br!@{471cNYDRG&zDrJGvCK4V&C_1 z%KytarGB8i)vsS)Mx<P7J^t2@zAP~@u^F#o>(`I2->_Ls)P)yPQ>_;lf7xYCE=#;9 zs&3N@bX~t;qb5ys??q8Di3y1bfd+BS;u9~alX#JCxbT7te%7GjW$}sU*NOjG_>I`u z_-2W<YW*-?&ouqfg%{M1zPMT9`L$}*sa><?51ZDlTmRgDtKaOB^J~@Njl`&!AD>s_ zyg1#Pn0QI;nvDOG=pX#MuFh{%r*`cG?E@NK_S173=u<s%iLNz&LWBQk(kLM@F`<d@ z*Zj>A5-v?hXqe#WYoHdZ*07<w3}n|;?c_Y&s94!S4fRzu-uL%#zn%-kxSU`>;d$Ur zL5)DH{+?C)fu2^x9#F(y0X6lSng2K1iKsu>+~9k@;KwmBF%8uNmkJu!u3cL@ApP8y z<CH>Zm5T%y2t3F2@;hnphjF#LsaAu(Q3BLIcJ}Pqw`$#4xo_XTk3ReCvyZj*?A*I| z?}zG34jw$XPy5nc@4ffl!k1rud7{qwBqS#%OY@Pw`>F`zXm{o0b~^k+)-23FYTUSS zBlYl#^m27t^li7@mU6Y4ZvLtAh*PwWw$-aw+s7Y&Y+6rEc^48?R#H-8+J76Liw4sk z{GX+zrJsn__cw3e{M6dDYqPJp=9(572RStmTr9Xq04~V2P8fI%kNNB;f=dJ!D_7B? ztgP%Sz1G56ZT#zr->=CAf6f@KTD58ne!|P)zj5P6Q;yVxpDka$+~KVpl6~~iN49Cx zCR0wq-N!SE5qN)>o|(OH;lh#2mMt5pu&>kDv17Xq7%(7h^5n_g6jy^=Q$fPT7hl{$ zxs9GzU3C?_i%v^Ri)UQDJ}vwY95`T#Wu`T1)TpI+IC=N(-KLyw1)pDg?KOM*?YAAC zl8?h3+3eV{!`^-OU3U#l9u)Jq*V4IzpMU;&ne^^!jamBDS6|r|Uwm<3>(;H$eel5t zC7SC?o)Mjo$=+HDhsiv9y7()eGR;*1;O_yxdO#)~z#m@G``26po(_8O@gSVdgJf<V z{CmDX6Z~I%@x@7!W1Mti9JH)kx6aXkekk8$$Uu1}r!U}$O~{5_zh%o71F#L`L63c4 zJ3RBsE3Y^jkfH3~kb`pdq;M;muD{m%NBCSee3fXZuKm_KeE6_w8FKocl$6vMJqD10 z@@BSj<w}#xO);~xVPt?zlvi^A?i)62Fl=Spwr%b;G~ff!H|zu%f!k93KhKPJ%u-%8 z`}yC@68~zJp#RN$#Tv7lH<}fGXm;rE;VrTi?7uqA;lFCts%e*AdTC3=@RQ{)P4aLw z;B$}xe1#rl0q(p;{@b^2cff0S4!^+{U4RzwhX3ej{-<VXZ<?iUHfyUCd@I!qT5J#v z>&=>phQ=?L#jP-#{GMt9M~-l6p*qdsFJEsSz~6(Hh40VAPOt;?<<{+H*KX5yIkt-b z&>$IH{fgODq9OAw)jN(T-~GB-^Hol*_E!ga-BV9_QgnGzixw^7qzmJqLvnERcsl6e zC3*z^tD*zG!*gVW-k|^ZUG3Q%LS2Rb_3xI`aE-n{*<QG|5e>>G+W^r8{(ZKXUHW{v zSyUH)tr_P1Kl-or$N(=7dhqvpj{YML^a|bZv|!`t8G4Ux_#V5U-SWQKO`_pC>Hjap zZ)j+@$*lE1%4ujWTTq_d;#a%d@uSsg^}t`gc$#wjEhUG^*cra1Dmu{jNSS!OqKE%{ z&bq*}_?gJoeV1$$8vbe4MKp904GZ>0-f_a$pX-wuCm^QYmtTHqT4#;{Xz<|as7fZD zmPk6j{`zZs{kd88ml4<5jDackME_KWSkI5le*J;jFL#*T2n}zC?O8gL?Clw!Bzwju zHI^M<&zDP|u<4_!vsFQZ!(Z~Aq})ZE{Q5X(!5`9l8tBn`^tv(~Ucb<FbgAU;OKjfI zWGfil&YsF@?`VL4-+p5Dn=lRCO3ZE$PMt+Vg*`(<*q*PzC&{N?CZE($G{h_~_pKUc zbR`-b{&8_}75-mqJnQ^%^1yys54=3E2d=%HfWQ2nt@+d4795^zbBDIGe9<sVG|<xJ zKW`TeJ>=tmwbKk5ygfsMw`Y9Pl`o6$FPb%l2Jt`kIkT?vQ);hPg}?m0(|_68Wa1%g z&eP#(K?bY`kuveL(1SmI^4ZZHtoXsURwx?&A{z1@D91l*pV^&zL_?|Bt)c;Y#wT4T zpXBWs8oWJ2gSTgVQv6DX|Gz5ZkDal;D9)+?Xz);(4sR=wbnqG)Xv?x&+oBO|toXm$ z+S9{C!;p4%X#Z||OXds>cZden*zDE_d&VbW&mCk7_@pHHB-Ur|lbWnHYgCSZWxrGp z{1x9%YT2@7oMM!5(1Bm1M`xgen1>!(c#pN#$7OuRdP~eeTanY+mX2y|3q?bbXqYb= zo`15x9o#47sYd%mboP@>l31TbgO4$qtSW!FGXL=xUjN&)Y10^4c)(u48{EL%(}M5E z-?Oj5Z?aagw$WCNNwVie!?UB>*n$ylEhHK$+w&jglcx3SV3Y2@#wPUXXk+i~XxVqC z*~Gy;ZTnlB3>qS13}?^sNwli)m%n%VFMKA0J9yE96L@0}@Y%}*A0HVX6AwWn`v2mD z_V$8kSS}itj1&#B1?(9buxEVIlk%(3Fcli^yT-=%77h2L*{HiaIU2x|7=!iM#~3ZO zzNsCj|M(2nFyaVc{`~nC3<iz3)Pt7?{mJY^d0E@^RJyGl+sd9FEgEDCi$%jTVSC0W z<qd9cvj(-d=>t;i@yt}4(zk<66b%oFhB2aHq-da3jxl~G+fX~s|A4=A!Rf#BdK|Po z^w2{V3WXd!o(B38(E&~97SEQxzS!1{Yh`Oh!%ETM>{&G6le|6W$|wDKP>TI&K&m|^ z8YYW|M?}N#rAMPP(j21rqz(}=#$wsM+Hw9L{Js9SZQHgnIDn^4g;dahTq5Z>87<#@ zbHv_XJH!4usiUnPn`A4)_KZ*R_B=;E2^waGY50TmX!89X?BPD;G=Qj!F%)m#Aebe8 zb=2&YO1jTwJ!G!+cbd*IT$h=dxe;8kM{Ho!s8NoFNd2lzOJ$jGjZeT9PSxI8UtAGm zV9$?+?YYu(Cyjr=AK7>A+!;C8(@#I`VlQGE<p*rYkRcT`oQ#f>$pn1xNlWlar?O|! zK&yh+RlQXYKIyE@TKP_E(xi#qamO8|vl&KQmz9-e4?OUIO`0^x*|kzW&hHQlRYeQD zXKlb&5epHIvLB#f&#%oLY)8J*exqQBTc0Cij3>kPJXN+ps|s2Fo^lm+73=>>*AD;7 zFTeb19qq}~zu?}ZINHe}KR@5PcI|39TV#(u`lzX<WRE}oxWkA2J^Y3S)&kZE^a@}P z0}c37^pLd>9<864W}D}M|6$uWXUMlPhHQZt1AE3N%@}qg=$~@`rQF}cDus?lf28Zv zwC``Jb1)&<u<0|?|HL!dgmHcS_1C+&N9SRj{{(k%MMluzf%o7yy2n0;*bZ4>57@M` zXUT!}+1oQdDbk+*zHBye;7rf!ll84zw|-n_dR!iaxx=<>I-_VhlVr+iS<|LXO|iAZ z1w4p1A^{pacsl4A4?w5<*!b3e%(}~-|9z^~=kgeX^*K1Qqb+;vUVHbIrFQtxp)Hbk zwet@;OKIcAjXR(-N;YQ9m_t2#_O!lz`#QdBU+HuS8n6rUKHvr&m1!Xd!8(lI6C+_O z<ReyVKgoN<NURgkQbiLBzTA$yPB;I<ShC$*<tR%YeDJ}e;Hh(?4zOuYL$hYhOlQ}e z99T2Zd14<=2l#?NIuD)f4d}54Yy^AoGNDHYiB0_4!`_?yv-IV(@}Jli`Y&C|(|NHs zuv1mUZN!KXP7ct3UsZ0|di3bw-bV(|-~k%^zLz~EF*bS+p7iJtw0ZsFePSwNZuycw zDED-=&KXW&4{;{=qxS&1M7|lCz>S=<&fYou?bxxSrKYBuPNz6I@Hx+T8tA=Vd6{@S z!9Kv<_vjIO2K0(J5ZU?shVZA{_CrB+n)9Ecdy+~3apK`P?D>TkUT`$PAM%E>4@X0K zdb-_k!wpWiRFil3!)tgBE#QqE;D30ZJp%eeti4)xfDK?1jEfHz?ngDwxajEURLMPG zd8bk#P0fe8PIa1#AG{6{|9HNFPf1CM!$-0;#TJ|@cJ?57oAk};0BaO{=6--{Xuyxc zQ~dv;MT@MsxY(_M&ph*tdyX7|_*5$2_FJuyBZT`py*FM+Q}?KD{iYuH693@;Wsj4& z#@^_`1-auFq^B;HP@Tm2R@u5+-|#i)H#!IY*a3ElOwbc#Kt7Aled9IbA|vF%dM<kZ zBE0dN)CsHG9R6NU=_7R*8a#j-bfH7o!uavyO+L$5rz0D<dEgoR48Dkl{;($kz#Y0~ z&z?<=F;`!UKV96R(c$mofAM=9G<d)0Y4J4B!*6_()^4{?K&M!1Bl!!iT!TNd@i7E- z9rPYug6G(fe8zO)aVEG|;2){~_=re(R3#JWBFBFF?YEoG<vRWLJdf<T4_!jnd7m`^ z+<kpSd!$)sfxE+>IsE=tYtLl#k~IiAutE5Q|G?L=9!1Io-Y#9b)Mm_>;q)1Pdw_0q z2iqZT;u@V{Jk|pF%z66hgfrzkxYO!^Pvp7?{vM#g!^vdA7&;T}#zDt;2HL<E-C8Z* z2`wIX#iw)6P~Xe3{`RlS|H!`F{#WbwIB0?Y^qvlSPX|3b#lK(+0J7md<bdzQPLUbD zh*|<QC}@H2n&V9T%(oaH`^w?(^<S|<WB3G|OeVzl#6QqQT@FCE=wEv2CFghH0rrZ% zgFkj4eVn7|&sJw5DX0fOeg0E^q9XqT4XmBSFZe(7fc1#A6CShYg!jmSSisAHYkWSw z7C)vvg{y0b=I<JJ=y3WUsT-B`++TaUjqK5NuDJ(Up!4t<8qsy>(NV<+rIHovDrYQC zXKez%Q?(!I2F@V-PXcpr_JMO6XWcAEi_7YvLyrW`v!f|Phwjk#bM}|_dgZRayZ)T; zcs0VkzWt*4)XuW^<N5I;@Xld)U9SoEJI<!h4&!O%eT{H`PPjiW+}92FG2uQX+-HY- zEAMO2#|xiWL8{;k&uN{jM~QC%^!bFbq9i?9pe(o@7DP6#si;)W2Wq$~8*@c#FW6jb z{&g7{8NXD#pQfCD2fg21K+OGPL4}?&_CL$ahN#xl`OWeg8@XU=3RkJNbGvfGZ+_uW zIvEbo+Ms65nys|A8z`GD!=EYUJS2bniPnNo<(J-3e4ej7*?o$E({%rpf;hz+`|eeZ zgE|?x&{XAbsd-Z`e&c}IYs$*$`$)9UbpMIkCGz0~nzIc5iH~Hz1P*|&VT5D;qw=c< z<a4*kZ?0fqYNpg1sdG_ZAtz3KXzM|<O`^RTwcZ%~wDJn+$~|=l2Vy7oo~)1fb=D$$ zHL)yl3ZL<scAIKd)I6!RQRCtK0yQe?JJkKDvC&RMyxxyt51>70ruGZ>vHr5IvCm~* z;%Imhrr*U*<s+8=rC!!kxm)Ue)XJ9ZkNmXC*A%fL^})^0evlXe00#j74!{%Eue~3> zWAny#cXbK!;k3K<s@}D`yl#4naG>tX83=Ow)O@`@QtzeCn5=&5u{s&Unxg${y5ijK z;NfvW{=~rG!uqrF$$l=UP0g8{yq_N&ekUBLds07l`Y0TzwNc|iAE{AM>!eQj8`+53 zhOkUxSjUxj$<+7n?qh8RJPyPh@Pyd9cvMGM>!UtH9+Ae}0JT@@$JG2H^^vnI)M%*n zQDZ_M6JBtS9`^GS2l@IU>nd@YkKa5lJV9QWTwsCnnbdssT{;^r8;isNee7OIA9a4; z*#u{4(8o%3x)|nHJtbXvh3=7fFgJQmPov&Ojf8q3b*iO*8gR;*;qI@@29>DhDI7S@ zgH2GgrFr^^D~1mro|&DUeIGF>;PD`D0xxLf*Qqs8<DgbXor(Gebuwy9)HbM*QC}L- zs~nyf)5pNU>7(kdzV^*{k@MpN0Ad>;5)W`e{%gml81=42!hxJ7xp8VN=p%J5>MPV5 zU5zU||H!+4!BoyBygs%QAJi)3Pi&?-M7q9r*&ScNexLXpy1@k=&~Gm2<LZXgtEk;l zGo<!BJ6tcsCa8~4E6h=i%JYE9B7HQqTeS-P$F}s{-c0%b`>;j)4*LT3cJKt>13wOy zzHJ*H>*neN<fqX`YWU=)y-iSOqSi;9EIW(?lXWX8ujAjYx!?O2?^O7p7~)HG5IZF1 zrw0!JegNPBpOC}J+Lm?CxSA=ox^cpRdTFJ0od09~i4!NLKlRj8-Kh-`kAnw1XJ5^p zn!G7^zzh5lpV6q_at^@TL{<98ePLazs*54UR=y%r`Idh0Vak*#&hO!OS^x0==mPve z7nvJeXxPMOJKwOqJKvN|RMJP;1o}v;YGSYd?8nJ-kkf_7?5|{tZoh?Xf|Hj|q->DI zU#E4m{kz_<eILB}tv<>os9&RxGe`Y~>8o7-<y(ojW0+sHi1$-ci0X#A+O&RC!5(?! z5x2hsC;TFI03PrF`M{e4rSI6QdH36MV>`IB0A3&ShyTJB{c(Wp*`?s*TU|Sb4ei^v zZ=rneaOhASv;SRp-Sx7*zis#5f4|EE>x`t!UHH8ZJcl3fpZy)W06)OLa$`*0w^_Os zxz-*tKNqTt{aSYK_JOSR)McnGDb6yT`*w8u{TFxu@B=(5%Le>dx9}b8OEvt}0^+-q zwHWrGia&N!OQbHL@0l9;S8y0OaG>Km{(yCmvAqs37k<Ips@91ks>|FfUCvUBbX1da z=IK;>su*}B-cRk_yZ1}fc*xP~3;%{JsIO^VcJmMqz<1^ch{=f2e6O|YEAjI|jWt{K zioKeft-z_8(?4vGv54*9H@RGNkX$--4eSFveeMbw;1_rfT;K(M8=ncDt5>g{qKPj& z)#Uoz*}v+y>G~dBcjjhH<O~k_odDDC3fN6I-Q;is2Y`F90q#R@h?DRaoJ&+LJWu1Y zSEx>N{ulqFbM*HyUWsz@toisHY76?!0#{?kF2IilAAF9Nc$u0Cal2^vvnH+X+~DWt z_xcQ90q_8rkM&5uk>Gp-XH}scokL#m8oKex%Dv1z&AHwD%p+gp{C`z=_!wB<IWT?S z(dCMX3&}a5k7qHrn;&}p`im|>FJl7uJZuizhE8;h^E;fq(DwqIe>g+BnVS{^{gwG1 z$$w-3;Cu0X$XUM$f&T4PKI~zQLH^`S8{ajFIzzy|PUYWDh}V%AeP_2u#rJh%a>NTk z4MCt9z<vIi7(D`{=sgeFdJR}k6~DofbKLiKV*@8@I;+LlRW|8k$Jw)IFHw!=uzb{K zIv4VXxpU_p<9Ad8*rzf27Zw(}_jS*?1qB6Nl+RvOR8-{T>DMsiET8^n<Yd&-bpDw< z>(?4%hxG3tcF5iseJ$1=<QBzsoNG+c-fE`yfojYA7~G3a6T|s<#@iIW><;al*fWts z*sQST=Q`J^=Huf4^#kU@*6>RJ`pUDkbZt-A11~EN$=rM4KZn#W#W!I`;7aU(Zf|;i zj!o-d9vk)w@88%zvVUc-z+R=f_DW9*FKVsq$-y1{XWpkrb#XDy0qwzN3TMV(FV5bJ zTm<_*_MJ)EcaozfrUGyL7L7d&d#J^K9B7OY+4jiAlG7oNz@82MAt%-#;vm|}hdQ}< zi~R?C5B5I9y6iVXe}32)gMD~s;eq`0+cU1tjSqtlJJ#pf(wuf~KS}IP+|Is%z0=5y zYuy~Tl$g!ezE<D!w(RU|cSeM|8nQ%RJpbLz`m<^60vGp>)ZQoDAof}Kr**;kEoyR{ zAK+Q9a|=hcx7|CoIDWE+`h6ca|3R-m=pMcvzk@9G-F3%Pd^NJ%zAoPujk(sH=bkm} zdfT{S9@9VTpVxO+T&#xwLT~Wf#9YV&e;SDkuUX6ev-I5W<qz+C+*P7=lKEMW*e5VH zepzdOcI5N;Y4Bzoc%jdoJ+Wq!PvTkj*{t2F#T@f2<BU2l)FDa`I42AN^(O*<5BCFg zxwnQAnX$1^>d$q*xTfEij4Hq4_tt)(&$y?S`?a-m^jY~8zqNL*e$j}lSoce7HN$u6 zO85L*_|91OD{JQklGC%YGWy-scX;fuetk2u+QkhXl-VY$SMQ8|=~<We>(gsc|E&J^ zJaBoh{{7mdXZ5>c$dz%i{n9i0+>?>z|Ep)axGS${9@qYYI<c|I4-6Wd<^IoYHAibv z{+yo7%IGy%{}yw&8z)vRc~Hi{!I~xG?rwwn4AFmLyf-7O;={;~I}OvL{KwN9GKOUI zjqS_dc5&%hT{4ICzdvJ8T<qXJ9eVZBzw~SucTalXtc<w!$%z$XANz2{_z`y;H+yp8 zF}NltRuHYnlM_8Z+jr~GtwUN`mz%Eb(Ifog`|IzHANq+O_vPN@`D^kw<Zsgd_}QP| zydbFny=Mb6KX-ZVhTLtrrMYFfweq6#;`5U7I_LGs>zy|&Z$jSmy!m;{^ETvd%PY+* z%i{+g-@s^dqjGbeo?1A)Ft>1i;ex{Dg=-2o6mBZqR=A_Ev~Yi6Sz#bpD;O1w4#o!K zgUy3U!PH>qV7Fk8;GMzV!2!Wx!JOcP;MCysU~X`Ja6xc+a7}PSa8qzwa7VB#7zou0 zMTMe6v7z`-^H5SKHPkuOEz~1)XQ+2*KxkMfCo~~6H8eex8=4<l5LzBu6WS2k6xtTr z5h@Ms50!-iMYW2eilU2Ri{gu#7bO*?7IiLKUbL;KtSGuTsd!lN)Z*#IxyAE~7Zk54 z7A>jz?OSyN@`vT;<WI<-o}ZgPKYu~K=hwFU9pYJ8exRUMK~zC>L2N;MLGyxc1w9Jx eEa+V@pkP=*PQiqNsRh%;(eK;$9QeP+f&T_bxyt<j literal 0 HcmV?d00001 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/util.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/util.py new file mode 100755 index 0000000..9d4bfd3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/util.py @@ -0,0 +1,1756 @@ +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import codecs +from collections import deque +import contextlib +import csv +from glob import iglob as std_iglob +import io +import json +import logging +import os +import py_compile +import re +import socket +try: + import ssl +except ImportError: # pragma: no cover + ssl = None +import subprocess +import sys +import tarfile +import tempfile +import textwrap + +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import time + +from . import DistlibException +from .compat import (string_types, text_type, shutil, raw_input, StringIO, + cache_from_source, urlopen, urljoin, httplib, xmlrpclib, + splittype, HTTPHandler, BaseConfigurator, valid_ident, + Container, configparser, URLError, ZipFile, fsdecode, + unquote, urlparse) + +logger = logging.getLogger(__name__) + +# +# Requirement parsing code as per PEP 508 +# + +IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') +VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') +COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + if os.path.exists(path): + os.remove(path) + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.write_binary_file(path, data.encode(encoding)) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None, hashed_invalidation=False): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + compile_kwargs = {} + if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'): + compile_kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.CHECKED_HASH + py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) + \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) + \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.split('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' + r'\(\s*(?P<ver>[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/version.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/version.py new file mode 100755 index 0000000..3eebe18 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w32.exe b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w32.exe new file mode 100755 index 0000000000000000000000000000000000000000..732215a9d34ccb7b417d637a7646d9b843ecafa8 GIT binary patch literal 89088 zcmeFae|S?>wm*FGqitH!CO`{C3REl(SahnPNDYM`O{q#T7)Xdvz$<hz5gjb&0FD$| zPs=nt#$jgk-tk`NUb*PJIy$3wMg@OiORy=5PEkZ0P^;6cyPm2=Y8#~Xyq~pC(iU~@ z_dd`2ywCg3TS)e=wSTX@_S$Q$y;FJf9>F9Cf*Bu86NCeB>CeT#|L3nblC!40kR?2m z{>H@z3`^g*ct!B1Tk<#8{Ol(+x7?n8>n(TO@iQ_1pEl;#NO$D_^p5<p8@>6r|7^p? zD>5@P3KB)%InlPUc<U{5lb_$uJ2!U@!dIxT&CTYnHuoCtzCL#`-1%8w%`JjkymkHD zpYr&>Cg9H}+(GW%^wV2|ROUbGfyXTfOART)i?<!WISJD#7!6|#8G`TvV*Xu^z32+K zc6>T0?9%;4K}Zn{6fx`yPa}*$9C+R!7zI~72c&$InY+UdMGBkF3c`HyxD3K09`bzW z?_q;rO&5ec#{?noJ4vI19bbHBt~vx^h2FH$V8i|^#EsiUg#JboP3@w-(&Uf&%NK<8 zSJZ5{MZ852W)~s>WeT(LIf&1wKNqULLI)GN_(-E-D)X~ZK=1;t<%*guHMhdg`-(mb zHzDv1KBN9zR9?--O+N$ReOXAr81V9z!X5SJ5`=3<1^<8V|AP@&sr2}Qvp;hQT24iW zOHg|EiZd1ojV;oo#(r^ba2`^8T22{~_UQ@YMZp7O1R*2@?SerFE~TuJB_wDaYC0h8 zfONF1t%{=H`W`bdYp+>YBsg9Ty9ec3iy+O3xa}TIvPK#Q&udyx1MvwG0(#iaGC|N| zJ#3?<Y4YLRkU`54s9BYRjyISA>){9$tW;Y34lPnX=&>D4X~|k7c$TwEfOzs@Yh#Nz z`FV;`(w!E`sKg@`2E}bDY>ku^4XS@tV(WO*<eu67;0Clk;vRHp!Qf<+5w0B!*Y>g? zYH=KK#%%Yu1~&m>IlB^#2^syGG|2AB1(}4aOcaC%!)}%`I7AIC2(Ro3yW`GSttng^ z_xb=ECor!L{-PNO>_ulJ3%fm=O0X!s%)$GZ?~I94l-^KEAX0n$?4wGpr7&i4#~)OB zQD%2NrWUKtZuYT1Vnu}AeF`cSgx>Rkk@}Lg{WltgT76VeA2aic`cTnpXrt2WXmJkM z9%u<Rp-*9{$HQ)>Xm?McyDyZ28Ux7mpxy?mnmvzMMr-85vkRrJLaDRx>|I7je+cM+ zj{RJ(3Vrgke;W@#D!y%U%fQLtlPKTAzWtVuOQdXpwsy6eRjt^cZ%0D4bF7$F;f!th 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ð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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w64.exe b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/w64.exe new file mode 100755 index 0000000000000000000000000000000000000000..c41bd0a011fd760ce20ba795d9e535e0d2c39876 GIT binary patch literal 99328 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 B=L-M; literal 0 HcmV?d00001 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/wheel.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/wheel.py new file mode 100755 index 0000000..b04bfae --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distlib/wheel.py @@ -0,0 +1,988 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import base64 +import codecs +import datetime +import distutils.util +from email import message_from_file +import hashlib +import imp +import json +import logging +import os +import posixpath +import re +import shutil +import sys +import tempfile +import zipfile + +from . import __version__, DistlibException +from .compat import sysconfig, ZipFile, fsdecode, text_type, filter +from .database import InstalledDistribution +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, + cached_property, get_cache_base, read_exports, tempdir) +from .version import NormalizedVersion, UnsupportedVersionError + +logger = logging.getLogger(__name__) + +cache = None # created when needed + +if hasattr(sys, 'pypy_version_info'): # pragma: no cover + IMP_PREFIX = 'pp' +elif sys.platform.startswith('java'): # pragma: no cover + IMP_PREFIX = 'jy' +elif sys.platform == 'cli': # pragma: no cover + IMP_PREFIX = 'ip' +else: + IMP_PREFIX = 'cp' + +VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') +if not VER_SUFFIX: # pragma: no cover + VER_SUFFIX = '%s%s' % sys.version_info[:2] +PYVER = 'py' + VER_SUFFIX +IMPVER = IMP_PREFIX + VER_SUFFIX + +ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') + +ABI = sysconfig.get_config_var('SOABI') +if ABI and ABI.startswith('cpython-'): + ABI = ABI.replace('cpython-', 'cp') +else: + def _derive_abi(): + parts = ['cp', VER_SUFFIX] + if sysconfig.get_config_var('Py_DEBUG'): + parts.append('d') + if sysconfig.get_config_var('WITH_PYMALLOC'): + parts.append('m') + if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: + parts.append('u') + return ''.join(parts) + ABI = _derive_abi() + del _derive_abi + +FILENAME_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))? +-(?P<py>\w+\d+(\.\w+\d+)*) +-(?P<bi>\w+) +-(?P<ar>\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + wheel_metadata = self.get_wheel_metadata(zf) + wv = wheel_metadata['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if file_version < (1, 1): + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] + else: + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy for sorting + p = to_posix(os.path.relpath(record_path, base)) + records.append((p, '', '')) + records.sort() + with CSVWriter(record_path) as writer: + for row in records: + writer.writerow(row) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. If kwarg ``bytecode_hashed_invalidation`` is True, written + bytecode will try to use file-hash based invalidation (PEP-552) on + supported interpreter versions (CPython 2.7+). + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + bc_hashed_invalidation = kwargs.get('bytecode_hashed_invalidation', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile, + hashed_invalidation=bc_hashed_invalidation) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' %s' % v.flags + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + if cache is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('dylib-cache'), + sys.version[:3]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = not path.endswith(METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distro.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distro.py new file mode 100755 index 0000000..aa4defc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/distro.py @@ -0,0 +1,1197 @@ +# Copyright 2015,2016,2017 Nir Cohen +# +# 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. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is a renewed alternative implementation for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.7 is expected to remove it +altogether. Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and is also expected to be removed in Python 3.7. +Still, there are many cases in which access to OS distribution information +is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = {} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release' +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current OS distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the OS distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular OS distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current distribution, as a + machine-readable string. + + For a number of OS distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + "openbsd" OpenBSD + "netbsd" NetBSD + "freebsd" FreeBSD + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the OS distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file, appended + with the value of the pretty version ("<version_id>" and "<codename>" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "<version_id>" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current OS distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current OS distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current OS distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "<codename>" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current OS + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current OS distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current OS distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def uname_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + """ + return _distro.uname_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +def uname_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + """ + return _distro.uname_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a OS distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current OS distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file='', + include_uname=True): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + distro release file can be found, the data source for the distro + release file will be empty. + + * ``include_name`` (bool): Controls whether uname command output is + included as a data source. If the uname command is not available in + the program execution path the data source for the uname command will + be empty. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + * ``include_uname`` (bool): The result of the ``include_uname`` + parameter. This controls whether the uname information will + be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + self.include_uname = include_uname + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "include_uname={self.include_uname!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r}, " \ + "_uname_info={self._uname_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the OS distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the OS distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + distro_id = self.uname_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the OS distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') \ + or self.uname_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') \ + or self.uname_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the OS distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', ''), + self.uname_attr('release') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = u'{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the OS distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the current distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the current distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the OS distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the OS distribution. + + For details, see :func:`distro.codename`. + """ + return self.os_release_attr('codename') \ + or self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the OS + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the OS distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the OS + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the OS + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def uname_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the uname command data source of the OS distribution. + + For details, see :func:`distro.uname_info`. + """ + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the OS distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the OS distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the OS distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + def uname_attr(self, attribute): + """ + Return a single named information item from the uname command + output data source of the OS distribution. + + For details, see :func:`distro.uname_release_attr`. + """ + return self._uname_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * commands or their arguments (not allowed in os-release) + if '=' in token: + k, v = token.split('=', 1) + if isinstance(v, bytes): + v = v.decode('utf-8') + props[k.lower()] = v + if k == 'VERSION': + # this handles cases in which the codename is in + # the `(CODENAME)` (rhel, centos, fedora) format + # or in the `, CODENAME` format (Ubuntu). + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + else: + props['codename'] = '' + else: + # Ignore any tokens that are not variable assignments + pass + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _uname_info(self): + with open(os.devnull, 'w') as devnull: + try: + cmd = ('uname', '-rs') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_uname_content(content) + + @staticmethod + def _parse_uname_content(lines): + props = {} + match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) + if match: + name, version = match.groups() + + # This is to prevent the Linux kernel version from + # appearing as the 'best' version on otherwise + # identifiable distributions. + if name == 'Linux': + return {} + props['id'] = name.lower() + props['name'] = name + props['release'] = version + return props + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + Returns: + A dictionary containing all information items. + """ + if isinstance(line, bytes): + line = line.decode('utf-8') + matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( + line.strip()[::-1]) + distro_info = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="OS distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/__init__.py new file mode 100755 index 0000000..0491234 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +<https://whatwg.org/html>`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.0.1" diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py new file mode 100755 index 0000000..4c77717 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,288 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name", DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name", DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_inputstream.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_inputstream.py new file mode 100755 index 0000000..a65e55f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,923 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type, binary_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re + +from pip._vendor import webencodings + +from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase +from .constants import _ReparseException +from . import _utils + +from io import StringIO + +try: + from io import BytesIO +except ImportError: + BytesIO = StringIO + +# Non-unicode versions of constants for use in the pre-parser +spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) +asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +else: + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) + +non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF]) + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + def unget(self, char): + # Only one character is allowed to be ungotten at once - it must + # be consumed again before any further call to unget + if char is not None: + if self.chunkOffset == 0: + # unget is called quite rarely, so it's a good idea to do + # more work here if it saves a bit of work in the frequently + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except: # pylint:disable=bare-except + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overriden, we've been overriden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, bytes): + """Look for a sequence of bytes at the start of a string. If the bytes + are found return True and advance the position to the byte after the + match. Otherwise return False and leave the position alone""" + p = self.position + data = self[p:p + len(bytes)] + rv = data.startswith(bytes) + if rv: + self.position += len(bytes) + return rv + + def jumpTo(self, bytes): + """Look for the next sequence of bytes matching a given sequence. If + a match is found advance the position to the last byte of the match""" + newPosition = self[self.position:].find(bytes) + if newPosition > -1: + # XXX: This is ugly, but I can't see a nicer way to fix this. + if self._position == -1: + self._position = 0 + self._position += (newPosition + len(bytes) - 1) + return True + else: + raise StopIteration + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + methodDispatch = ( + (b"<!--", self.handleComment), + (b"<meta", self.handleMeta), + (b"</", self.handlePossibleEndTag), + (b"<!", self.handleOther), + (b"<?", self.handleOther), + (b"<", self.handlePossibleStartTag)) + for _ in self.data: + keepParsing = True + for key, method in methodDispatch: + if self.data.matchBytes(key): + try: + keepParsing = method() + break + except StopIteration: + keepParsing = False + break + if not keepParsing: + break + + return self.encoding + + def handleComment(self): + """Skip over comments""" + return self.data.jumpTo(b"-->") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have <meta not followed by a space so just keep going + return True + # We have a valid meta element we want to search for attributes + hasPragma = False + pendingEncoding = None + while True: + # Try to find the next attribute after the current position + attr = self.getAttribute() + if attr is None: + return True + else: + if attr[0] == b"http-equiv": + hasPragma = attr[1] == b"content-type" + if hasPragma and pendingEncoding is not None: + self.encoding = pendingEncoding + return False + elif attr[0] == b"charset": + tentativeEncoding = attr[1] + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + self.encoding = codec + return False + elif attr[0] == b"content": + contentParser = ContentAttrParser(EncodingBytes(attr[1])) + tentativeEncoding = contentParser.parse() + if tentativeEncoding is not None: + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + if hasPragma: + self.encoding = codec + return False + else: + pendingEncoding = codec + + def handlePossibleStartTag(self): + return self.handlePossibleTag(False) + + def handlePossibleEndTag(self): + next(self.data) + return self.handlePossibleTag(True) + + def handlePossibleTag(self, endTag): + data = self.data + if data.currentByte not in asciiLettersBytes: + # If the next byte is not an ascii letter either ignore this + # fragment (possible start tag case) or treat it according to + # handleOther + if endTag: + data.previous() + self.handleOther() + return True + + c = data.skipUntil(spacesAngleBrackets) + if c == b"<": + # return to the first step in the overall "two step" algorithm + # reprocessing the < byte + data.previous() + else: + # Read all attributes + attr = self.getAttribute() + while attr is not None: + attr = self.getAttribute() + return True + + def handleOther(self): + return self.data.jumpTo(b">") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +def lookupEncoding(encoding): + """Return the python codec name corresponding to an encoding or None if the + string doesn't correspond to a valid encoding.""" + if isinstance(encoding, binary_type): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py new file mode 100755 index 0000000..178f6e7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1721 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, + 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, + 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, + 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, + 0xFFFFF, 0x10FFFE, 0x10FFFF])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.state = self.dataState + else: + # XXX data can be _'_... + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-char", + "datavars": {"data": data}}) + self.stream.unget(data) + self.state = self.bogusCommentState + return True + + def tagNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rawtextLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rawtextEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rawtextEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def scriptDataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEndTagOpenState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) + self.state = self.scriptDataEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.scriptDataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapeStartDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.state = self.dataState + else: + chars = self.stream.charsUntil(("<", "-", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapeStartState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py new file mode 100755 index 0000000..a5ba4bf --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie as PyTrie + +Trie = PyTrie + +# pylint:disable=wrong-import-position +try: + from .datrie import Trie as DATrie +except ImportError: + pass +else: + Trie = DATrie +# pylint:enable=wrong-import-position diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py new file mode 100755 index 0000000..a1158bb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py new file mode 100755 index 0000000..e2e5f86 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import, division, unicode_literals + +from datrie import Trie as DATrie +from pip._vendor.six import text_type + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + chars = set() + for key in data.keys(): + if not isinstance(key, text_type): + raise TypeError("All keys must be strings") + for char in key: + chars.add(char) + + self._data = DATrie("".join(chars)) + for key, value in data.items(): + self._data[key] = value + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + raise NotImplementedError() + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + return self._data.keys(prefix) + + def has_keys_with_prefix(self, prefix): + return self._data.has_keys_with_prefix(prefix) + + def longest_prefix(self, prefix): + return self._data.longest_prefix(prefix) + + def longest_prefix_item(self, prefix): + return self._data.longest_prefix_item(prefix) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/py.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/py.py new file mode 100755 index 0000000..c178b21 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_utils.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_utils.py new file mode 100755 index 0000000..0703afb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,124 @@ +from __future__ import absolute_import, division, unicode_literals + +from types import ModuleType + +from pip._vendor.six import text_type + +try: + import xml.etree.cElementTree as default_etree +except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # We need this with u"" because of http://bugs.jython.org/issue2039 + _x = eval('u"\\uD800"') # pylint:disable=eval-used + assert isinstance(_x, text_type) +except: # pylint:disable=bare-except + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + def __init__(self, items=()): + # Using _dictEntries instead of directly assigning to self is about + # twice as fast. Please do careful performance testing before changing + # anything here. + _dictEntries = [] + for name, value in items: + if isinstance(name, (list, tuple, frozenset, set)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/constants.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/constants.py new file mode 100755 index 0000000..1ff8041 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2947 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring '</>'.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in + adjustForeignAttributes.items()]) + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +asciiLetters = frozenset(string.ascii_letters) +digits = frozenset(string.digits) +hexDigits = frozenset(string.hexdigits) + +asciiUpper2Lower = dict([(ord(c), ord(c.lower())) + for c in string.ascii_uppercase]) + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100755 index 0000000..5ba926e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/base.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/base.py new file mode 100755 index 0000000..c7dbaed --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100755 index 0000000..aefb5c8 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ``<meta charset=ENCODING>`` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/lint.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/lint.py new file mode 100755 index 0000000..fcc07ee --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100755 index 0000000..4a86501 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an <code>optgroup</code> + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100755 index 0000000..af8e77b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type <application>/<type> + (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('<script> do_nasty_stuff() </script>') + # => <script> do_nasty_stuff() </script> + # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') + # => <a>Click here for $100</a> + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "</%s>" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py new file mode 100755 index 0000000..0d12584 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/html5parser.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/html5parser.py new file mode 100755 index 0000000..ae41a13 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types +from collections import OrderedDict + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def normalizedTokens(self): + for token in self.tokenizer: + yield self.normalizeToken(token) + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def normalizeToken(self, token): + # HTML5 specific normalizations to the token stream + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + token["data"] = OrderedDict(raw) + if len(raw) > len(token["data"]): + # we had some duplicated attribute, fix so first wins + token["data"].update(raw[::-1]) + + return token + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((value, key) for key, value in + tokenTypes.items()) + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + try: + info = {"type": type_names[token['type']]} + except: + raise + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), self.endTagImplyHead) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + class InHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("title", self.startTagTitle), + (("noframes", "style"), self.startTagNoFramesStyle), + ("noscript", self.startTagNoscript), + ("script", self.startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + self.startTagBaseLinkCommand), + ("meta", self.startTagMeta), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("head", self.endTagHead), + (("br", "html", "body"), self.endTagHtmlBodyBr) + ]) + self.endTagHandler.default = self.endTagOther + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + class InHeadNoscriptPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), + (("head", "noscript"), self.startTagHeadNoscript), + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("noscript", self.endTagNoscript), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + self.startTagFromHead), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + self.endTagHtmlBodyBr)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + self.startTagProcessInHead), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + self.startTagCloseP), + (headingElements, self.startTagHeading), + (("pre", "listing"), self.startTagPreListing), + ("form", self.startTagForm), + (("li", "dd", "dt"), self.startTagListItem), + ("plaintext", self.startTagPlaintext), + ("a", self.startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), self.startTagFormatting), + ("nobr", self.startTagNobr), + ("button", self.startTagButton), + (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), + ("xmp", self.startTagXmp), + ("table", self.startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + self.startTagVoidFormatting), + (("param", "source", "track"), self.startTagParamSource), + ("input", self.startTagInput), + ("hr", self.startTagHr), + ("image", self.startTagImage), + ("isindex", self.startTagIsIndex), + ("textarea", self.startTagTextarea), + ("iframe", self.startTagIFrame), + ("noscript", self.startTagNoscript), + (("noembed", "noframes"), self.startTagRawtext), + ("select", self.startTagSelect), + (("rp", "rt"), self.startTagRpRt), + (("option", "optgroup"), self.startTagOpt), + (("math"), self.startTagMath), + (("svg"), self.startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), self.startTagMisplaced) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("body", self.endTagBody), + ("html", self.endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), self.endTagBlock), + ("form", self.endTagForm), + ("p", self.endTagP), + (("dd", "dt", "li"), self.endTagListItem), + (headingElements, self.endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), self.endTagFormatting), + (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we + # want to drop leading newlines + data = token["data"] + self.processSpaceCharacters = self.processSpaceCharactersNonPre + if (data.startswith("\n") and + self.tree.openElements[-1].name in ("pre", "listing", "textarea") and + not self.tree.openElements[-1].hasContent()): + data = data[1:] + if data: + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(data) + + def processCharacters(self, token): + if token["data"] == "\u0000": + # The tokenizer should always emit null on its own + return + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + # This must be bad for performance + if (self.parser.framesetOK and + any([char not in spaceCharacters + for char in token["data"]])): + self.parser.framesetOK = False + + def processSpaceCharactersNonPre(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + + def startTagProcessInHead(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagBody(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "body"}) + if (len(self.tree.openElements) == 1 or + self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + else: + self.parser.framesetOK = False + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[1].attributes: + self.tree.openElements[1].attributes[attr] = value + + def startTagFrameset(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) + if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + elif not self.parser.framesetOK: + pass + else: + if self.tree.openElements[1].parent: + self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) + while self.tree.openElements[-1].name != "html": + self.tree.openElements.pop() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagCloseP(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + + def startTagPreListing(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + + def startTagForm(self, token): + if self.tree.formPointer: + self.parser.parseError("unexpected-start-tag", {"name": "form"}) + else: + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + + def startTagListItem(self, token): + self.parser.framesetOK = False + + stopNamesMap = {"li": ["li"], + "dt": ["dt", "dd"], + "dd": ["dt", "dd"]} + stopNames = stopNamesMap[token["name"]] + for node in reversed(self.tree.openElements): + if node.name in stopNames: + self.parser.phase.processEndTag( + impliedTagToken(node.name, "EndTag")) + break + if (node.nameTuple in specialElements and + node.name not in ("address", "div", "p")): + break + + if self.tree.elementInScope("p", variant="button"): + self.parser.phase.processEndTag( + impliedTagToken("p", "EndTag")) + + self.tree.insertElement(token) + + def startTagPlaintext(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.plaintextState + + def startTagHeading(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + if self.tree.openElements[-1].name in headingElements: + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagA(self, token): + afeAElement = self.tree.elementInActiveFormattingElements("a") + if afeAElement: + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "a", "endName": "a"}) + self.endTagFormatting(impliedTagToken("a")) + if afeAElement in self.tree.openElements: + self.tree.openElements.remove(afeAElement) + if afeAElement in self.tree.activeFormattingElements: + self.tree.activeFormattingElements.remove(afeAElement) + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagNobr(self, token): + self.tree.reconstructActiveFormattingElements() + if self.tree.elementInScope("nobr"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "nobr", "endName": "nobr"}) + self.processEndTag(impliedTagToken("nobr")) + # XXX Need tests that trigger the following + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagButton(self, token): + if self.tree.elementInScope("button"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "button", "endName": "button"}) + self.processEndTag(impliedTagToken("button")) + return token + else: + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + + def startTagAppletMarqueeObject(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.activeFormattingElements.append(Marker) + self.parser.framesetOK = False + + def startTagXmp(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.reconstructActiveFormattingElements() + self.parser.framesetOK = False + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagTable(self, token): + if self.parser.compatMode != "quirks": + if self.tree.elementInScope("p", variant="button"): + self.processEndTag(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.parser.phase = self.parser.phases["inTable"] + + def startTagVoidFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagInput(self, token): + framesetOK = self.parser.framesetOK + self.startTagVoidFormatting(token) + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + # input type=hidden doesn't change framesetOK + self.parser.framesetOK = framesetOK + + def startTagParamSource(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagHr(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagImage(self, token): + # No really... + self.parser.parseError("unexpected-start-tag-treated-as", + {"originalName": "image", "newName": "img"}) + self.processStartTag(impliedTagToken("img", "StartTag", + attributes=token["data"], + selfClosing=token["selfClosing"])) + + def startTagIsIndex(self, token): + self.parser.parseError("deprecated-tag", {"name": "isindex"}) + if self.tree.formPointer: + return + form_attrs = {} + if "action" in token["data"]: + form_attrs["action"] = token["data"]["action"] + self.processStartTag(impliedTagToken("form", "StartTag", + attributes=form_attrs)) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processStartTag(impliedTagToken("label", "StartTag")) + # XXX Localization ... + if "prompt" in token["data"]: + prompt = token["data"]["prompt"] + else: + prompt = "This is a searchable index. Enter search keywords: " + self.processCharacters( + {"type": tokenTypes["Characters"], "data": prompt}) + attributes = token["data"].copy() + if "action" in attributes: + del attributes["action"] + if "prompt" in attributes: + del attributes["prompt"] + attributes["name"] = "isindex" + self.processStartTag(impliedTagToken("input", "StartTag", + attributes=attributes, + selfClosing=token["selfClosing"])) + self.processEndTag(impliedTagToken("label")) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processEndTag(impliedTagToken("form")) + + def startTagTextarea(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.rcdataState + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + self.parser.framesetOK = False + + def startTagIFrame(self, token): + self.parser.framesetOK = False + self.startTagRawtext(token) + + def startTagNoscript(self, token): + if self.parser.scripting: + self.startTagRawtext(token) + else: + self.startTagOther(token) + + def startTagRawtext(self, token): + """iframe, noembed noframes, noscript(if scripting enabled)""" + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagOpt(self, token): + if self.tree.openElements[-1].name == "option": + self.parser.phase.processEndTag(impliedTagToken("option")) + self.tree.reconstructActiveFormattingElements() + self.parser.tree.insertElement(token) + + def startTagSelect(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + if self.parser.phase in (self.parser.phases["inTable"], + self.parser.phases["inCaption"], + self.parser.phases["inColumnGroup"], + self.parser.phases["inTableBody"], + self.parser.phases["inRow"], + self.parser.phases["inCell"]): + self.parser.phase = self.parser.phases["inSelectInTable"] + else: + self.parser.phase = self.parser.phases["inSelect"] + + def startTagRpRt(self, token): + if self.tree.elementInScope("ruby"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "ruby": + self.parser.parseError() + self.tree.insertElement(token) + + def startTagMath(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustMathMLAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["mathml"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagSvg(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["svg"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMisplaced(self, token): + """ Elements that should be children of other elements that have a + different insertion mode; here they are ignored + "caption", "col", "colgroup", "frame", "frameset", "head", + "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", + "tr", "noscript" + """ + self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) + + def startTagOther(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + + def endTagP(self, token): + if not self.tree.elementInScope("p", variant="button"): + self.startTagCloseP(impliedTagToken("p", "StartTag")) + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + self.endTagP(impliedTagToken("p", "EndTag")) + else: + self.tree.generateImpliedEndTags("p") + if self.tree.openElements[-1].name != "p": + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + node = self.tree.openElements.pop() + while node.name != "p": + node = self.tree.openElements.pop() + + def endTagBody(self, token): + if not self.tree.elementInScope("body"): + self.parser.parseError() + return + elif self.tree.openElements[-1].name != "body": + for node in self.tree.openElements[2:]: + if node.name not in frozenset(("dd", "dt", "li", "optgroup", + "option", "p", "rp", "rt", + "tbody", "td", "tfoot", + "th", "thead", "tr", "body", + "html")): + # Not sure this is the correct name for the parse error + self.parser.parseError( + "expected-one-end-tag-but-got-another", + {"gotName": "body", "expectedName": node.name}) + break + self.parser.phase = self.parser.phases["afterBody"] + + def endTagHtml(self, token): + # We repeat the test for the body end tag token being ignored here + if self.tree.elementInScope("body"): + self.endTagBody(impliedTagToken("body")) + return token + + def endTagBlock(self, token): + # Put us back in the right whitespace handling mode + if token["name"] == "pre": + self.processSpaceCharacters = self.processSpaceCharactersNonPre + inScope = self.tree.elementInScope(token["name"]) + if inScope: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + if inScope: + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagForm(self, token): + node = self.tree.formPointer + self.tree.formPointer = None + if node is None or not self.tree.elementInScope(node): + self.parser.parseError("unexpected-end-tag", + {"name": "form"}) + else: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1] != node: + self.parser.parseError("end-tag-too-early-ignored", + {"name": "form"}) + self.tree.openElements.remove(node) + + def endTagListItem(self, token): + if token["name"] == "li": + variant = "list" + else: + variant = None + if not self.tree.elementInScope(token["name"], variant=variant): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + else: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError( + "end-tag-too-early", + {"name": token["name"]}) + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagHeading(self, token): + for item in headingElements: + if self.tree.elementInScope(item): + self.tree.generateImpliedEndTags() + break + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + for item in headingElements: + if self.tree.elementInScope(item): + item = self.tree.openElements.pop() + while item.name not in headingElements: + item = self.tree.openElements.pop() + break + + def endTagFormatting(self, token): + """The much-feared adoption agency algorithm""" + # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 + # XXX Better parseError messages appreciated. + + # Step 1 + outerLoopCounter = 0 + + # Step 2 + while outerLoopCounter < 8: + + # Step 3 + outerLoopCounter += 1 + + # Step 4: + + # Let the formatting element be the last element in + # the list of active formatting elements that: + # - is between the end of the list and the last scope + # marker in the list, if any, or the start of the list + # otherwise, and + # - has the same tag name as the token. + formattingElement = self.tree.elementInActiveFormattingElements( + token["name"]) + if (not formattingElement or + (formattingElement in self.tree.openElements and + not self.tree.elementInScope(formattingElement.name))): + # If there is no such node, then abort these steps + # and instead act as described in the "any other + # end tag" entry below. + self.endTagOther(token) + return + + # Otherwise, if there is such a node, but that node is + # not in the stack of open elements, then this is a + # parse error; remove the element from the list, and + # abort these steps. + elif formattingElement not in self.tree.openElements: + self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) + self.tree.activeFormattingElements.remove(formattingElement) + return + + # Otherwise, if there is such a node, and that node is + # also in the stack of open elements, but the element + # is not in scope, then this is a parse error; ignore + # the token, and abort these steps. + elif not self.tree.elementInScope(formattingElement.name): + self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) + return + + # Otherwise, there is a formatting element and that + # element is in the stack and is in scope. If the + # element is not the current node, this is a parse + # error. In any case, proceed with the algorithm as + # written in the following steps. + else: + if formattingElement != self.tree.openElements[-1]: + self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) + + # Step 5: + + # Let the furthest block be the topmost node in the + # stack of open elements that is lower in the stack + # than the formatting element, and is an element in + # the special category. There might not be one. + afeIndex = self.tree.openElements.index(formattingElement) + furthestBlock = None + for element in self.tree.openElements[afeIndex:]: + if element.nameTuple in specialElements: + furthestBlock = element + break + + # Step 6: + + # If there is no furthest block, then the UA must + # first pop all the nodes from the bottom of the stack + # of open elements, from the current node up to and + # including the formatting element, then remove the + # formatting element from the list of active + # formatting elements, and finally abort these steps. + if furthestBlock is None: + element = self.tree.openElements.pop() + while element != formattingElement: + element = self.tree.openElements.pop() + self.tree.activeFormattingElements.remove(element) + return + + # Step 7 + commonAncestor = self.tree.openElements[afeIndex - 1] + + # Step 8: + # The bookmark is supposed to help us identify where to reinsert + # nodes in step 15. We have to ensure that we reinsert nodes after + # the node before the active formatting element. Note the bookmark + # can move in step 9.7 + bookmark = self.tree.activeFormattingElements.index(formattingElement) + + # Step 9 + lastNode = node = furthestBlock + innerLoopCounter = 0 + + index = self.tree.openElements.index(node) + while innerLoopCounter < 3: + innerLoopCounter += 1 + # Node is element before node in open elements + index -= 1 + node = self.tree.openElements[index] + if node not in self.tree.activeFormattingElements: + self.tree.openElements.remove(node) + continue + # Step 9.6 + if node == formattingElement: + break + # Step 9.7 + if lastNode == furthestBlock: + bookmark = self.tree.activeFormattingElements.index(node) + 1 + # Step 9.8 + clone = node.cloneNode() + # Replace node with clone + self.tree.activeFormattingElements[ + self.tree.activeFormattingElements.index(node)] = clone + self.tree.openElements[ + self.tree.openElements.index(node)] = clone + node = clone + # Step 9.9 + # Remove lastNode from its parents, if any + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + node.appendChild(lastNode) + # Step 9.10 + lastNode = node + + # Step 10 + # Foster parent lastNode if commonAncestor is a + # table, tbody, tfoot, thead, or tr we need to foster + # parent the lastNode + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + + if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): + parent, insertBefore = self.tree.getTableMisnestedNodePosition() + parent.insertBefore(lastNode, insertBefore) + else: + commonAncestor.appendChild(lastNode) + + # Step 11 + clone = formattingElement.cloneNode() + + # Step 12 + furthestBlock.reparentChildren(clone) + + # Step 13 + furthestBlock.appendChild(clone) + + # Step 14 + self.tree.activeFormattingElements.remove(formattingElement) + self.tree.activeFormattingElements.insert(bookmark, clone) + + # Step 15 + self.tree.openElements.remove(formattingElement) + self.tree.openElements.insert( + self.tree.openElements.index(furthestBlock) + 1, clone) + + def endTagAppletMarqueeObject(self, token): + if self.tree.elementInScope(token["name"]): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + if self.tree.elementInScope(token["name"]): + element = self.tree.openElements.pop() + while element.name != token["name"]: + element = self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + + def endTagBr(self, token): + self.parser.parseError("unexpected-end-tag-treated-as", + {"originalName": "br", "newName": "br element"}) + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(impliedTagToken("br", "StartTag")) + self.tree.openElements.pop() + + def endTagOther(self, token): + for node in self.tree.openElements[::-1]: + if node.name == token["name"]: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + while self.tree.openElements.pop() != node: + pass + break + else: + if node.nameTuple in specialElements: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + break + + class TextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([ + ("script", self.endTagScript)]) + self.endTagHandler.default = self.endTagOther + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processEOF(self): + self.parser.parseError("expected-named-closing-tag-but-got-eof", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + return True + + def startTagOther(self, token): + assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] + + def endTagScript(self, token): + node = self.tree.openElements.pop() + assert node.name == "script" + self.parser.phase = self.parser.originalPhase + # The rest of this method is all stuff that only happens if + # document.write works + + def endTagOther(self, token): + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + + class InTablePhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("caption", self.startTagCaption), + ("colgroup", self.startTagColgroup), + ("col", self.startTagCol), + (("tbody", "tfoot", "thead"), self.startTagRowGroup), + (("td", "th", "tr"), self.startTagImplyTbody), + ("table", self.startTagTable), + (("style", "script"), self.startTagStyleScript), + ("input", self.startTagInput), + ("form", self.startTagForm) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "tbody", "td", + "tfoot", "th", "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableContext(self): + # "clear the stack back to a table context" + while self.tree.openElements[-1].name not in ("table", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + # When the current node is <html> it's an innerHTML case + + # processing methods + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-table") + else: + assert self.parser.innerHTML + # Stop parsing + + def processSpaceCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processSpaceCharacters(token) + + def processCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processCharacters(token) + + def insertText(self, token): + # If we get here there must be at least one non-whitespace character + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processCharacters(token) + self.tree.insertFromTable = False + + def startTagCaption(self, token): + self.clearStackToTableContext() + self.tree.activeFormattingElements.append(Marker) + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCaption"] + + def startTagColgroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inColumnGroup"] + + def startTagCol(self, token): + self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) + return token + + def startTagRowGroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inTableBody"] + + def startTagImplyTbody(self, token): + self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) + return token + + def startTagTable(self, token): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "table", "endName": "table"}) + self.parser.phase.processEndTag(impliedTagToken("table")) + if not self.parser.innerHTML: + return token + + def startTagStyleScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagInput(self, token): + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + self.parser.parseError("unexpected-hidden-input-in-table") + self.tree.insertElement(token) + # XXX associate with form + self.tree.openElements.pop() + else: + self.startTagOther(token) + + def startTagForm(self, token): + self.parser.parseError("unexpected-form-in-table") + if self.tree.formPointer is None: + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + self.tree.openElements.pop() + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processStartTag(token) + self.tree.insertFromTable = False + + def endTagTable(self, token): + if self.tree.elementInScope("table", variant="table"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "table": + self.parser.parseError("end-tag-too-early-named", + {"gotName": "table", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "table": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processEndTag(token) + self.tree.insertFromTable = False + + class InTableTextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.originalPhase = None + self.characterTokens = [] + + def flushCharacters(self): + data = "".join([item["data"] for item in self.characterTokens]) + if any([item not in spaceCharacters for item in data]): + token = {"type": tokenTypes["Characters"], "data": data} + self.parser.phases["inTable"].insertText(token) + elif data: + self.tree.insertText(data) + self.characterTokens = [] + + def processComment(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEOF(self): + self.flushCharacters() + self.parser.phase = self.originalPhase + return True + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.characterTokens.append(token) + + def processSpaceCharacters(self, token): + # pretty sure we should never reach here + self.characterTokens.append(token) + # assert False + + def processStartTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEndTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + class InCaptionPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-caption + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableElement) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("caption", self.endTagCaption), + ("table", self.endTagTable), + (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagCaption(self): + return not self.tree.elementInScope("caption", variant="table") + + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableElement(self, token): + self.parser.parseError() + # XXX Have to duplicate logic here to find out if the tag is ignored + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagCaption(self, token): + if not self.ignoreEndTagCaption(): + # AT this code is quite similar to endTagTable in "InTable" + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "caption": + self.parser.parseError("expected-one-end-tag-but-got-another", + {"gotName": "caption", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "caption": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inTable"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + self.parser.parseError() + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InColumnGroupPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-column + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("col", self.startTagCol) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("colgroup", self.endTagColgroup), + ("col", self.endTagCol) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagColgroup(self): + return self.tree.openElements[-1].name == "html" + + def processEOF(self): + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + return + else: + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return True + + def processCharacters(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def startTagCol(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def endTagColgroup(self, token): + if self.ignoreEndTagColgroup(): + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + else: + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + + def endTagCol(self, token): + self.parser.parseError("no-end-tag", {"name": "col"}) + + def endTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + class InTableBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("tr", self.startTagTr), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), + self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "td", "th", + "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableBodyContext(self): + while self.tree.openElements[-1].name not in ("tbody", "tfoot", + "thead", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTr(self, token): + self.clearStackToTableBodyContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inRow"] + + def startTagTableCell(self, token): + self.parser.parseError("unexpected-cell-in-table-body", + {"name": token["name"]}) + self.startTagTr(impliedTagToken("tr", "StartTag")) + return token + + def startTagTableOther(self, token): + # XXX AT Any ideas on how to share this with endTagTable? + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.clearStackToTableBodyContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + else: + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagTable(self, token): + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InRowPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-row + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead", + "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("tr", self.endTagTr), + ("table", self.endTagTable), + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + (("body", "caption", "col", "colgroup", "html", "td", "th"), + self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods (XXX unify this with other table helper methods) + def clearStackToTableRowContext(self): + while self.tree.openElements[-1].name not in ("tr", "html"): + self.parser.parseError("unexpected-implied-end-tag-in-table-row", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + + def ignoreEndTagTr(self): + return not self.tree.elementInScope("tr", variant="table") + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTableCell(self, token): + self.clearStackToTableRowContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCell"] + self.tree.activeFormattingElements.append(Marker) + + def startTagTableOther(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTr(self, token): + if not self.ignoreEndTagTr(): + self.clearStackToTableRowContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTableBody"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # Reprocess the current tag if the tr end tag was not ignored + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagTr(impliedTagToken("tr")) + return token + else: + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-row", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InCellPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-cell + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("td", "th"), self.endTagTableCell), + (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), + (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) + ]) + self.endTagHandler.default = self.endTagOther + + # helper + def closeCell(self): + if self.tree.elementInScope("td", variant="table"): + self.endTagTableCell(impliedTagToken("td")) + elif self.tree.elementInScope("th", variant="table"): + self.endTagTableCell(impliedTagToken("th")) + + # the rest + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableOther(self, token): + if (self.tree.elementInScope("td", variant="table") or + self.tree.elementInScope("th", variant="table")): + self.closeCell() + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagTableCell(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.tree.generateImpliedEndTags(token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-cell-end-tag", + {"name": token["name"]}) + while True: + node = self.tree.openElements.pop() + if node.name == token["name"]: + break + else: + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inRow"] + else: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagImply(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.closeCell() + return token + else: + # sometimes innerHTML case + self.parser.parseError() + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InSelectPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("option", self.startTagOption), + ("optgroup", self.startTagOptgroup), + ("select", self.startTagSelect), + (("input", "keygen", "textarea"), self.startTagInput), + ("script", self.startTagScript) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("option", self.endTagOption), + ("optgroup", self.endTagOptgroup), + ("select", self.endTagSelect) + ]) + self.endTagHandler.default = self.endTagOther + + # http://www.whatwg.org/specs/web-apps/current-work/#in-select + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-select") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.tree.insertText(token["data"]) + + def startTagOption(self, token): + # We need to imply </option> if <option> is the current node. + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagOptgroup(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagSelect(self, token): + self.parser.parseError("unexpected-select-in-select") + self.endTagSelect(impliedTagToken("select")) + + def startTagInput(self, token): + self.parser.parseError("unexpected-input-in-select") + if self.tree.elementInScope("select", variant="select"): + self.endTagSelect(impliedTagToken("select")) + return token + else: + assert self.parser.innerHTML + + def startTagScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-select", + {"name": token["name"]}) + + def endTagOption(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "option"}) + + def endTagOptgroup(self, token): + # </optgroup> implicitly closes <option> + if (self.tree.openElements[-1].name == "option" and + self.tree.openElements[-2].name == "optgroup"): + self.tree.openElements.pop() + # It also closes </optgroup> + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + # But nothing else + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "optgroup"}) + + def endTagSelect(self, token): + if self.tree.elementInScope("select", variant="select"): + node = self.tree.openElements.pop() + while node.name != "select": + node = self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-select", + {"name": token["name"]}) + + class InSelectInTablePhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.startTagTable) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.endTagTable) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.phases["inSelect"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inSelect"].processCharacters(token) + + def startTagTable(self, token): + self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) + self.endTagOther(impliedTagToken("select")) + return token + + def startTagOther(self, token): + return self.parser.phases["inSelect"].processStartTag(token) + + def endTagTable(self, token): + self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagOther(impliedTagToken("select")) + return token + + def endTagOther(self, token): + return self.parser.phases["inSelect"].processEndTag(token) + + class InForeignContentPhase(Phase): + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", + "center", "code", "dd", "div", "dl", "dt", + "em", "embed", "h1", "h2", "h3", + "h4", "h5", "h6", "head", "hr", "i", "img", + "li", "listing", "menu", "meta", "nobr", + "ol", "p", "pre", "ruby", "s", "small", + "span", "strong", "strike", "sub", "sup", + "table", "tt", "u", "ul", "var"]) + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + def adjustSVGTagNames(self, token): + replacements = {"altglyph": "altGlyph", + "altglyphdef": "altGlyphDef", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath"} + + if token["name"] in replacements: + token["name"] = replacements[token["name"]] + + def processCharacters(self, token): + if token["data"] == "\u0000": + token["data"] = "\uFFFD" + elif (self.parser.framesetOK and + any(char not in spaceCharacters for char in token["data"])): + self.parser.framesetOK = False + Phase.processCharacters(self, token) + + def processStartTag(self, token): + currentNode = self.tree.openElements[-1] + if (token["name"] in self.breakoutElements or + (token["name"] == "font" and + set(token["data"].keys()) & set(["color", "face", "size"]))): + self.parser.parseError("unexpected-html-element-in-foreign-content", + {"name": token["name"]}) + while (self.tree.openElements[-1].namespace != + self.tree.defaultNamespace and + not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and + not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): + self.tree.openElements.pop() + return token + + else: + if currentNode.namespace == namespaces["mathml"]: + self.parser.adjustMathMLAttributes(token) + elif currentNode.namespace == namespaces["svg"]: + self.adjustSVGTagNames(token) + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = currentNode.namespace + self.tree.insertElement(token) + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def processEndTag(self, token): + nodeIndex = len(self.tree.openElements) - 1 + node = self.tree.openElements[-1] + if node.name.translate(asciiUpper2Lower) != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + while True: + if node.name.translate(asciiUpper2Lower) == token["name"]: + # XXX this isn't in the spec but it seems necessary + if self.parser.phase == self.parser.phases["inTableText"]: + self.parser.phase.flushCharacters() + self.parser.phase = self.parser.phase.originalPhase + while self.tree.openElements.pop() != node: + assert self.tree.openElements + new_token = None + break + nodeIndex -= 1 + + node = self.tree.openElements[nodeIndex] + if node.namespace != self.tree.defaultNamespace: + continue + else: + new_token = self.parser.phase.processEndTag(token) + break + return new_token + + class AfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processComment(self, token): + # This is needed because data is to be appended to the <html> element + # here and not to whatever is currently open. + self.tree.insertComment(token, self.tree.openElements[0]) + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-body") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def endTagHtml(self, name): + if self.parser.innerHTML: + self.parser.parseError("unexpected-end-tag-after-body-innerhtml") + else: + self.parser.phase = self.parser.phases["afterAfterBody"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class InFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("frameset", self.startTagFrameset), + ("frame", self.startTagFrame), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("frameset", self.endTagFrameset) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-frameset") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-in-frameset") + + def startTagFrameset(self, token): + self.tree.insertElement(token) + + def startTagFrame(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + + def startTagNoframes(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-frameset", + {"name": token["name"]}) + + def endTagFrameset(self, token): + if self.tree.openElements[-1].name == "html": + # innerHTML case + self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") + else: + self.tree.openElements.pop() + if (not self.parser.innerHTML and + self.tree.openElements[-1].name != "frameset"): + # If we're not in innerHTML mode and the current node is not a + # "frameset" element (anymore) then switch. + self.parser.phase = self.parser.phases["afterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-frameset", + {"name": token["name"]}) + + class AfterFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#after3 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("html", self.endTagHtml) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-frameset") + + def startTagNoframes(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-frameset", + {"name": token["name"]}) + + def endTagHtml(self, token): + self.parser.phase = self.parser.phases["afterAfterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-frameset", + {"name": token["name"]}) + + class AfterAfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class AfterAfterFramesetPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoFrames) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagNoFrames(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + # pylint:enable=unused-argument + + return { + "initial": InitialPhase, + "beforeHtml": BeforeHtmlPhase, + "beforeHead": BeforeHeadPhase, + "inHead": InHeadPhase, + "inHeadNoscript": InHeadNoscriptPhase, + "afterHead": AfterHeadPhase, + "inBody": InBodyPhase, + "text": TextPhase, + "inTable": InTablePhase, + "inTableText": InTableTextPhase, + "inCaption": InCaptionPhase, + "inColumnGroup": InColumnGroupPhase, + "inTableBody": InTableBodyPhase, + "inRow": InRowPhase, + "inCell": InCellPhase, + "inSelect": InSelectPhase, + "inSelectInTable": InSelectInTablePhase, + "inForeignContent": InForeignContentPhase, + "afterBody": AfterBodyPhase, + "inFrameset": InFramesetPhase, + "afterFrameset": AfterFramesetPhase, + "afterAfterBody": AfterAfterBodyPhase, + "afterAfterFrameset": AfterAfterFramesetPhase, + # XXX after after frameset + } + + +def adjust_attributes(token, replacements): + needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) + if needs_adjustment: + token['data'] = OrderedDict((replacements.get(k, k), v) + for k, v in token['data'].items()) + + +def impliedTagToken(name, type="EndTag", attributes=None, + selfClosing=False): + if attributes is None: + attributes = {} + return {"type": tokenTypes[type], "name": name, "data": attributes, + "selfClosing": selfClosing} + + +class ParseError(Exception): + """Error in parsed document""" + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/serializer.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/serializer.py new file mode 100755 index 0000000..53f4d44 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/serializer.py @@ -0,0 +1,409 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +import re + +from codecs import register_error, xmlcharrefreplace_errors + +from .constants import voidElements, booleanAttributes, spaceCharacters +from .constants import rcdataElements, entities, xmlEntities +from . import treewalkers, _utils +from xml.sax.saxutils import escape + +_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" +_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") +_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" + "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" + "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" + "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" + "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" + "\u3000]") + + +_encode_entity_map = {} +_is_ucs4 = len("\U0010FFFF") == 1 +for k, v in list(entities.items()): + # skip multi-character entities + if ((_is_ucs4 and len(v) > 1) or + (not _is_ucs4 and len(v) > 2)): + continue + if v != "&": + if len(v) == 2: + v = _utils.surrogatePairToCodepoint(v) + else: + v = ord(v) + if v not in _encode_entity_map or k.islower(): + # prefer < over < and similarly for &, >, etc. + _encode_entity_map[v] = k + + +def htmlentityreplace_errors(exc): + if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): + res = [] + codepoints = [] + skip = False + for i, c in enumerate(exc.object[exc.start:exc.end]): + if skip: + skip = False + continue + index = i + exc.start + if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): + codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) + skip = True + else: + codepoint = ord(c) + codepoints.append(codepoint) + for cp in codepoints: + e = _encode_entity_map.get(cp) + if e: + res.append("&") + res.append(e) + if not e.endswith(";"): + res.append(";") + else: + res.append("&#x%s;" % (hex(cp)[2:])) + return ("".join(res), exc.end) + else: + return xmlcharrefreplace_errors(exc) + + +register_error("htmlentityreplace", htmlentityreplace_errors) + + +def serialize(input, tree="etree", encoding=None, **serializer_opts): + """Serializes the input token stream using the specified treewalker + + :arg input: the token stream to serialize + + :arg tree: the treewalker to use + + :arg encoding: the encoding to use + + :arg serializer_opts: any options to pass to the + :py:class:`html5lib.serializer.HTMLSerializer` that gets created + + :returns: the tree serialized as a string + + Example: + + >>> from html5lib.html5parser import parse + >>> from html5lib.serializer import serialize + >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') + >>> serialize(token_stream, omit_optional_tags=False) + '<html><head></head><body><p>Hi!</p></body></html>' + + """ + # XXX: Should we cache this? + walker = treewalkers.getTreeWalker(tree) + s = HTMLSerializer(**serializer_opts) + return s.render(walker(input), encoding) + + +class HTMLSerializer(object): + + # attribute quoting options + quote_attr_values = "legacy" # be secure by default + quote_char = '"' + use_best_quote_char = True + + # tag syntax options + omit_optional_tags = True + minimize_boolean_attributes = True + use_trailing_solidus = False + space_before_trailing_solidus = True + + # escaping options + escape_lt_in_attrs = False + escape_rcdata = False + resolve_entities = True + + # miscellaneous options + alphabetical_attributes = False + inject_meta_charset = True + strip_whitespace = False + sanitize = False + + options = ("quote_attr_values", "quote_char", "use_best_quote_char", + "omit_optional_tags", "minimize_boolean_attributes", + "use_trailing_solidus", "space_before_trailing_solidus", + "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", + "alphabetical_attributes", "inject_meta_charset", + "strip_whitespace", "sanitize") + + def __init__(self, **kwargs): + """Initialize HTMLSerializer + + :arg inject_meta_charset: Whether or not to inject the meta charset. + + Defaults to ``True``. + + :arg quote_attr_values: Whether to quote attribute values that don't + require quoting per legacy browser behavior (``"legacy"``), when + required by the standard (``"spec"``), or always (``"always"``). + + Defaults to ``"legacy"``. + + :arg quote_char: Use given quote character for attribute quoting. + + Defaults to ``"`` which will use double quotes unless attribute + value contains a double quote, in which case single quotes are + used. + + :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute + values. + + Defaults to ``False``. + + :arg escape_rcdata: Whether to escape characters that need to be + escaped within normal elements within rcdata elements such as + style. + + Defaults to ``False``. + + :arg resolve_entities: Whether to resolve named character entities that + appear in the source tree. The XML predefined entities < > + & " ' are unaffected by this setting. + + Defaults to ``True``. + + :arg strip_whitespace: Whether to remove semantically meaningless + whitespace. (This compresses all whitespace to a single space + except within ``pre``.) + + Defaults to ``False``. + + :arg minimize_boolean_attributes: Shortens boolean attributes to give + just the attribute value, for example:: + + <input disabled="disabled"> + + becomes:: + + <input disabled> + + Defaults to ``True``. + + :arg use_trailing_solidus: Includes a close-tag slash at the end of the + start tag of void elements (empty elements whose end tag is + forbidden). E.g. ``<hr/>``. + + Defaults to ``False``. + + :arg space_before_trailing_solidus: Places a space immediately before + the closing slash in a tag using a trailing solidus. E.g. + ``<hr />``. Requires ``use_trailing_solidus=True``. + + Defaults to ``True``. + + :arg sanitize: Strip all unsafe or unknown constructs from output. + See :py:class:`html5lib.filters.sanitizer.Filter`. + + Defaults to ``False``. + + :arg omit_optional_tags: Omit start/end tags that are optional. + + Defaults to ``True``. + + :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. + + Defaults to ``False``. + + """ + unexpected_args = frozenset(kwargs) - frozenset(self.options) + if len(unexpected_args) > 0: + raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) + if 'quote_char' in kwargs: + self.use_best_quote_char = False + for attr in self.options: + setattr(self, attr, kwargs.get(attr, getattr(self, attr))) + self.errors = [] + self.strict = False + + def encode(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "htmlentityreplace") + else: + return string + + def encodeStrict(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "strict") + else: + return string + + def serialize(self, treewalker, encoding=None): + # pylint:disable=too-many-nested-blocks + self.encoding = encoding + in_cdata = False + self.errors = [] + + if encoding and self.inject_meta_charset: + from .filters.inject_meta_charset import Filter + treewalker = Filter(treewalker, encoding) + # Alphabetical attributes is here under the assumption that none of + # the later filters add or change order of attributes; it needs to be + # before the sanitizer so escaped elements come out correctly + if self.alphabetical_attributes: + from .filters.alphabeticalattributes import Filter + treewalker = Filter(treewalker) + # WhitespaceFilter should be used before OptionalTagFilter + # for maximum efficiently of this latter filter + if self.strip_whitespace: + from .filters.whitespace import Filter + treewalker = Filter(treewalker) + if self.sanitize: + from .filters.sanitizer import Filter + treewalker = Filter(treewalker) + if self.omit_optional_tags: + from .filters.optionaltags import Filter + treewalker = Filter(treewalker) + + for token in treewalker: + type = token["type"] + if type == "Doctype": + doctype = "<!DOCTYPE %s" % token["name"] + + if token["publicId"]: + doctype += ' PUBLIC "%s"' % token["publicId"] + elif token["systemId"]: + doctype += " SYSTEM" + if token["systemId"]: + if token["systemId"].find('"') >= 0: + if token["systemId"].find("'") >= 0: + self.serializeError("System identifer contains both single and double quote characters") + quote_char = "'" + else: + quote_char = '"' + doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) + + doctype += ">" + yield self.encodeStrict(doctype) + + elif type in ("Characters", "SpaceCharacters"): + if type == "SpaceCharacters" or in_cdata: + if in_cdata and token["data"].find("</") >= 0: + self.serializeError("Unexpected </ in CDATA") + yield self.encode(token["data"]) + else: + yield self.encode(escape(token["data"])) + + elif type in ("StartTag", "EmptyTag"): + name = token["name"] + yield self.encodeStrict("<%s" % name) + if name in rcdataElements and not self.escape_rcdata: + in_cdata = True + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + for (_, attr_name), attr_value in token["data"].items(): + # TODO: Add namespace support here + k = attr_name + v = attr_value + yield self.encodeStrict(' ') + + yield self.encodeStrict(k) + if not self.minimize_boolean_attributes or \ + (k not in booleanAttributes.get(name, tuple()) and + k not in booleanAttributes.get("", tuple())): + yield self.encodeStrict("=") + if self.quote_attr_values == "always" or len(v) == 0: + quote_attr = True + elif self.quote_attr_values == "spec": + quote_attr = _quoteAttributeSpec.search(v) is not None + elif self.quote_attr_values == "legacy": + quote_attr = _quoteAttributeLegacy.search(v) is not None + else: + raise ValueError("quote_attr_values must be one of: " + "'always', 'spec', or 'legacy'") + v = v.replace("&", "&") + if self.escape_lt_in_attrs: + v = v.replace("<", "<") + if quote_attr: + quote_char = self.quote_char + if self.use_best_quote_char: + if "'" in v and '"' not in v: + quote_char = '"' + elif '"' in v and "'" not in v: + quote_char = "'" + if quote_char == "'": + v = v.replace("'", "'") + else: + v = v.replace('"', """) + yield self.encodeStrict(quote_char) + yield self.encode(v) + yield self.encodeStrict(quote_char) + else: + yield self.encode(v) + if name in voidElements and self.use_trailing_solidus: + if self.space_before_trailing_solidus: + yield self.encodeStrict(" /") + else: + yield self.encodeStrict("/") + yield self.encode(">") + + elif type == "EndTag": + name = token["name"] + if name in rcdataElements: + in_cdata = False + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + yield self.encodeStrict("</%s>" % name) + + elif type == "Comment": + data = token["data"] + if data.find("--") >= 0: + self.serializeError("Comment contains --") + yield self.encodeStrict("<!--%s-->" % token["data"]) + + elif type == "Entity": + name = token["name"] + key = name + ";" + if key not in entities: + self.serializeError("Entity %s not recognized" % name) + if self.resolve_entities and key not in xmlEntities: + data = entities[key] + else: + data = "&%s;" % name + yield self.encodeStrict(data) + + else: + self.serializeError(token["data"]) + + def render(self, treewalker, encoding=None): + """Serializes the stream from the treewalker into a string + + :arg treewalker: the treewalker to serialize + + :arg encoding: the string encoding to use + + :returns: the serialized tree + + Example: + + >>> from html5lib import parse, getTreeWalker + >>> from html5lib.serializer import HTMLSerializer + >>> token_stream = parse('<html><body>Hi!</body></html>') + >>> walker = getTreeWalker('etree') + >>> serializer = HTMLSerializer(omit_optional_tags=False) + >>> serializer.render(walker(token_stream)) + '<html><head></head><body>Hi!</body></html>' + + """ + if encoding: + return b"".join(list(self.serialize(treewalker, encoding))) + else: + return "".join(list(self.serialize(treewalker))) + + def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): + # XXX The idea is to make data mandatory. + self.errors.append(data) + if self.strict: + raise SerializeError + + +class SerializeError(Exception): + """Error in serialized tree""" + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py new file mode 100755 index 0000000..7ef5959 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py @@ -0,0 +1,30 @@ +"""Tree adapters let you convert from one tree structure to another + +Example: + +.. code-block:: python + + from pip._vendor import html5lib + from pip._vendor.html5lib.treeadapters import genshi + + doc = '<html><body>Hi!</body></html>' + treebuilder = html5lib.getTreeBuilder('etree') + parser = html5lib.HTMLParser(tree=treebuilder) + tree = parser.parse(doc) + TreeWalker = html5lib.getTreeWalker('etree') + + genshi_tree = genshi.to_genshi(TreeWalker(tree)) + +""" +from __future__ import absolute_import, division, unicode_literals + +from . import sax + +__all__ = ["sax"] + +try: + from . import genshi # noqa +except ImportError: + pass +else: + __all__.append("genshi") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py new file mode 100755 index 0000000..61d5fb6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName, Attrs +from genshi.core import START, END, TEXT, COMMENT, DOCTYPE + + +def to_genshi(walker): + """Convert a tree to a genshi tree + + :arg walker: the treewalker to use to walk the tree to convert it + + :returns: generator of genshi nodes + + """ + text = [] + for token in walker: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + text.append(token["data"]) + elif text: + yield TEXT, "".join(text), (None, -1, -1) + text = [] + + if type in ("StartTag", "EmptyTag"): + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) + for attr, value in token["data"].items()]) + yield (START, (QName(name), attrs), (None, -1, -1)) + if type == "EmptyTag": + type = "EndTag" + + if type == "EndTag": + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + + yield END, QName(name), (None, -1, -1) + + elif type == "Comment": + yield COMMENT, token["data"], (None, -1, -1) + + elif type == "Doctype": + yield DOCTYPE, (token["name"], token["publicId"], + token["systemId"]), (None, -1, -1) + + else: + pass # FIXME: What to do? + + if text: + yield TEXT, "".join(text), (None, -1, -1) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py new file mode 100755 index 0000000..f4ccea5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py @@ -0,0 +1,50 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.sax.xmlreader import AttributesNSImpl + +from ..constants import adjustForeignAttributes, unadjustForeignAttributes + +prefix_mapping = {} +for prefix, localName, namespace in adjustForeignAttributes.values(): + if prefix is not None: + prefix_mapping[prefix] = namespace + + +def to_sax(walker, handler): + """Call SAX-like content handler based on treewalker walker + + :arg walker: the treewalker to use to walk the tree to convert it + + :arg handler: SAX handler to use + + """ + handler.startDocument() + for prefix, namespace in prefix_mapping.items(): + handler.startPrefixMapping(prefix, namespace) + + for token in walker: + type = token["type"] + if type == "Doctype": + continue + elif type in ("StartTag", "EmptyTag"): + attrs = AttributesNSImpl(token["data"], + unadjustForeignAttributes) + handler.startElementNS((token["namespace"], token["name"]), + token["name"], + attrs) + if type == "EmptyTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type == "EndTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type in ("Characters", "SpaceCharacters"): + handler.characters(token["data"]) + elif type == "Comment": + pass + else: + assert False, "Unknown token type" + + for prefix, namespace in prefix_mapping.items(): + handler.endPrefixMapping(prefix) + handler.endDocument() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py new file mode 100755 index 0000000..d44447e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py @@ -0,0 +1,88 @@ +"""A collection of modules for building different kinds of trees from HTML +documents. + +To create a treebuilder for a new type of tree, you need to do +implement several things: + +1. A set of classes for various types of elements: Document, Doctype, Comment, + Element. These must implement the interface of ``base.treebuilders.Node`` + (although comment nodes have a different signature for their constructor, + see ``treebuilders.etree.Comment``) Textual content may also be implemented + as another node type, or not, as your tree implementation requires. + +2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits + from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: + + * ``documentClass`` - the class to use for the bottommost node of a document + * ``elementClass`` - the class to use for HTML Elements + * ``commentClass`` - the class to use for comments + * ``doctypeClass`` - the class to use for doctypes + + It also has one required method: + + * ``getDocument`` - Returns the root node of the complete document tree + +3. If you wish to run the unit tests, you must also create a ``testSerializer`` + method on your treebuilder which accepts a node and returns a string + containing Node and its children serialized according to the format used in + the unittests + +""" + +from __future__ import absolute_import, division, unicode_literals + +from .._utils import default_etree + +treeBuilderCache = {} + + +def getTreeBuilder(treeType, implementation=None, **kwargs): + """Get a TreeBuilder class for various types of trees with built-in support + + :arg treeType: the name of the tree type required (case-insensitive). Supported + values are: + + * "dom" - A generic builder for DOM implementations, defaulting to a + xml.dom.minidom based implementation. + * "etree" - A generic builder for tree implementations exposing an + ElementTree-like interface, defaulting to xml.etree.cElementTree if + available and xml.etree.ElementTree if not. + * "lxml" - A etree-based builder for lxml.etree, handling limitations + of lxml's implementation. + + :arg implementation: (Currently applies to the "etree" and "dom" tree + types). A module implementing the tree type e.g. xml.etree.ElementTree + or xml.etree.cElementTree. + + :arg kwargs: Any additional options to pass to the TreeBuilder when + creating it. + + Example: + + >>> from html5lib.treebuilders import getTreeBuilder + >>> builder = getTreeBuilder('etree') + + """ + + treeType = treeType.lower() + if treeType not in treeBuilderCache: + if treeType == "dom": + from . import dom + # Come up with a sane default (pref. from the stdlib) + if implementation is None: + from xml.dom import minidom + implementation = minidom + # NEVER cache here, caching is done in the dom submodule + return dom.getDomModule(implementation, **kwargs).TreeBuilder + elif treeType == "lxml": + from . import etree_lxml + treeBuilderCache[treeType] = etree_lxml.TreeBuilder + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeBuilder + else: + raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) + return treeBuilderCache.get(treeType) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py new file mode 100755 index 0000000..73973db --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py @@ -0,0 +1,417 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from ..constants import scopingElements, tableInsertModeElements, namespaces + +# The scope markers are inserted when entering object elements, +# marquees, table cells, and table captions, and are used to prevent formatting +# from "leaking" into tables, object elements, and marquees. +Marker = None + +listElementsMap = { + None: (frozenset(scopingElements), False), + "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), + "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), + (namespaces["html"], "ul")])), False), + "table": (frozenset([(namespaces["html"], "html"), + (namespaces["html"], "table")]), False), + "select": (frozenset([(namespaces["html"], "optgroup"), + (namespaces["html"], "option")]), True) +} + + +class Node(object): + """Represents an item in the tree""" + def __init__(self, name): + """Creates a Node + + :arg name: The tag name associated with the node + + """ + # The tag name assocaited with the node + self.name = name + # The parent of the current node (or None for the document node) + self.parent = None + # The value of the current node (applies to text nodes and comments) + self.value = None + # A dict holding name -> value pairs for attributes of the node + self.attributes = {} + # A list of child nodes of the current node. This must include all + # elements but not necessarily other node types. + self.childNodes = [] + # A list of miscellaneous flags that can be set on the node. + self._flags = [] + + def __str__(self): + attributesStr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in + self.attributes.items()]) + if attributesStr: + return "<%s %s>" % (self.name, attributesStr) + else: + return "<%s>" % (self.name) + + def __repr__(self): + return "<%s>" % (self.name) + + def appendChild(self, node): + """Insert node as a child of the current node + + :arg node: the node to insert + + """ + raise NotImplementedError + + def insertText(self, data, insertBefore=None): + """Insert data as text in the current node, positioned before the + start of node insertBefore or to the end of the node's text. + + :arg data: the data to insert + + :arg insertBefore: True if you want to insert the text before the node + and False if you want to insert it after the node + + """ + raise NotImplementedError + + def insertBefore(self, node, refNode): + """Insert node as a child of the current node, before refNode in the + list of child nodes. Raises ValueError if refNode is not a child of + the current node + + :arg node: the node to insert + + :arg refNode: the child node to insert the node before + + """ + raise NotImplementedError + + def removeChild(self, node): + """Remove node from the children of the current node + + :arg node: the child node to remove + + """ + raise NotImplementedError + + def reparentChildren(self, newParent): + """Move all the children of the current node to newParent. + This is needed so that trees that don't store text as nodes move the + text in the correct way + + :arg newParent: the node to move all this node's children to + + """ + # XXX - should this method be made more general? + for child in self.childNodes: + newParent.appendChild(child) + self.childNodes = [] + + def cloneNode(self): + """Return a shallow copy of the current node i.e. a node with the same + name and attributes but with no parent or child nodes + """ + raise NotImplementedError + + def hasContent(self): + """Return true if the node has children or text, false otherwise + """ + raise NotImplementedError + + +class ActiveFormattingElements(list): + def append(self, node): + equalCount = 0 + if node != Marker: + for element in self[::-1]: + if element == Marker: + break + if self.nodesEqual(element, node): + equalCount += 1 + if equalCount == 3: + self.remove(element) + break + list.append(self, node) + + def nodesEqual(self, node1, node2): + if not node1.nameTuple == node2.nameTuple: + return False + + if not node1.attributes == node2.attributes: + return False + + return True + + +class TreeBuilder(object): + """Base treebuilder implementation + + * documentClass - the class to use for the bottommost node of a document + * elementClass - the class to use for HTML Elements + * commentClass - the class to use for comments + * doctypeClass - the class to use for doctypes + + """ + # pylint:disable=not-callable + + # Document class + documentClass = None + + # The class to use for creating a node + elementClass = None + + # The class to use for creating comments + commentClass = None + + # The class to use for creating doctypes + doctypeClass = None + + # Fragment class + fragmentClass = None + + def __init__(self, namespaceHTMLElements): + """Create a TreeBuilder + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + """ + if namespaceHTMLElements: + self.defaultNamespace = "http://www.w3.org/1999/xhtml" + else: + self.defaultNamespace = None + self.reset() + + def reset(self): + self.openElements = [] + self.activeFormattingElements = ActiveFormattingElements() + + # XXX - rename these to headElement, formElement + self.headPointer = None + self.formPointer = None + + self.insertFromTable = False + + self.document = self.documentClass() + + def elementInScope(self, target, variant=None): + + # If we pass a node in we match that. if we pass a string + # match any node with that name + exactNode = hasattr(target, "nameTuple") + if not exactNode: + if isinstance(target, text_type): + target = (namespaces["html"], target) + assert isinstance(target, tuple) + + listElements, invert = listElementsMap[variant] + + for node in reversed(self.openElements): + if exactNode and node == target: + return True + elif not exactNode and node.nameTuple == target: + return True + elif (invert ^ (node.nameTuple in listElements)): + return False + + assert False # We should never reach this point + + def reconstructActiveFormattingElements(self): + # Within this algorithm the order of steps described in the + # specification is not quite the same as the order of steps in the + # code. It should still do the same though. + + # Step 1: stop the algorithm when there's nothing to do. + if not self.activeFormattingElements: + return + + # Step 2 and step 3: we start with the last element. So i is -1. + i = len(self.activeFormattingElements) - 1 + entry = self.activeFormattingElements[i] + if entry == Marker or entry in self.openElements: + return + + # Step 6 + while entry != Marker and entry not in self.openElements: + if i == 0: + # This will be reset to 0 below + i = -1 + break + i -= 1 + # Step 5: let entry be one earlier in the list. + entry = self.activeFormattingElements[i] + + while True: + # Step 7 + i += 1 + + # Step 8 + entry = self.activeFormattingElements[i] + clone = entry.cloneNode() # Mainly to get a new copy of the attributes + + # Step 9 + element = self.insertElement({"type": "StartTag", + "name": clone.name, + "namespace": clone.namespace, + "data": clone.attributes}) + + # Step 10 + self.activeFormattingElements[i] = element + + # Step 11 + if element == self.activeFormattingElements[-1]: + break + + def clearActiveFormattingElements(self): + entry = self.activeFormattingElements.pop() + while self.activeFormattingElements and entry != Marker: + entry = self.activeFormattingElements.pop() + + def elementInActiveFormattingElements(self, name): + """Check if an element exists between the end of the active + formatting elements and the last marker. If it does, return it, else + return false""" + + for item in self.activeFormattingElements[::-1]: + # Check for Marker first because if it's a Marker it doesn't have a + # name attribute. + if item == Marker: + break + elif item.name == name: + return item + return False + + def insertRoot(self, token): + element = self.createElement(token) + self.openElements.append(element) + self.document.appendChild(element) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = self.doctypeClass(name, publicId, systemId) + self.document.appendChild(doctype) + + def insertComment(self, token, parent=None): + if parent is None: + parent = self.openElements[-1] + parent.appendChild(self.commentClass(token["data"])) + + def createElement(self, token): + """Create an element but don't insert it anywhere""" + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + return element + + def _getInsertFromTable(self): + return self._insertFromTable + + def _setInsertFromTable(self, value): + """Switch the function used to insert an element from the + normal one to the misnested table one and back again""" + self._insertFromTable = value + if value: + self.insertElement = self.insertElementTable + else: + self.insertElement = self.insertElementNormal + + insertFromTable = property(_getInsertFromTable, _setInsertFromTable) + + def insertElementNormal(self, token): + name = token["name"] + assert isinstance(name, text_type), "Element %s not unicode" % name + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + self.openElements[-1].appendChild(element) + self.openElements.append(element) + return element + + def insertElementTable(self, token): + """Create an element and insert it into the tree""" + element = self.createElement(token) + if self.openElements[-1].name not in tableInsertModeElements: + return self.insertElementNormal(token) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + if insertBefore is None: + parent.appendChild(element) + else: + parent.insertBefore(element, insertBefore) + self.openElements.append(element) + return element + + def insertText(self, data, parent=None): + """Insert text data.""" + if parent is None: + parent = self.openElements[-1] + + if (not self.insertFromTable or (self.insertFromTable and + self.openElements[-1].name + not in tableInsertModeElements)): + parent.insertText(data) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + parent.insertText(data, insertBefore) + + def getTableMisnestedNodePosition(self): + """Get the foster parent element, and sibling to insert before + (or None) when inserting a misnested table node""" + # The foster parent element is the one which comes before the most + # recently opened table element + # XXX - this is really inelegant + lastTable = None + fosterParent = None + insertBefore = None + for elm in self.openElements[::-1]: + if elm.name == "table": + lastTable = elm + break + if lastTable: + # XXX - we should really check that this parent is actually a + # node here + if lastTable.parent: + fosterParent = lastTable.parent + insertBefore = lastTable + else: + fosterParent = self.openElements[ + self.openElements.index(lastTable) - 1] + else: + fosterParent = self.openElements[0] + return fosterParent, insertBefore + + def generateImpliedEndTags(self, exclude=None): + name = self.openElements[-1].name + # XXX td, th and tr are not actually needed + if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and + name != exclude): + self.openElements.pop() + # XXX This is not entirely what the specification says. We should + # investigate it more closely. + self.generateImpliedEndTags(exclude) + + def getDocument(self): + """Return the final tree""" + return self.document + + def getFragment(self): + """Return the final fragment""" + # assert self.innerHTML + fragment = self.fragmentClass() + self.openElements[0].reparentChildren(fragment) + return fragment + + def testSerializer(self, node): + """Serialize the subtree of node in the format required by unit tests + + :arg node: the node from which to start serializing + + """ + raise NotImplementedError diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py new file mode 100755 index 0000000..dcfac22 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py @@ -0,0 +1,236 @@ +from __future__ import absolute_import, division, unicode_literals + + +from collections import MutableMapping +from xml.dom import minidom, Node +import weakref + +from . import base +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + + +def getDomBuilder(DomImplementation): + Dom = DomImplementation + + class AttrList(MutableMapping): + def __init__(self, element): + self.element = element + + def __iter__(self): + return iter(self.element.attributes.keys()) + + def __setitem__(self, name, value): + if isinstance(name, tuple): + raise NotImplementedError + else: + attr = self.element.ownerDocument.createAttribute(name) + attr.value = value + self.element.attributes[name] = attr + + def __len__(self): + return len(self.element.attributes) + + def items(self): + return list(self.element.attributes.items()) + + def values(self): + return list(self.element.attributes.values()) + + def __getitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + return self.element.attributes[name].value + + def __delitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + del self.element.attributes[name] + + class NodeBuilder(base.Node): + def __init__(self, element): + base.Node.__init__(self, element.nodeName) + self.element = element + + namespace = property(lambda self: hasattr(self.element, "namespaceURI") and + self.element.namespaceURI or None) + + def appendChild(self, node): + node.parent = self + self.element.appendChild(node.element) + + def insertText(self, data, insertBefore=None): + text = self.element.ownerDocument.createTextNode(data) + if insertBefore: + self.element.insertBefore(text, insertBefore.element) + else: + self.element.appendChild(text) + + def insertBefore(self, node, refNode): + self.element.insertBefore(node.element, refNode.element) + node.parent = self + + def removeChild(self, node): + if node.element.parentNode == self.element: + self.element.removeChild(node.element) + node.parent = None + + def reparentChildren(self, newParent): + while self.element.hasChildNodes(): + child = self.element.firstChild + self.element.removeChild(child) + newParent.element.appendChild(child) + self.childNodes = [] + + def getAttributes(self): + return AttrList(self.element) + + def setAttributes(self, attributes): + if attributes: + for name, value in list(attributes.items()): + if isinstance(name, tuple): + if name[0] is not None: + qualifiedName = (name[0] + ":" + name[1]) + else: + qualifiedName = name[1] + self.element.setAttributeNS(name[2], qualifiedName, + value) + else: + self.element.setAttribute( + name, value) + attributes = property(getAttributes, setAttributes) + + def cloneNode(self): + return NodeBuilder(self.element.cloneNode(False)) + + def hasContent(self): + return self.element.hasChildNodes() + + def getNameTuple(self): + if self.namespace is None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + def documentClass(self): + self.dom = Dom.getDOMImplementation().createDocument(None, None, None) + return weakref.proxy(self) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + domimpl = Dom.getDOMImplementation() + doctype = domimpl.createDocumentType(name, publicId, systemId) + self.document.appendChild(NodeBuilder(doctype)) + if Dom == minidom: + doctype.ownerDocument = self.dom + + def elementClass(self, name, namespace=None): + if namespace is None and self.defaultNamespace is None: + node = self.dom.createElement(name) + else: + node = self.dom.createElementNS(namespace, name) + + return NodeBuilder(node) + + def commentClass(self, data): + return NodeBuilder(self.dom.createComment(data)) + + def fragmentClass(self): + return NodeBuilder(self.dom.createDocumentFragment()) + + def appendChild(self, node): + self.dom.appendChild(node.element) + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + return self.dom + + def getFragment(self): + return base.TreeBuilder.getFragment(self).element + + def insertText(self, data, parent=None): + data = data + if parent != self: + base.TreeBuilder.insertText(self, data, parent) + else: + # HACK: allow text nodes as children of the document node + if hasattr(self.dom, '_child_node_types'): + # pylint:disable=protected-access + if Node.TEXT_NODE not in self.dom._child_node_types: + self.dom._child_node_types = list(self.dom._child_node_types) + self.dom._child_node_types.append(Node.TEXT_NODE) + self.dom.appendChild(self.dom.createTextNode(data)) + + implementation = DomImplementation + name = None + + def testSerializer(element): + element.normalize() + rv = [] + + def serializeElement(element, indent=0): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + if element.name: + if element.publicId or element.systemId: + publicId = element.publicId or "" + systemId = element.systemId or "" + rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % + (' ' * indent, element.name, publicId, systemId)) + else: + rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) + else: + rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) + elif element.nodeType == Node.DOCUMENT_NODE: + rv.append("#document") + elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + rv.append("#document-fragment") + elif element.nodeType == Node.COMMENT_NODE: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) + elif element.nodeType == Node.TEXT_NODE: + rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) + else: + if (hasattr(element, "namespaceURI") and + element.namespaceURI is not None): + name = "%s %s" % (constants.prefixes[element.namespaceURI], + element.nodeName) + else: + name = element.nodeName + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.hasAttributes(): + attributes = [] + for i in range(len(element.attributes)): + attr = element.attributes.item(i) + name = attr.nodeName + value = attr.value + ns = attr.namespaceURI + if ns: + name = "%s %s" % (constants.prefixes[ns], attr.localName) + else: + name = attr.nodeName + attributes.append((name, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + indent += 2 + for child in element.childNodes: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + + return locals() + + +# The actual means to get a module! +getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py new file mode 100755 index 0000000..0dedf44 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py @@ -0,0 +1,340 @@ +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +from pip._vendor.six import text_type + +import re + +from . import base +from .. import _ihatexml +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation, fullTree=False): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class Element(base.Node): + def __init__(self, name, namespace=None): + self._name = name + self._namespace = namespace + self._element = ElementTree.Element(self._getETreeTag(name, + namespace)) + if namespace is None: + self.nameTuple = namespaces["html"], self._name + else: + self.nameTuple = self._namespace, self._name + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getETreeTag(self, name, namespace): + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + return etree_tag + + def _setName(self, name): + self._name = name + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getName(self): + return self._name + + name = property(_getName, _setName) + + def _setNamespace(self, namespace): + self._namespace = namespace + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getNamespace(self): + return self._namespace + + namespace = property(_getNamespace, _setNamespace) + + def _getAttributes(self): + return self._element.attrib + + def _setAttributes(self, attributes): + # Delete existing attributes first + # XXX - there may be a better way to do this... + for key in list(self._element.attrib.keys()): + del self._element.attrib[key] + for key, value in attributes.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], key[1]) + else: + name = key + self._element.set(name, value) + + attributes = property(_getAttributes, _setAttributes) + + def _getChildNodes(self): + return self._childNodes + + def _setChildNodes(self, value): + del self._element[:] + self._childNodes = [] + for element in value: + self.insertChild(element) + + childNodes = property(_getChildNodes, _setChildNodes) + + def hasContent(self): + """Return true if the node has children or text""" + return bool(self._element.text or len(self._element)) + + def appendChild(self, node): + self._childNodes.append(node) + self._element.append(node._element) + node.parent = self + + def insertBefore(self, node, refNode): + index = list(self._element).index(refNode._element) + self._element.insert(index, node._element) + node.parent = self + + def removeChild(self, node): + self._childNodes.remove(node) + self._element.remove(node._element) + node.parent = None + + def insertText(self, data, insertBefore=None): + if not(len(self._element)): + if not self._element.text: + self._element.text = "" + self._element.text += data + elif insertBefore is None: + # Insert the text as the tail of the last child element + if not self._element[-1].tail: + self._element[-1].tail = "" + self._element[-1].tail += data + else: + # Insert the text before the specified node + children = list(self._element) + index = children.index(insertBefore._element) + if index > 0: + if not self._element[index - 1].tail: + self._element[index - 1].tail = "" + self._element[index - 1].tail += data + else: + if not self._element.text: + self._element.text = "" + self._element.text += data + + def cloneNode(self): + element = type(self)(self.name, self.namespace) + for name, value in self.attributes.items(): + element.attributes[name] = value + return element + + def reparentChildren(self, newParent): + if newParent.childNodes: + newParent.childNodes[-1]._element.tail += self._element.text + else: + if not newParent._element.text: + newParent._element.text = "" + if self._element.text is not None: + newParent._element.text += self._element.text + self._element.text = "" + base.Node.reparentChildren(self, newParent) + + class Comment(Element): + def __init__(self, data): + # Use the superclass constructor to set all properties on the + # wrapper element + self._element = ElementTree.Comment(data) + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getData(self): + return self._element.text + + def _setData(self, value): + self._element.text = value + + data = property(_getData, _setData) + + class DocumentType(Element): + def __init__(self, name, publicId, systemId): + Element.__init__(self, "<!DOCTYPE>") + self._element.text = name + self.publicId = publicId + self.systemId = systemId + + def _getPublicId(self): + return self._element.get("publicId", "") + + def _setPublicId(self, value): + if value is not None: + self._element.set("publicId", value) + + publicId = property(_getPublicId, _setPublicId) + + def _getSystemId(self): + return self._element.get("systemId", "") + + def _setSystemId(self, value): + if value is not None: + self._element.set("systemId", value) + + systemId = property(_getSystemId, _setSystemId) + + class Document(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_ROOT") + + class DocumentFragment(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_FRAGMENT") + + def testSerializer(element): + rv = [] + + def serializeElement(element, indent=0): + if not(hasattr(element, "tag")): + element = element.getroot() + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + rv.append("#document") + if element.text is not None: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + elif element.tag == ElementTreeCommentType: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + else: + assert isinstance(element.tag, text_type), \ + "Expected unicode, got %s, %s" % (type(element.tag), element.tag) + nsmatch = tag_regexp.match(element.tag) + + if nsmatch is None: + name = element.tag + else: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + name = "%s %s" % (prefix, name) + rv.append("|%s<%s>" % (' ' * indent, name)) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = name + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + def tostring(element): # pylint:disable=unused-variable + """Serialize an element and its child nodes to a string""" + rv = [] + filter = _ihatexml.InfosetFilter() + + def serializeElement(element): + if isinstance(element, ElementTree.ElementTree): + element = element.getroot() + + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + if element.text is not None: + rv.append(element.text) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + + for child in element: + serializeElement(child) + + elif element.tag == ElementTreeCommentType: + rv.append("<!--%s-->" % (element.text,)) + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (filter.fromXmlName(element.tag),)) + else: + attr = " ".join(["%s=\"%s\"" % ( + filter.fromXmlName(name), value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + documentClass = Document + doctypeClass = DocumentType + elementClass = Element + commentClass = Comment + fragmentClass = DocumentFragment + implementation = ElementTreeImplementation + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._element + else: + if self.defaultNamespace is not None: + return self.document._element.find( + "{%s}html" % self.defaultNamespace) + else: + return self.document._element.find("html") + + def getFragment(self): + return base.TreeBuilder.getFragment(self)._element + + return locals() + + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py new file mode 100755 index 0000000..ca12a99 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -0,0 +1,366 @@ +"""Module for supporting the lxml.etree library. The idea here is to use as much +of the native library as possible, without using fragile hacks like custom element +names that break between releases. The downside of this is that we cannot represent +all possible trees; specifically the following are known to cause problems: + +Text or comments as siblings of the root element +Docypes with no name + +When any of these things occur, we emit a DataLossWarning +""" + +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +import warnings +import re +import sys + +from . import base +from ..constants import DataLossWarning +from .. import constants +from . import etree as etree_builders +from .. import _ihatexml + +import lxml.etree as etree + + +fullTree = True +tag_regexp = re.compile("{([^}]*)}(.*)") + +comment_type = etree.Comment("asd").tag + + +class DocumentType(object): + def __init__(self, name, publicId, systemId): + self.name = name + self.publicId = publicId + self.systemId = systemId + + +class Document(object): + def __init__(self): + self._elementTree = None + self._childNodes = [] + + def appendChild(self, element): + self._elementTree.getroot().addnext(element._element) + + def _getChildNodes(self): + return self._childNodes + + childNodes = property(_getChildNodes) + + +def testSerializer(element): + rv = [] + infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + + def serializeElement(element, indent=0): + if not hasattr(element, "tag"): + if hasattr(element, "getroot"): + # Full tree case + rv.append("#document") + if element.docinfo.internalDTD: + if not (element.docinfo.public_id or + element.docinfo.system_url): + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + else: + dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( + element.docinfo.root_name, + element.docinfo.public_id, + element.docinfo.system_url) + rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) + next_element = element.getroot() + while next_element.getprevious() is not None: + next_element = next_element.getprevious() + while next_element is not None: + serializeElement(next_element, indent + 2) + next_element = next_element.getnext() + elif isinstance(element, str) or isinstance(element, bytes): + # Text in a fragment + assert isinstance(element, str) or sys.version_info[0] == 2 + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + # Fragment case + rv.append("#document-fragment") + for next_element in element: + serializeElement(next_element, indent + 2) + elif element.tag == comment_type: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) + else: + assert isinstance(element, etree._Element) + nsmatch = etree_builders.tag_regexp.match(element.tag) + if nsmatch is not None: + ns = nsmatch.group(1) + tag = nsmatch.group(2) + prefix = constants.prefixes[ns] + rv.append("|%s<%s %s>" % (' ' * indent, prefix, + infosetFilter.fromXmlName(tag))) + else: + rv.append("|%s<%s>" % (' ' * indent, + infosetFilter.fromXmlName(element.tag))) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + name = infosetFilter.fromXmlName(name) + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = infosetFilter.fromXmlName(name) + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + +def tostring(element): + """Serialize an element and its child nodes to a string""" + rv = [] + + def serializeElement(element): + if not hasattr(element, "tag"): + if element.docinfo.internalDTD: + if element.docinfo.doctype: + dtd_str = element.docinfo.doctype + else: + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + rv.append(dtd_str) + serializeElement(element.getroot()) + + elif element.tag == comment_type: + rv.append("<!--%s-->" % (element.text,)) + + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (element.tag,)) + else: + attr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if hasattr(element, "tail") and element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + +class TreeBuilder(base.TreeBuilder): + documentClass = Document + doctypeClass = DocumentType + elementClass = None + commentClass = None + fragmentClass = Document + implementation = etree + + def __init__(self, namespaceHTMLElements, fullTree=False): + builder = etree_builders.getETreeModule(etree, fullTree=fullTree) + infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + self.namespaceHTMLElements = namespaceHTMLElements + + class Attributes(dict): + def __init__(self, element, value=None): + if value is None: + value = {} + self._element = element + dict.__init__(self, value) # pylint:disable=non-parent-init-called + for key, value in self.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + def __setitem__(self, key, value): + dict.__setitem__(self, key, value) + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + class Element(builder.Element): + def __init__(self, name, namespace): + name = infosetFilter.coerceElement(name) + builder.Element.__init__(self, name, namespace=namespace) + self._attributes = Attributes(self) + + def _setName(self, name): + self._name = infosetFilter.coerceElement(name) + self._element.tag = self._getETreeTag( + self._name, self._namespace) + + def _getName(self): + return infosetFilter.fromXmlName(self._name) + + name = property(_getName, _setName) + + def _getAttributes(self): + return self._attributes + + def _setAttributes(self, attributes): + self._attributes = Attributes(self, attributes) + + attributes = property(_getAttributes, _setAttributes) + + def insertText(self, data, insertBefore=None): + data = infosetFilter.coerceCharacters(data) + builder.Element.insertText(self, data, insertBefore) + + def appendChild(self, child): + builder.Element.appendChild(self, child) + + class Comment(builder.Comment): + def __init__(self, data): + data = infosetFilter.coerceComment(data) + builder.Comment.__init__(self, data) + + def _setData(self, data): + data = infosetFilter.coerceComment(data) + self._element.text = data + + def _getData(self): + return self._element.text + + data = property(_getData, _setData) + + self.elementClass = Element + self.commentClass = Comment + # self.fragmentClass = builder.DocumentFragment + base.TreeBuilder.__init__(self, namespaceHTMLElements) + + def reset(self): + base.TreeBuilder.reset(self) + self.insertComment = self.insertCommentInitial + self.initial_comments = [] + self.doctype = None + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._elementTree + else: + return self.document._elementTree.getroot() + + def getFragment(self): + fragment = [] + element = self.openElements[0]._element + if element.text: + fragment.append(element.text) + fragment.extend(list(element)) + if element.tail: + fragment.append(element.tail) + return fragment + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + if not name: + warnings.warn("lxml cannot represent empty doctype", DataLossWarning) + self.doctype = None + else: + coercedName = self.infosetFilter.coerceElement(name) + if coercedName != name: + warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) + + doctype = self.doctypeClass(coercedName, publicId, systemId) + self.doctype = doctype + + def insertCommentInitial(self, data, parent=None): + assert parent is None or parent is self.document + assert self.document._elementTree is None + self.initial_comments.append(data) + + def insertCommentMain(self, data, parent=None): + if (parent == self.document and + self.document._elementTree.getroot()[-1].tag == comment_type): + warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) + super(TreeBuilder, self).insertComment(data, parent) + + def insertRoot(self, token): + # Because of the way libxml2 works, it doesn't seem to be possible to + # alter information like the doctype after the tree has been parsed. + # Therefore we need to use the built-in parser to create our initial + # tree, after which we can add elements like normal + docStr = "" + if self.doctype: + assert self.doctype.name + docStr += "<!DOCTYPE %s" % self.doctype.name + if (self.doctype.publicId is not None or + self.doctype.systemId is not None): + docStr += (' PUBLIC "%s" ' % + (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) + if self.doctype.systemId: + sysid = self.doctype.systemId + if sysid.find("'") >= 0 and sysid.find('"') >= 0: + warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) + sysid = sysid.replace("'", 'U00027') + if sysid.find("'") >= 0: + docStr += '"%s"' % sysid + else: + docStr += "'%s'" % sysid + else: + docStr += "''" + docStr += ">" + if self.doctype.name != token["name"]: + warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) + docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" + root = etree.fromstring(docStr) + + # Append the initial comments: + for comment_token in self.initial_comments: + comment = self.commentClass(comment_token["data"]) + root.addprevious(comment._element) + + # Create the root document and add the ElementTree to it + self.document = self.documentClass() + self.document._elementTree = root.getroottree() + + # Give the root element the right name + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + root.tag = etree_tag + + # Add the root element to the internal child/open data structures + root_element = self.elementClass(name, namespace) + root_element._element = root + self.document._childNodes.append(root_element) + self.openElements.append(root_element) + + # Reset to the default insert comment function + self.insertComment = self.insertCommentMain diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py new file mode 100755 index 0000000..9bec207 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py @@ -0,0 +1,154 @@ +"""A collection of modules for iterating through different kinds of +tree, generating tokens identical to those produced by the tokenizer +module. + +To create a tree walker for a new type of tree, you need to do +implement a tree walker object (called TreeWalker by convention) that +implements a 'serialize' method taking a tree as sole argument and +returning an iterator generating tokens. +""" + +from __future__ import absolute_import, division, unicode_literals + +from .. import constants +from .._utils import default_etree + +__all__ = ["getTreeWalker", "pprint"] + +treeWalkerCache = {} + + +def getTreeWalker(treeType, implementation=None, **kwargs): + """Get a TreeWalker class for various types of tree with built-in support + + :arg str treeType: the name of the tree type required (case-insensitive). + Supported values are: + + * "dom": The xml.dom.minidom DOM implementation + * "etree": A generic walker for tree implementations exposing an + elementtree-like interface (known to work with ElementTree, + cElementTree and lxml.etree). + * "lxml": Optimized walker for lxml.etree + * "genshi": a Genshi stream + + :arg implementation: A module implementing the tree type e.g. + xml.etree.ElementTree or cElementTree (Currently applies to the "etree" + tree type only). + + :arg kwargs: keyword arguments passed to the etree walker--for other + walkers, this has no effect + + :returns: a TreeWalker class + + """ + + treeType = treeType.lower() + if treeType not in treeWalkerCache: + if treeType == "dom": + from . import dom + treeWalkerCache[treeType] = dom.TreeWalker + elif treeType == "genshi": + from . import genshi + treeWalkerCache[treeType] = genshi.TreeWalker + elif treeType == "lxml": + from . import etree_lxml + treeWalkerCache[treeType] = etree_lxml.TreeWalker + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # XXX: NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeWalker + return treeWalkerCache.get(treeType) + + +def concatenateCharacterTokens(tokens): + pendingCharacters = [] + for token in tokens: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + pendingCharacters.append(token["data"]) + else: + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + pendingCharacters = [] + yield token + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + + +def pprint(walker): + """Pretty printer for tree walkers + + Takes a TreeWalker instance and pretty prints the output of walking the tree. + + :arg walker: a TreeWalker instance + + """ + output = [] + indent = 0 + for token in concatenateCharacterTokens(walker): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + # tag name + if token["namespace"] and token["namespace"] != constants.namespaces["html"]: + if token["namespace"] in constants.prefixes: + ns = constants.prefixes[token["namespace"]] + else: + ns = token["namespace"] + name = "%s %s" % (ns, token["name"]) + else: + name = token["name"] + output.append("%s<%s>" % (" " * indent, name)) + indent += 2 + # attributes (sorted for consistent ordering) + attrs = token["data"] + for (namespace, localname), value in sorted(attrs.items()): + if namespace: + if namespace in constants.prefixes: + ns = constants.prefixes[namespace] + else: + ns = namespace + name = "%s %s" % (ns, localname) + else: + name = localname + output.append("%s%s=\"%s\"" % (" " * indent, name, value)) + # self-closing + if type == "EmptyTag": + indent -= 2 + + elif type == "EndTag": + indent -= 2 + + elif type == "Comment": + output.append("%s<!-- %s -->" % (" " * indent, token["data"])) + + elif type == "Doctype": + if token["name"]: + if token["publicId"]: + output.append("""%s<!DOCTYPE %s "%s" "%s">""" % + (" " * indent, + token["name"], + token["publicId"], + token["systemId"] if token["systemId"] else "")) + elif token["systemId"]: + output.append("""%s<!DOCTYPE %s "" "%s">""" % + (" " * indent, + token["name"], + token["systemId"])) + else: + output.append("%s<!DOCTYPE %s>" % (" " * indent, + token["name"])) + else: + output.append("%s<!DOCTYPE >" % (" " * indent,)) + + elif type == "Characters": + output.append("%s\"%s\"" % (" " * indent, token["data"])) + + elif type == "SpaceCharacters": + assert False, "concatenateCharacterTokens should have got rid of all Space tokens" + + else: + raise ValueError("Unknown token type, %s" % type) + + return "\n".join(output) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py new file mode 100755 index 0000000..80c474c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node +from ..constants import namespaces, voidElements, spaceCharacters + +__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", + "TreeWalker", "NonRecursiveTreeWalker"] + +DOCUMENT = Node.DOCUMENT_NODE +DOCTYPE = Node.DOCUMENT_TYPE_NODE +TEXT = Node.TEXT_NODE +ELEMENT = Node.ELEMENT_NODE +COMMENT = Node.COMMENT_NODE +ENTITY = Node.ENTITY_NODE +UNKNOWN = "<#UNKNOWN#>" + +spaceCharacters = "".join(spaceCharacters) + + +class TreeWalker(object): + """Walks a tree yielding tokens + + Tokens are dicts that all have a ``type`` field specifying the type of the + token. + + """ + def __init__(self, tree): + """Creates a TreeWalker + + :arg tree: the tree to walk + + """ + self.tree = tree + + def __iter__(self): + raise NotImplementedError + + def error(self, msg): + """Generates an error token with the given message + + :arg msg: the error message + + :returns: SerializeError token + + """ + return {"type": "SerializeError", "data": msg} + + def emptyTag(self, namespace, name, attrs, hasChildren=False): + """Generates an EmptyTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :arg hasChildren: whether or not to yield a SerializationError because + this tag shouldn't have children + + :returns: EmptyTag token + + """ + yield {"type": "EmptyTag", "name": name, + "namespace": namespace, + "data": attrs} + if hasChildren: + yield self.error("Void element has children") + + def startTag(self, namespace, name, attrs): + """Generates a StartTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :returns: StartTag token + + """ + return {"type": "StartTag", + "name": name, + "namespace": namespace, + "data": attrs} + + def endTag(self, namespace, name): + """Generates an EndTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :returns: EndTag token + + """ + return {"type": "EndTag", + "name": name, + "namespace": namespace} + + def text(self, data): + """Generates SpaceCharacters and Characters tokens + + Depending on what's in the data, this generates one or more + ``SpaceCharacters`` and ``Characters`` tokens. + + For example: + + >>> from html5lib.treewalkers.base import TreeWalker + >>> # Give it an empty tree just so it instantiates + >>> walker = TreeWalker([]) + >>> list(walker.text('')) + [] + >>> list(walker.text(' ')) + [{u'data': ' ', u'type': u'SpaceCharacters'}] + >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE + [{u'data': ' ', u'type': u'SpaceCharacters'}, + {u'data': u'abc', u'type': u'Characters'}, + {u'data': u' ', u'type': u'SpaceCharacters'}] + + :arg data: the text data + + :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens + + """ + data = data + middle = data.lstrip(spaceCharacters) + left = data[:len(data) - len(middle)] + if left: + yield {"type": "SpaceCharacters", "data": left} + data = middle + middle = data.rstrip(spaceCharacters) + right = data[len(middle):] + if middle: + yield {"type": "Characters", "data": middle} + if right: + yield {"type": "SpaceCharacters", "data": right} + + def comment(self, data): + """Generates a Comment token + + :arg data: the comment + + :returns: Comment token + + """ + return {"type": "Comment", "data": data} + + def doctype(self, name, publicId=None, systemId=None): + """Generates a Doctype token + + :arg name: + + :arg publicId: + + :arg systemId: + + :returns: the Doctype token + + """ + return {"type": "Doctype", + "name": name, + "publicId": publicId, + "systemId": systemId} + + def entity(self, name): + """Generates an Entity token + + :arg name: the entity name + + :returns: an Entity token + + """ + return {"type": "Entity", "name": name} + + def unknown(self, nodeType): + """Handles unknown node types""" + return self.error("Unknown node type: " + nodeType) + + +class NonRecursiveTreeWalker(TreeWalker): + def getNodeDetails(self, node): + raise NotImplementedError + + def getFirstChild(self, node): + raise NotImplementedError + + def getNextSibling(self, node): + raise NotImplementedError + + def getParentNode(self, node): + raise NotImplementedError + + def __iter__(self): + currentNode = self.tree + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + hasChildren = False + + if type == DOCTYPE: + yield self.doctype(*details) + + elif type == TEXT: + for token in self.text(*details): + yield token + + elif type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + for token in self.emptyTag(namespace, name, attributes, + hasChildren): + yield token + hasChildren = False + else: + yield self.startTag(namespace, name, attributes) + + elif type == COMMENT: + yield self.comment(details[0]) + + elif type == ENTITY: + yield self.entity(details[0]) + + elif type == DOCUMENT: + hasChildren = True + + else: + yield self.unknown(details[0]) + + if hasChildren: + firstChild = self.getFirstChild(currentNode) + else: + firstChild = None + + if firstChild is not None: + currentNode = firstChild + else: + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + if type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (namespace and namespace != namespaces["html"]) or name not in voidElements: + yield self.endTag(namespace, name) + if self.tree is currentNode: + currentNode = None + break + nextSibling = self.getNextSibling(currentNode) + if nextSibling is not None: + currentNode = nextSibling + break + else: + currentNode = self.getParentNode(currentNode) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py new file mode 100755 index 0000000..b0c89b0 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node + +from . import base + + +class TreeWalker(base.NonRecursiveTreeWalker): + def getNodeDetails(self, node): + if node.nodeType == Node.DOCUMENT_TYPE_NODE: + return base.DOCTYPE, node.name, node.publicId, node.systemId + + elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + return base.TEXT, node.nodeValue + + elif node.nodeType == Node.ELEMENT_NODE: + attrs = {} + for attr in list(node.attributes.keys()): + attr = node.getAttributeNode(attr) + if attr.namespaceURI: + attrs[(attr.namespaceURI, attr.localName)] = attr.value + else: + attrs[(None, attr.name)] = attr.value + return (base.ELEMENT, node.namespaceURI, node.nodeName, + attrs, node.hasChildNodes()) + + elif node.nodeType == Node.COMMENT_NODE: + return base.COMMENT, node.nodeValue + + elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): + return (base.DOCUMENT,) + + else: + return base.UNKNOWN, node.nodeType + + def getFirstChild(self, node): + return node.firstChild + + def getNextSibling(self, node): + return node.nextSibling + + def getParentNode(self, node): + return node.parentNode diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py new file mode 100755 index 0000000..95fc0c1 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import OrderedDict +import re + +from pip._vendor.six import string_types + +from . import base +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable + """Given the particular ElementTree representation, this implementation, + to avoid using recursion, returns "nodes" as tuples with the following + content: + + 1. The current element + + 2. The index of the element relative to its parent + + 3. A stack of ancestor elements + + 4. A flag "text", "tail" or None to indicate if the current node is a + text node; either the text or tail of the current element (1) + """ + def getNodeDetails(self, node): + if isinstance(node, tuple): # It might be the root Element + elt, _, _, flag = node + if flag in ("text", "tail"): + return base.TEXT, getattr(elt, flag) + else: + node = elt + + if not(hasattr(node, "tag")): + node = node.getroot() + + if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): + return (base.DOCUMENT,) + + elif node.tag == "<!DOCTYPE>": + return (base.DOCTYPE, node.text, + node.get("publicId"), node.get("systemId")) + + elif node.tag == ElementTreeCommentType: + return base.COMMENT, node.text + + else: + assert isinstance(node.tag, string_types), type(node.tag) + # This is assumed to be an ordinary element + match = tag_regexp.match(node.tag) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = node.tag + attrs = OrderedDict() + for name, value in list(node.attrib.items()): + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, tag, + attrs, len(node) or node.text) + + def getFirstChild(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + element, key, parents, flag = node, None, [], None + + if flag in ("text", "tail"): + return None + else: + if element.text: + return element, key, parents, "text" + elif len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + + def getNextSibling(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + else: + if element.tail and flag != "tail": + return element, key, parents, "tail" + elif key < len(parents[-1]) - 1: + return parents[-1][key + 1], key + 1, parents, None + else: + return None + + def getParentNode(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if not parents: + return element + else: + return element, key, parents, None + else: + parent = parents.pop() + if not parents: + return parent + else: + assert list(parents[-1]).count(parent) == 1 + return parent, list(parents[-1]).index(parent), parents, None + + return locals() + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py new file mode 100755 index 0000000..e81ddf3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from lxml import etree +from ..treebuilders.etree import tag_regexp + +from . import base + +from .. import _ihatexml + + +def ensure_str(s): + if s is None: + return None + elif isinstance(s, text_type): + return s + else: + return s.decode("ascii", "strict") + + +class Root(object): + def __init__(self, et): + self.elementtree = et + self.children = [] + + try: + if et.docinfo.internalDTD: + self.children.append(Doctype(self, + ensure_str(et.docinfo.root_name), + ensure_str(et.docinfo.public_id), + ensure_str(et.docinfo.system_url))) + except AttributeError: + pass + + try: + node = et.getroot() + except AttributeError: + node = et + + while node.getprevious() is not None: + node = node.getprevious() + while node is not None: + self.children.append(node) + node = node.getnext() + + self.text = None + self.tail = None + + def __getitem__(self, key): + return self.children[key] + + def getnext(self): + return None + + def __len__(self): + return 1 + + +class Doctype(object): + def __init__(self, root_node, name, public_id, system_id): + self.root_node = root_node + self.name = name + self.public_id = public_id + self.system_id = system_id + + self.text = None + self.tail = None + + def getnext(self): + return self.root_node.children[1] + + +class FragmentRoot(Root): + def __init__(self, children): + self.children = [FragmentWrapper(self, child) for child in children] + self.text = self.tail = None + + def getnext(self): + return None + + +class FragmentWrapper(object): + def __init__(self, fragment_root, obj): + self.root_node = fragment_root + self.obj = obj + if hasattr(self.obj, 'text'): + self.text = ensure_str(self.obj.text) + else: + self.text = None + if hasattr(self.obj, 'tail'): + self.tail = ensure_str(self.obj.tail) + else: + self.tail = None + + def __getattr__(self, name): + return getattr(self.obj, name) + + def getnext(self): + siblings = self.root_node.children + idx = siblings.index(self) + if idx < len(siblings) - 1: + return siblings[idx + 1] + else: + return None + + def __getitem__(self, key): + return self.obj[key] + + def __bool__(self): + return bool(self.obj) + + def getparent(self): + return None + + def __str__(self): + return str(self.obj) + + def __unicode__(self): + return str(self.obj) + + def __len__(self): + return len(self.obj) + + +class TreeWalker(base.NonRecursiveTreeWalker): + def __init__(self, tree): + # pylint:disable=redefined-variable-type + if isinstance(tree, list): + self.fragmentChildren = set(tree) + tree = FragmentRoot(tree) + else: + self.fragmentChildren = set() + tree = Root(tree) + base.NonRecursiveTreeWalker.__init__(self, tree) + self.filter = _ihatexml.InfosetFilter() + + def getNodeDetails(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + return base.TEXT, ensure_str(getattr(node, key)) + + elif isinstance(node, Root): + return (base.DOCUMENT,) + + elif isinstance(node, Doctype): + return base.DOCTYPE, node.name, node.public_id, node.system_id + + elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): + return base.TEXT, ensure_str(node.obj) + + elif node.tag == etree.Comment: + return base.COMMENT, ensure_str(node.text) + + elif node.tag == etree.Entity: + return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; + + else: + # This is assumed to be an ordinary element + match = tag_regexp.match(ensure_str(node.tag)) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = ensure_str(node.tag) + attrs = {} + for name, value in list(node.attrib.items()): + name = ensure_str(name) + value = ensure_str(value) + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), + attrs, len(node) > 0 or node.text) + + def getFirstChild(self, node): + assert not isinstance(node, tuple), "Text nodes have no children" + + assert len(node) or node.text, "Node has no children" + if node.text: + return (node, "text") + else: + return node[0] + + def getNextSibling(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + # XXX: we cannot use a "bool(node) and node[0] or None" construct here + # because node[0] might evaluate to False if it has no child element + if len(node): + return node[0] + else: + return None + else: # tail + return node.getnext() + + return (node, "tail") if node.tail else node.getnext() + + def getParentNode(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + return node + # else: fallback to "normal" processing + elif node in self.fragmentChildren: + return None + + return node.getparent() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py new file mode 100755 index 0000000..7483be2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName +from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT +from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT + +from . import base + +from ..constants import voidElements, namespaces + + +class TreeWalker(base.TreeWalker): + def __iter__(self): + # Buffer the events so we can pass in the following one + previous = None + for event in self.tree: + if previous is not None: + for token in self.tokens(previous, event): + yield token + previous = event + + # Don't forget the final event! + if previous is not None: + for token in self.tokens(previous, None): + yield token + + def tokens(self, event, next): + kind, data, _ = event + if kind == START: + tag, attribs = data + name = tag.localname + namespace = tag.namespace + converted_attribs = {} + for k, v in attribs: + if isinstance(k, QName): + converted_attribs[(k.namespace, k.localname)] = v + else: + converted_attribs[(None, k)] = v + + if namespace == namespaces["html"] and name in voidElements: + for token in self.emptyTag(namespace, name, converted_attribs, + not next or next[0] != END or + next[1] != tag): + yield token + else: + yield self.startTag(namespace, name, converted_attribs) + + elif kind == END: + name = data.localname + namespace = data.namespace + if namespace != namespaces["html"] or name not in voidElements: + yield self.endTag(namespace, name) + + elif kind == COMMENT: + yield self.comment(data) + + elif kind == TEXT: + for token in self.text(data): + yield token + + elif kind == DOCTYPE: + yield self.doctype(*data) + + elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, + START_CDATA, END_CDATA, PI): + pass + + else: + yield self.unknown(kind) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/__init__.py new file mode 100755 index 0000000..847bf93 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/codec.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/codec.py new file mode 100755 index 0000000..98c65ea --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + 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 = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/compat.py new file mode 100755 index 0000000..4d47f33 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/core.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/core.py new file mode 100755 index 0000000..104624a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/core.py @@ -0,0 +1,396 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] == 3: + unicode = str + unichr = chr + +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): + v = unicodedata.combining(unichr(cp)) + if v == 0: + if not unicodedata.name(unichr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # 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 {0} at position {1}'.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 {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + 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 {0} 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 {0} 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): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + 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): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + 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, pos, exception=False): + + 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 == u'\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 + + +def check_label(label): + + 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 {0} not allowed at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.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 {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + ulabel(label) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + 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() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + 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, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + 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(u'.') + 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(u'') + return u'.'.join(result) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/idnadata.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/idnadata.py new file mode 100755 index 0000000..a80c959 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/idnadata.py @@ -0,0 +1,1979 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "11.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, + 0x340000004db6, + 0x4e0000009ff0, + 0xf9000000fa6e, + 0xfa700000fada, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5ef000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b11f, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + ), +} +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: 85, + 0x857: 85, + 0x858: 85, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 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, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 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, + 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, +} +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, + 0x8a0000008b5, + 0x8b6000008be, + 0x8d3000008e2, + 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, + 0xb5600000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0000000d04, + 0xd0500000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8200000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8700000e89, + 0xe8a00000e8b, + 0xe8d00000e8e, + 0xe9400000e98, + 0xe9900000ea0, + 0xea100000ea4, + 0xea500000ea6, + 0xea700000ea8, + 0xeaa00000eac, + 0xead00000eb3, + 0xeb400000eba, + 0xebb00000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 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, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 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, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfa, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001dfa, + 0x1dfb00001e00, + 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, + 0x2c3000002c5f, + 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, + 0x31a0000031bb, + 0x31f000003200, + 0x340000004db6, + 0x4e0000009ff0, + 0xa0000000a48d, + 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, + 0xa7f70000a7f8, + 0xa7fa0000a828, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab66, + 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, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 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, + 0x10f0000010f1d, + 0x10f2700010f28, + 0x10f3000010f51, + 0x1100000011047, + 0x1106600011070, + 0x1107f000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1114400011147, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111c9000111cd, + 0x111d0000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e0001123f, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133b00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x1145e0001145f, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b8, + 0x116c0000116ca, + 0x117000001171b, + 0x1171d0001172c, + 0x117300001173a, + 0x118000001183b, + 0x118c0000118ea, + 0x118ff00011900, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a84, + 0x11a8600011a9a, + 0x11a9d00011a9e, + 0x11ac000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x11d6000011d66, + 0x11d6700011d69, + 0x11d6a00011d8f, + 0x11d9000011d92, + 0x11d9300011d99, + 0x11da000011daa, + 0x11ee000011ef7, + 0x120000001239a, + 0x1248000012544, + 0x130000001342f, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16e6000016e80, + 0x16f0000016f45, + 0x16f5000016f7f, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x17000000187f2, + 0x1880000018af3, + 0x1b0000001b11f, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94b, + 0x1e9500001e95a, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/intranges.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/intranges.py new file mode 100755 index 0000000..fa8a735 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/intranges.py @@ -0,0 +1,53 @@ +""" +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 + +def intranges_from_list(list_): + """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, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """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/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/package_data.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/package_data.py new file mode 100755 index 0000000..257e898 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.8' + diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/uts46data.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/uts46data.py new file mode 100755 index 0000000..a68ed4c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/idna/uts46data.py @@ -0,0 +1,8205 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "11.0.0" +def _seg_0(): + 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', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + 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', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'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', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'M', u'ϳ'), + (0x380, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + ] + +def _seg_7(): + return [ + (0x403, 'M', u'ѓ'), + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + ] + +def _seg_8(): + return [ + (0x49E, 'M', u'ҟ'), + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + ] + +def _seg_9(): + return [ + (0x503, 'V'), + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'M', u'ԩ'), + (0x529, 'V'), + (0x52A, 'M', u'ԫ'), + (0x52B, 'V'), + (0x52C, 'M', u'ԭ'), + (0x52D, 'V'), + (0x52E, 'M', u'ԯ'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5EF, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + ] + +def _seg_10(): + return [ + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (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'), + (0x8A0, 'V'), + (0x8B5, 'X'), + (0x8B6, 'V'), + (0x8BE, 'X'), + (0x8D3, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (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', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (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', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (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', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + ] + +def _seg_11(): + return [ + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (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'), + (0xB56, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (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'), + ] + +def _seg_12(): + return [ + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC78, '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'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD00, 'V'), + (0xD04, 'X'), + (0xD05, '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'), + (0xD82, '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', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE87, 'V'), + (0xE89, 'X'), + (0xE8A, 'V'), + (0xE8B, 'X'), + (0xE8D, 'V'), + (0xE8E, 'X'), + (0xE94, 'V'), + ] + +def _seg_13(): + return [ + (0xE98, 'X'), + (0xE99, 'V'), + (0xEA0, 'X'), + (0xEA1, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEA8, 'X'), + (0xEAA, 'V'), + (0xEAC, 'X'), + (0xEAD, 'V'), + (0xEB3, 'M', u'ໍາ'), + (0xEB4, 'V'), + (0xEBA, 'X'), + (0xEBB, 'V'), + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (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'), + ] + +def _seg_14(): + return [ + (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'), + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', u'Ᏸ'), + (0x13F9, 'M', u'Ᏹ'), + (0x13FA, 'M', u'Ᏺ'), + (0x13FB, 'M', u'Ᏻ'), + (0x13FC, 'M', u'Ᏼ'), + (0x13FD, 'M', u'Ᏽ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, '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'), + (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'), + ] + +def _seg_15(): + return [ + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1ABF, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'M', u'в'), + (0x1C81, 'M', u'д'), + (0x1C82, 'M', u'о'), + (0x1C83, 'M', u'с'), + (0x1C84, 'M', u'т'), + (0x1C86, 'M', u'ъ'), + (0x1C87, 'M', u'ѣ'), + (0x1C88, 'M', u'ꙋ'), + (0x1C89, 'X'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFA, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + ] + +def _seg_16(): + return [ + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DFA, 'X'), + (0x1DFB, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + ] + +def _seg_17(): + return [ + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + ] + +def _seg_18(): + return [ + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + ] + +def _seg_19(): + return [ + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + ] + +def _seg_20(): + return [ + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + ] + +def _seg_21(): + return [ + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20C0, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + ] + +def _seg_22(): + return [ + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + ] + +def _seg_23(): + return [ + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + ] + +def _seg_24(): + return [ + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B98, 'V'), + (0x2BC9, 'X'), + (0x2BCA, 'V'), + (0x2BFF, 'X'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + ] + +def _seg_25(): + return [ + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + ] + +def _seg_26(): + return [ + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (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'), + (0x2E4F, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + ] + +def _seg_27(): + return [ + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + ] + +def _seg_28(): + return [ + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x3130, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + ] + +def _seg_29(): + return [ + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + ] + +def _seg_30(): + return [ + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31BB, 'X'), + (0x31C0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + ] + +def _seg_31(): + return [ + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + ] + +def _seg_32(): + return [ + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'X'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + ] + +def _seg_33(): + return [ + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + ] + +def _seg_34(): + return [ + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + ] + +def _seg_35(): + return [ + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + (0x3400, 'V'), + (0x4DB6, 'X'), + (0x4DC0, 'V'), + (0x9FF0, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'M', u'ꚙ'), + (0xA699, 'V'), + (0xA69A, 'M', u'ꚛ'), + (0xA69B, 'V'), + (0xA69C, 'M', u'ъ'), + (0xA69D, 'M', u'ь'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + ] + +def _seg_36(): + return [ + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + ] + +def _seg_37(): + return [ + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA796, 'M', u'ꞗ'), + (0xA797, 'V'), + (0xA798, 'M', u'ꞙ'), + (0xA799, 'V'), + (0xA79A, 'M', u'ꞛ'), + (0xA79B, 'V'), + (0xA79C, 'M', u'ꞝ'), + (0xA79D, 'V'), + (0xA79E, 'M', u'ꞟ'), + (0xA79F, 'V'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'M', u'ɜ'), + (0xA7AC, 'M', u'ɡ'), + (0xA7AD, 'M', u'ɬ'), + (0xA7AE, 'M', u'ɪ'), + (0xA7AF, 'V'), + (0xA7B0, 'M', u'ʞ'), + (0xA7B1, 'M', u'ʇ'), + (0xA7B2, 'M', u'ʝ'), + (0xA7B3, 'M', u'ꭓ'), + (0xA7B4, 'M', u'ꞵ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', u'ꞷ'), + (0xA7B7, 'V'), + (0xA7B8, 'X'), + (0xA7B9, 'V'), + (0xA7BA, 'X'), + (0xA7F7, 'V'), + (0xA7F8, 'M', u'ħ'), + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82C, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + (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', u'ꜧ'), + (0xAB5D, 'M', u'ꬷ'), + (0xAB5E, 'M', u'ɫ'), + (0xAB5F, 'M', u'ꭒ'), + (0xAB60, 'V'), + (0xAB66, 'X'), + (0xAB70, 'M', u'Ꭰ'), + (0xAB71, 'M', u'Ꭱ'), + (0xAB72, 'M', u'Ꭲ'), + (0xAB73, 'M', u'Ꭳ'), + (0xAB74, 'M', u'Ꭴ'), + (0xAB75, 'M', u'Ꭵ'), + (0xAB76, 'M', u'Ꭶ'), + (0xAB77, 'M', u'Ꭷ'), + (0xAB78, 'M', u'Ꭸ'), + (0xAB79, 'M', u'Ꭹ'), + (0xAB7A, 'M', u'Ꭺ'), + ] + +def _seg_38(): + return [ + (0xAB7B, 'M', u'Ꭻ'), + (0xAB7C, 'M', u'Ꭼ'), + (0xAB7D, 'M', u'Ꭽ'), + (0xAB7E, 'M', u'Ꭾ'), + (0xAB7F, 'M', u'Ꭿ'), + (0xAB80, 'M', u'Ꮀ'), + (0xAB81, 'M', u'Ꮁ'), + (0xAB82, 'M', u'Ꮂ'), + (0xAB83, 'M', u'Ꮃ'), + (0xAB84, 'M', u'Ꮄ'), + (0xAB85, 'M', u'Ꮅ'), + (0xAB86, 'M', u'Ꮆ'), + (0xAB87, 'M', u'Ꮇ'), + (0xAB88, 'M', u'Ꮈ'), + (0xAB89, 'M', u'Ꮉ'), + (0xAB8A, 'M', u'Ꮊ'), + (0xAB8B, 'M', u'Ꮋ'), + (0xAB8C, 'M', u'Ꮌ'), + (0xAB8D, 'M', u'Ꮍ'), + (0xAB8E, 'M', u'Ꮎ'), + (0xAB8F, 'M', u'Ꮏ'), + (0xAB90, 'M', u'Ꮐ'), + (0xAB91, 'M', u'Ꮑ'), + (0xAB92, 'M', u'Ꮒ'), + (0xAB93, 'M', u'Ꮓ'), + (0xAB94, 'M', u'Ꮔ'), + (0xAB95, 'M', u'Ꮕ'), + (0xAB96, 'M', u'Ꮖ'), + (0xAB97, 'M', u'Ꮗ'), + (0xAB98, 'M', u'Ꮘ'), + (0xAB99, 'M', u'Ꮙ'), + (0xAB9A, 'M', u'Ꮚ'), + (0xAB9B, 'M', u'Ꮛ'), + (0xAB9C, 'M', u'Ꮜ'), + (0xAB9D, 'M', u'Ꮝ'), + (0xAB9E, 'M', u'Ꮞ'), + (0xAB9F, 'M', u'Ꮟ'), + (0xABA0, 'M', u'Ꮠ'), + (0xABA1, 'M', u'Ꮡ'), + (0xABA2, 'M', u'Ꮢ'), + (0xABA3, 'M', u'Ꮣ'), + (0xABA4, 'M', u'Ꮤ'), + (0xABA5, 'M', u'Ꮥ'), + (0xABA6, 'M', u'Ꮦ'), + (0xABA7, 'M', u'Ꮧ'), + (0xABA8, 'M', u'Ꮨ'), + (0xABA9, 'M', u'Ꮩ'), + (0xABAA, 'M', u'Ꮪ'), + (0xABAB, 'M', u'Ꮫ'), + (0xABAC, 'M', u'Ꮬ'), + (0xABAD, 'M', u'Ꮭ'), + (0xABAE, 'M', u'Ꮮ'), + (0xABAF, 'M', u'Ꮯ'), + (0xABB0, 'M', u'Ꮰ'), + (0xABB1, 'M', u'Ꮱ'), + (0xABB2, 'M', u'Ꮲ'), + (0xABB3, 'M', u'Ꮳ'), + (0xABB4, 'M', u'Ꮴ'), + (0xABB5, 'M', u'Ꮵ'), + (0xABB6, 'M', u'Ꮶ'), + (0xABB7, 'M', u'Ꮷ'), + (0xABB8, 'M', u'Ꮸ'), + (0xABB9, 'M', u'Ꮹ'), + (0xABBA, 'M', u'Ꮺ'), + (0xABBB, 'M', u'Ꮻ'), + (0xABBC, 'M', u'Ꮼ'), + (0xABBD, 'M', u'Ꮽ'), + (0xABBE, 'M', u'Ꮾ'), + (0xABBF, 'M', u'Ꮿ'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + ] + +def _seg_39(): + return [ + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + ] + +def _seg_40(): + return [ + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + ] + +def _seg_41(): + return [ + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + ] + +def _seg_42(): + return [ + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + ] + +def _seg_43(): + return [ + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + ] + +def _seg_44(): + return [ + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + ] + +def _seg_45(): + return [ + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + ] + +def _seg_46(): + return [ + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + ] + +def _seg_47(): + return [ + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + ] + +def _seg_48(): + return [ + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + ] + +def _seg_49(): + return [ + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + ] + +def _seg_50(): + return [ + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + ] + +def _seg_51(): + return [ + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + ] + +def _seg_52(): + return [ + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (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'), + (0x1019C, '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', u'𐐨'), + (0x10401, 'M', u'𐐩'), + ] + +def _seg_53(): + return [ + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', u'𐓘'), + (0x104B1, 'M', u'𐓙'), + (0x104B2, 'M', u'𐓚'), + (0x104B3, 'M', u'𐓛'), + (0x104B4, 'M', u'𐓜'), + (0x104B5, 'M', u'𐓝'), + (0x104B6, 'M', u'𐓞'), + (0x104B7, 'M', u'𐓟'), + (0x104B8, 'M', u'𐓠'), + (0x104B9, 'M', u'𐓡'), + (0x104BA, 'M', u'𐓢'), + (0x104BB, 'M', u'𐓣'), + (0x104BC, 'M', u'𐓤'), + (0x104BD, 'M', u'𐓥'), + (0x104BE, 'M', u'𐓦'), + (0x104BF, 'M', u'𐓧'), + (0x104C0, 'M', u'𐓨'), + (0x104C1, 'M', u'𐓩'), + (0x104C2, 'M', u'𐓪'), + (0x104C3, 'M', u'𐓫'), + (0x104C4, 'M', u'𐓬'), + (0x104C5, 'M', u'𐓭'), + (0x104C6, 'M', u'𐓮'), + (0x104C7, 'M', u'𐓯'), + (0x104C8, 'M', u'𐓰'), + (0x104C9, 'M', u'𐓱'), + (0x104CA, 'M', u'𐓲'), + (0x104CB, 'M', u'𐓳'), + (0x104CC, 'M', u'𐓴'), + (0x104CD, 'M', u'𐓵'), + (0x104CE, 'M', u'𐓶'), + (0x104CF, 'M', u'𐓷'), + (0x104D0, 'M', u'𐓸'), + (0x104D1, 'M', u'𐓹'), + (0x104D2, 'M', u'𐓺'), + (0x104D3, 'M', u'𐓻'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + ] + +def _seg_54(): + return [ + (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'), + (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', u'𐳀'), + (0x10C81, 'M', u'𐳁'), + (0x10C82, 'M', u'𐳂'), + (0x10C83, 'M', u'𐳃'), + (0x10C84, 'M', u'𐳄'), + (0x10C85, 'M', u'𐳅'), + (0x10C86, 'M', u'𐳆'), + (0x10C87, 'M', u'𐳇'), + (0x10C88, 'M', u'𐳈'), + (0x10C89, 'M', u'𐳉'), + (0x10C8A, 'M', u'𐳊'), + (0x10C8B, 'M', u'𐳋'), + (0x10C8C, 'M', u'𐳌'), + (0x10C8D, 'M', u'𐳍'), + (0x10C8E, 'M', u'𐳎'), + (0x10C8F, 'M', u'𐳏'), + (0x10C90, 'M', u'𐳐'), + (0x10C91, 'M', u'𐳑'), + (0x10C92, 'M', u'𐳒'), + (0x10C93, 'M', u'𐳓'), + (0x10C94, 'M', u'𐳔'), + (0x10C95, 'M', u'𐳕'), + (0x10C96, 'M', u'𐳖'), + (0x10C97, 'M', u'𐳗'), + (0x10C98, 'M', u'𐳘'), + (0x10C99, 'M', u'𐳙'), + (0x10C9A, 'M', u'𐳚'), + (0x10C9B, 'M', u'𐳛'), + (0x10C9C, 'M', u'𐳜'), + (0x10C9D, 'M', u'𐳝'), + (0x10C9E, 'M', u'𐳞'), + (0x10C9F, 'M', u'𐳟'), + (0x10CA0, 'M', u'𐳠'), + (0x10CA1, 'M', u'𐳡'), + (0x10CA2, 'M', u'𐳢'), + (0x10CA3, 'M', u'𐳣'), + (0x10CA4, 'M', u'𐳤'), + (0x10CA5, 'M', u'𐳥'), + (0x10CA6, 'M', u'𐳦'), + (0x10CA7, 'M', u'𐳧'), + (0x10CA8, 'M', u'𐳨'), + ] + +def _seg_55(): + return [ + (0x10CA9, 'M', u'𐳩'), + (0x10CAA, 'M', u'𐳪'), + (0x10CAB, 'M', u'𐳫'), + (0x10CAC, 'M', u'𐳬'), + (0x10CAD, 'M', u'𐳭'), + (0x10CAE, 'M', u'𐳮'), + (0x10CAF, 'M', u'𐳯'), + (0x10CB0, 'M', u'𐳰'), + (0x10CB1, 'M', u'𐳱'), + (0x10CB2, 'M', u'𐳲'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D28, 'X'), + (0x10D30, 'V'), + (0x10D3A, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x10F00, 'V'), + (0x10F28, 'X'), + (0x10F30, 'V'), + (0x10F5A, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11147, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111CE, 'X'), + (0x111D0, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + (0x11213, 'V'), + (0x1123F, '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'), + (0x1145A, 'X'), + (0x1145B, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + ] + +def _seg_56(): + return [ + (0x1145F, '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'), + (0x116B8, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171B, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11740, 'X'), + (0x11800, 'V'), + (0x1183C, 'X'), + (0x118A0, 'M', u'𑣀'), + (0x118A1, 'M', u'𑣁'), + (0x118A2, 'M', u'𑣂'), + (0x118A3, 'M', u'𑣃'), + (0x118A4, 'M', u'𑣄'), + (0x118A5, 'M', u'𑣅'), + (0x118A6, 'M', u'𑣆'), + (0x118A7, 'M', u'𑣇'), + (0x118A8, 'M', u'𑣈'), + (0x118A9, 'M', u'𑣉'), + (0x118AA, 'M', u'𑣊'), + (0x118AB, 'M', u'𑣋'), + (0x118AC, 'M', u'𑣌'), + (0x118AD, 'M', u'𑣍'), + (0x118AE, 'M', u'𑣎'), + (0x118AF, 'M', u'𑣏'), + (0x118B0, 'M', u'𑣐'), + (0x118B1, 'M', u'𑣑'), + (0x118B2, 'M', u'𑣒'), + (0x118B3, 'M', u'𑣓'), + (0x118B4, 'M', u'𑣔'), + (0x118B5, 'M', u'𑣕'), + (0x118B6, 'M', u'𑣖'), + (0x118B7, 'M', u'𑣗'), + (0x118B8, 'M', u'𑣘'), + (0x118B9, 'M', u'𑣙'), + (0x118BA, 'M', u'𑣚'), + (0x118BB, 'M', u'𑣛'), + (0x118BC, 'M', u'𑣜'), + (0x118BD, 'M', u'𑣝'), + (0x118BE, 'M', u'𑣞'), + (0x118BF, 'M', u'𑣟'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11900, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11A84, 'X'), + (0x11A86, 'V'), + (0x11AA3, 'X'), + (0x11AC0, 'V'), + (0x11AF9, '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'), + ] + +def _seg_57(): + return [ + (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'), + (0x12000, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16A70, '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'), + (0x16E60, 'V'), + (0x16E9B, 'X'), + (0x16F00, 'V'), + (0x16F45, 'X'), + (0x16F50, 'V'), + (0x16F7F, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE2, 'X'), + (0x17000, 'V'), + (0x187F2, 'X'), + (0x18800, 'V'), + (0x18AF3, 'X'), + (0x1B000, 'V'), + (0x1B11F, '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'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1E9, 'X'), + (0x1D200, 'V'), + ] + +def _seg_58(): + return [ + (0x1D246, 'X'), + (0x1D2E0, 'V'), + (0x1D2F4, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D379, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + ] + +def _seg_59(): + return [ + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + ] + +def _seg_60(): + return [ + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + ] + +def _seg_61(): + return [ + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + ] + +def _seg_62(): + return [ + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + ] + +def _seg_63(): + return [ + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + ] + +def _seg_64(): + return [ + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + ] + +def _seg_65(): + return [ + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + ] + +def _seg_66(): + return [ + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + ] + +def _seg_67(): + return [ + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + ] + +def _seg_68(): + return [ + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', u'𞤢'), + (0x1E901, 'M', u'𞤣'), + (0x1E902, 'M', u'𞤤'), + (0x1E903, 'M', u'𞤥'), + (0x1E904, 'M', u'𞤦'), + (0x1E905, 'M', u'𞤧'), + (0x1E906, 'M', u'𞤨'), + (0x1E907, 'M', u'𞤩'), + (0x1E908, 'M', u'𞤪'), + (0x1E909, 'M', u'𞤫'), + (0x1E90A, 'M', u'𞤬'), + (0x1E90B, 'M', u'𞤭'), + (0x1E90C, 'M', u'𞤮'), + (0x1E90D, 'M', u'𞤯'), + (0x1E90E, 'M', u'𞤰'), + (0x1E90F, 'M', u'𞤱'), + (0x1E910, 'M', u'𞤲'), + (0x1E911, 'M', u'𞤳'), + (0x1E912, 'M', u'𞤴'), + (0x1E913, 'M', u'𞤵'), + (0x1E914, 'M', u'𞤶'), + (0x1E915, 'M', u'𞤷'), + (0x1E916, 'M', u'𞤸'), + (0x1E917, 'M', u'𞤹'), + (0x1E918, 'M', u'𞤺'), + (0x1E919, 'M', u'𞤻'), + (0x1E91A, 'M', u'𞤼'), + (0x1E91B, 'M', u'𞤽'), + (0x1E91C, 'M', u'𞤾'), + (0x1E91D, 'M', u'𞤿'), + (0x1E91E, 'M', u'𞥀'), + (0x1E91F, 'M', u'𞥁'), + (0x1E920, 'M', u'𞥂'), + (0x1E921, 'M', u'𞥃'), + (0x1E922, 'V'), + (0x1E94B, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + (0x1EC71, 'V'), + (0x1ECB5, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + ] + +def _seg_69(): + return [ + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + ] + +def _seg_70(): + return [ + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (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', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'V'), + (0x1F10D, 'X'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + ] + +def _seg_71(): + return [ + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'V'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'X'), + (0x1F170, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F1AD, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'M', u'配'), + ] + +def _seg_72(): + return [ + (0x1F23C, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F260, 'V'), + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D5, 'X'), + (0x1F6E0, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6FA, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x1F780, 'V'), + (0x1F7D9, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F900, 'V'), + (0x1F90C, 'X'), + (0x1F910, 'V'), + (0x1F93F, 'X'), + (0x1F940, 'V'), + (0x1F971, 'X'), + (0x1F973, 'V'), + (0x1F977, 'X'), + (0x1F97A, 'V'), + (0x1F97B, 'X'), + (0x1F97C, 'V'), + (0x1F9A3, 'X'), + (0x1F9B0, 'V'), + (0x1F9BA, 'X'), + (0x1F9C0, 'V'), + (0x1F9C3, 'X'), + (0x1F9D0, 'V'), + (0x1FA00, 'X'), + (0x1FA60, 'V'), + (0x1FA6E, 'X'), + (0x20000, 'V'), + (0x2A6D7, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + ] + +def _seg_73(): + return [ + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + ] + +def _seg_74(): + return [ + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + ] + +def _seg_75(): + return [ + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + ] + +def _seg_76(): + return [ + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + ] + +def _seg_77(): + return [ + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0xE0100, 'I'), + ] + +def _seg_78(): + return [ + (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() +) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/ipaddress.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/ipaddress.py new file mode 100755 index 0000000..f2d0766 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/ipaddress.py @@ -0,0 +1,2419 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.22' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError("%s and %s are not of the same version" (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/__init__.py new file mode 100755 index 0000000..a6f44a5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/__init__.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- + +""" +lockfile.py - Platform-independent advisory file locks. + +Requires Python 2.5 unless you apply 2.4.diff +Locking is done on a per-thread basis instead of a per-process basis. + +Usage: + +>>> lock = LockFile('somefile') +>>> try: +... lock.acquire() +... except AlreadyLocked: +... print 'somefile', 'is locked already.' +... except LockFailed: +... print 'somefile', 'can\\'t be locked.' +... else: +... print 'got lock' +got lock +>>> print lock.is_locked() +True +>>> lock.release() + +>>> lock = LockFile('somefile') +>>> print lock.is_locked() +False +>>> with lock: +... print lock.is_locked() +True +>>> print lock.is_locked() +False + +>>> lock = LockFile('somefile') +>>> # It is okay to lock twice from the same thread... +>>> with lock: +... lock.acquire() +... +>>> # Though no counter is kept, so you can't unlock multiple times... +>>> print lock.is_locked() +False + +Exceptions: + + Error - base class for other exceptions + LockError - base class for all locking exceptions + AlreadyLocked - Another thread or process already holds the lock + LockFailed - Lock failed for some other reason + UnlockError - base class for all unlocking exceptions + AlreadyUnlocked - File was not locked. + NotMyLock - File was locked but not by the current thread/process +""" + +from __future__ import absolute_import + +import functools +import os +import socket +import threading +import warnings + +# Work with PEP8 and non-PEP8 versions of threading module. +if not hasattr(threading, "current_thread"): + threading.current_thread = threading.currentThread +if not hasattr(threading.Thread, "get_name"): + threading.Thread.get_name = threading.Thread.getName + +__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', + 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', + 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', + 'LockBase', 'locked'] + + +class Error(Exception): + """ + Base class for other exceptions. + + >>> try: + ... raise Error + ... except Exception: + ... pass + """ + pass + + +class LockError(Error): + """ + Base class for error arising from attempts to acquire the lock. + + >>> try: + ... raise LockError + ... except Error: + ... pass + """ + pass + + +class LockTimeout(LockError): + """Raised when lock creation fails within a user-defined period of time. + + >>> try: + ... raise LockTimeout + ... except LockError: + ... pass + """ + pass + + +class AlreadyLocked(LockError): + """Some other thread/process is locking the file. + + >>> try: + ... raise AlreadyLocked + ... except LockError: + ... pass + """ + pass + + +class LockFailed(LockError): + """Lock file creation failed for some other reason. + + >>> try: + ... raise LockFailed + ... except LockError: + ... pass + """ + pass + + +class UnlockError(Error): + """ + Base class for errors arising from attempts to release the lock. + + >>> try: + ... raise UnlockError + ... except Error: + ... pass + """ + pass + + +class NotLocked(UnlockError): + """Raised when an attempt is made to unlock an unlocked file. + + >>> try: + ... raise NotLocked + ... except UnlockError: + ... pass + """ + pass + + +class NotMyLock(UnlockError): + """Raised when an attempt is made to unlock a file someone else locked. + + >>> try: + ... raise NotMyLock + ... except UnlockError: + ... pass + """ + pass + + +class _SharedBase(object): + def __init__(self, path): + self.path = path + + def acquire(self, timeout=None): + """ + Acquire the lock. + + * If timeout is omitted (or None), wait forever trying to lock the + file. + + * If timeout > 0, try to acquire the lock for that many seconds. If + the lock period expires and the file is still locked, raise + LockTimeout. + + * If timeout <= 0, raise AlreadyLocked immediately if the file is + already locked. + """ + raise NotImplemented("implement in subclass") + + def release(self): + """ + Release the lock. + + If the file is not locked, raise NotLocked. + """ + raise NotImplemented("implement in subclass") + + def __enter__(self): + """ + Context manager support. + """ + self.acquire() + return self + + def __exit__(self, *_exc): + """ + Context manager support. + """ + self.release() + + def __repr__(self): + return "<%s: %r>" % (self.__class__.__name__, self.path) + + +class LockBase(_SharedBase): + """Base class for platform-specific lock classes.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = LockBase('somefile') + >>> lock = LockBase('somefile', threaded=False) + """ + super(LockBase, self).__init__(path) + self.lock_file = os.path.abspath(path) + ".lock" + self.hostname = socket.gethostname() + self.pid = os.getpid() + if threaded: + t = threading.current_thread() + # Thread objects in Python 2.4 and earlier do not have ident + # attrs. Worm around that. + ident = getattr(t, "ident", hash(t)) + self.tname = "-%x" % (ident & 0xffffffff) + else: + self.tname = "" + dirname = os.path.dirname(self.lock_file) + + # unique name is mostly about the current process, but must + # also contain the path -- otherwise, two adjacent locked + # files conflict (one file gets locked, creating lock-file and + # unique file, the other one gets locked, creating lock-file + # and overwriting the already existing lock-file, then one + # gets unlocked, deleting both lock-file and unique file, + # finally the last lock errors out upon releasing. + self.unique_name = os.path.join(dirname, + "%s%s.%s%s" % (self.hostname, + self.tname, + self.pid, + hash(self.path))) + self.timeout = timeout + + def is_locked(self): + """ + Tell whether or not the file is locked. + """ + raise NotImplemented("implement in subclass") + + def i_am_locking(self): + """ + Return True if this object is locking the file. + """ + raise NotImplemented("implement in subclass") + + def break_lock(self): + """ + Remove a lock. Useful if a locking thread failed to unlock. + """ + raise NotImplemented("implement in subclass") + + def __repr__(self): + return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, + self.path) + + +def _fl_helper(cls, mod, *args, **kwds): + warnings.warn("Import from %s module instead of lockfile package" % mod, + DeprecationWarning, stacklevel=2) + # This is a bit funky, but it's only for awhile. The way the unit tests + # are constructed this function winds up as an unbound method, so it + # actually takes three args, not two. We want to toss out self. + if not isinstance(args[0], str): + # We are testing, avoid the first arg + args = args[1:] + if len(args) == 1 and not kwds: + kwds["threaded"] = True + return cls(*args, **kwds) + + +def LinkFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import LinkLockFile from the + lockfile.linklockfile module. + """ + from . import linklockfile + return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", + *args, **kwds) + + +def MkdirFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import MkdirLockFile from the + lockfile.mkdirlockfile module. + """ + from . import mkdirlockfile + return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", + *args, **kwds) + + +def SQLiteFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import SQLiteLockFile from the + lockfile.mkdirlockfile module. + """ + from . import sqlitelockfile + return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", + *args, **kwds) + + +def locked(path, timeout=None): + """Decorator which enables locks for decorated function. + + Arguments: + - path: path for lockfile. + - timeout (optional): Timeout for acquiring lock. + + Usage: + @locked('/var/run/myname', timeout=0) + def myname(...): + ... + """ + def decor(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + lock = FileLock(path, timeout=timeout) + lock.acquire() + try: + return func(*args, **kwargs) + finally: + lock.release() + return wrapper + return decor + + +if hasattr(os, "link"): + from . import linklockfile as _llf + LockFile = _llf.LinkLockFile +else: + from . import mkdirlockfile as _mlf + LockFile = _mlf.MkdirLockFile + +FileLock = LockFile diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/linklockfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/linklockfile.py new file mode 100755 index 0000000..2ca9be0 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/linklockfile.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import + +import time +import os + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class LinkLockFile(LockBase): + """Lock access to a file using atomic property of link(2). + + >>> lock = LinkLockFile('somefile') + >>> lock = LinkLockFile('somefile', threaded=False) + """ + + def acquire(self, timeout=None): + try: + open(self.unique_name, "wb").close() + except IOError: + raise LockFailed("failed to create %s" % self.unique_name) + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a hard link to it. + try: + os.link(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + nlinks = os.stat(self.unique_name).st_nlink + if nlinks == 2: + # The original link plus the one I created == 2. We're + # good to go. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + os.unlink(self.unique_name) + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name) and + os.stat(self.unique_name).st_nlink == 2) + + def break_lock(self): + if os.path.exists(self.lock_file): + os.unlink(self.lock_file) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100755 index 0000000..05a8c96 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import, division + +import time +import os +import sys +import errno + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class MkdirLockFile(LockBase): + """Lock file by creating a directory.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = MkdirLockFile('somefile') + >>> lock = MkdirLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + # Lock file itself is a directory. Place the unique file name into + # it. + self.unique_name = os.path.join(self.lock_file, + "%s.%s%s" % (self.hostname, + self.tname, + self.pid)) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + else: + wait = max(0, timeout / 10) + + while True: + try: + os.mkdir(self.lock_file) + except OSError: + err = sys.exc_info()[1] + if err.errno == errno.EEXIST: + # Already locked. + if os.path.exists(self.unique_name): + # Already locked by me. + return + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock. + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(wait) + else: + # Couldn't create the lock for some other reason + raise LockFailed("failed to create %s" % self.lock_file) + else: + open(self.unique_name, "wb").close() + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.rmdir(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name)) + + def break_lock(self): + if os.path.exists(self.lock_file): + for name in os.listdir(self.lock_file): + os.unlink(os.path.join(self.lock_file, name)) + os.rmdir(self.lock_file) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py new file mode 100755 index 0000000..069e85b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +# pidlockfile.py +# +# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> +# +# This is free software: you may copy, modify, and/or distribute this work +# under the terms of the Python Software Foundation License, version 2 or +# later as published by the Python Software Foundation. +# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. + +""" Lockfile behaviour implemented via Unix PID files. + """ + +from __future__ import absolute_import + +import errno +import os +import time + +from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, + LockTimeout) + + +class PIDLockFile(LockBase): + """ Lockfile implemented as a Unix PID file. + + The lock file is a normal file named by the attribute `path`. + A lock's PID file contains a single line of text, containing + the process ID (PID) of the process that acquired the lock. + + >>> lock = PIDLockFile('somefile') + >>> lock = PIDLockFile('somefile') + """ + + def __init__(self, path, threaded=False, timeout=None): + # pid lockfiles don't support threaded operation, so always force + # False as the threaded arg. + LockBase.__init__(self, path, False, timeout) + self.unique_name = self.path + + def read_pid(self): + """ Get the PID from the lock file. + """ + return read_pid_from_pidfile(self.path) + + def is_locked(self): + """ Test if the lock is currently held. + + The lock is held if the PID file for this lock exists. + + """ + return os.path.exists(self.path) + + def i_am_locking(self): + """ Test if the lock is held by the current process. + + Returns ``True`` if the current process ID matches the + number stored in the PID file. + """ + return self.is_locked() and os.getpid() == self.read_pid() + + def acquire(self, timeout=None): + """ Acquire the lock. + + Creates the PID file for this lock, or raises an error if + the lock could not be acquired. + """ + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + try: + write_pid_to_pidfile(self.path) + except OSError as exc: + if exc.errno == errno.EEXIST: + # The lock creation failed. Maybe sleep a bit. + if time.time() > end_time: + if timeout is not None and timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + raise LockFailed("failed to create %s" % self.path) + else: + return + + def release(self): + """ Release the lock. + + Removes the PID file to release the lock, or raises an + error if the current process does not hold the lock. + + """ + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + remove_existing_pidfile(self.path) + + def break_lock(self): + """ Break an existing lock. + + Removes the PID file if it already exists, otherwise does + nothing. + + """ + remove_existing_pidfile(self.path) + + +def read_pid_from_pidfile(pidfile_path): + """ Read the PID recorded in the named PID file. + + Read and return the numeric PID recorded as text in the named + PID file. If the PID file cannot be read, or if the content is + not a valid PID, return ``None``. + + """ + pid = None + try: + pidfile = open(pidfile_path, 'r') + except IOError: + pass + else: + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. + # + # Programs that read PID files should be somewhat flexible + # in what they accept; i.e., they should ignore extra + # whitespace, leading zeroes, absence of the trailing + # newline, or additional lines in the PID file. + + line = pidfile.readline().strip() + try: + pid = int(line) + except ValueError: + pass + pidfile.close() + + return pid + + +def write_pid_to_pidfile(pidfile_path): + """ Write the PID in the named PID file. + + Get the numeric process ID (“PID”) of the current process + and write it to the named file as a line of text. + + """ + open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) + open_mode = 0o644 + pidfile_fd = os.open(pidfile_path, open_flags, open_mode) + pidfile = os.fdopen(pidfile_fd, 'w') + + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. For + # example, if crond was process number 25, /var/run/crond.pid + # would contain three characters: two, five, and newline. + + pid = os.getpid() + pidfile.write("%s\n" % pid) + pidfile.close() + + +def remove_existing_pidfile(pidfile_path): + """ Remove the named PID file if it exists. + + Removing a PID file that doesn't already exist puts us in the + desired state, so we ignore the condition if the file does not + exist. + + """ + try: + os.remove(pidfile_path) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + raise diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100755 index 0000000..f997e24 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py @@ -0,0 +1,156 @@ +from __future__ import absolute_import, division + +import time +import os + +try: + unicode +except NameError: + unicode = str + +from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked + + +class SQLiteLockFile(LockBase): + "Demonstrate SQL-based locking." + + testdb = None + + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = SQLiteLockFile('somefile') + >>> lock = SQLiteLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + self.lock_file = unicode(self.lock_file) + self.unique_name = unicode(self.unique_name) + + if SQLiteLockFile.testdb is None: + import tempfile + _fd, testdb = tempfile.mkstemp() + os.close(_fd) + os.unlink(testdb) + del _fd, tempfile + SQLiteLockFile.testdb = testdb + + import sqlite3 + self.connection = sqlite3.connect(SQLiteLockFile.testdb) + + c = self.connection.cursor() + try: + c.execute("create table locks" + "(" + " lock_file varchar(32)," + " unique_name varchar(32)" + ")") + except sqlite3.OperationalError: + pass + else: + self.connection.commit() + import atexit + atexit.register(os.unlink, SQLiteLockFile.testdb) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + elif timeout <= 0: + wait = 0 + else: + wait = timeout / 10 + + cursor = self.connection.cursor() + + while True: + if not self.is_locked(): + # Not locked. Try to lock it. + cursor.execute("insert into locks" + " (lock_file, unique_name)" + " values" + " (?, ?)", + (self.lock_file, self.unique_name)) + self.connection.commit() + + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) > 1: + # Nope. Someone else got there. Remove our lock. + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + else: + # Yup. We're done, so go home. + return + else: + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) == 1: + # We're the locker, so go home. + return + + # Maybe we should wait a bit longer. + if timeout is not None and time.time() > end_time: + if timeout > 0: + # No more waiting. + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock and we are impatient.. + raise AlreadyLocked("%s is already locked" % self.path) + + # Well, okay. We'll give it a bit longer. + time.sleep(wait) + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me (by %s)" % + (self.unique_name, self._who_is_locking())) + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + + def _who_is_locking(self): + cursor = self.connection.cursor() + cursor.execute("select unique_name from locks" + " where lock_file = ?", + (self.lock_file,)) + return cursor.fetchone()[0] + + def is_locked(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?", + (self.lock_file,)) + rows = cursor.fetchall() + return not not rows + + def i_am_locking(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?" + " and unique_name = ?", + (self.lock_file, self.unique_name)) + return not not cursor.fetchall() + + def break_lock(self): + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where lock_file = ?", + (self.lock_file,)) + self.connection.commit() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py new file mode 100755 index 0000000..23b41f5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import os +import time + +from . import (LockBase, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class SymlinkLockFile(LockBase): + """Lock access to a file using symlink(2).""" + + def __init__(self, path, threaded=True, timeout=None): + # super(SymlinkLockFile).__init(...) + LockBase.__init__(self, path, threaded, timeout) + # split it back! + self.unique_name = os.path.split(self.unique_name)[1] + + def acquire(self, timeout=None): + # Hopefully unnecessary for symlink. + # try: + # open(self.unique_name, "wb").close() + # except IOError: + # raise LockFailed("failed to create %s" % self.unique_name) + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a symbolic link to it. + try: + os.symlink(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + if self.i_am_locking(): + # Linked to out unique name. Proceed. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout / 10 if timeout is not None else 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.islink(self.lock_file) + + def i_am_locking(self): + return (os.path.islink(self.lock_file) + and os.readlink(self.lock_file) == self.unique_name) + + def break_lock(self): + if os.path.islink(self.lock_file): # exists && link + os.unlink(self.lock_file) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/__init__.py new file mode 100755 index 0000000..2afca5a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/__init__.py @@ -0,0 +1,66 @@ +# coding: utf-8 +from pip._vendor.msgpack._version import version +from pip._vendor.msgpack.exceptions import * + +from collections import namedtuple + + +class ExtType(namedtuple('ExtType', 'code data')): + """ExtType represents ext type in msgpack.""" + def __new__(cls, code, data): + if not isinstance(code, int): + raise TypeError("code must be int") + if not isinstance(data, bytes): + raise TypeError("data must be bytes") + if not 0 <= code <= 127: + raise ValueError("code must be 0~127") + return super(ExtType, cls).__new__(cls, code, data) + + +import os +if os.environ.get('MSGPACK_PUREPYTHON'): + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +else: + try: + from pip._vendor.msgpack._packer import Packer + from pip._vendor.msgpack._unpacker import unpackb, Unpacker + except ImportError: + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + + +def unpack(stream, **kwargs): + """ + Unpack an object from `stream`. + + Raises `ExtraData` when `stream` contains extra bytes. + See :class:`Unpacker` for options. + """ + data = stream.read() + return unpackb(data, **kwargs) + + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/_version.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/_version.py new file mode 100755 index 0000000..d28f0de --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 5, 6) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/exceptions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/exceptions.py new file mode 100755 index 0000000..9766881 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/exceptions.py @@ -0,0 +1,41 @@ +class UnpackException(Exception): + """Deprecated. Use Exception instead to catch all exception during unpacking.""" + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + """Deprecated. Use ValueError instead.""" + + +class ExtraData(UnpackValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + + +class PackException(Exception): + """Deprecated. Use Exception instead to catch all exception during packing.""" + + +class PackValueError(PackException, ValueError): + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/fallback.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/fallback.py new file mode 100755 index 0000000..9418421 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/msgpack/fallback.py @@ -0,0 +1,977 @@ +"""Fallback pure Python implementation of msgpack""" + +import sys +import struct +import warnings + +if sys.version_info[0] == 3: + PY3 = True + int_types = int + Unicode = str + xrange = range + def dict_iteritems(d): + return d.items() +else: + PY3 = False + int_types = (int, long) + Unicode = unicode + def dict_iteritems(d): + return d.iteritems() + + +if hasattr(sys, 'pypy_version_info'): + # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own + # StringBuilder is fastest. + from __pypy__ import newlist_hint + try: + from __pypy__.builders import BytesBuilder as StringBuilder + except ImportError: + from __pypy__.builders import StringBuilder + USING_STRINGBUILDER = True + class StringIO(object): + def __init__(self, s=b''): + if s: + self.builder = StringBuilder(len(s)) + self.builder.append(s) + else: + self.builder = StringBuilder() + def write(self, s): + if isinstance(s, memoryview): + s = s.tobytes() + elif isinstance(s, bytearray): + s = bytes(s) + self.builder.append(s) + def getvalue(self): + return self.builder.build() +else: + USING_STRINGBUILDER = False + from io import BytesIO as StringIO + newlist_hint = lambda size: [] + + +from pip._vendor.msgpack.exceptions import ( + BufferFull, + OutOfData, + UnpackValueError, + PackValueError, + PackOverflowError, + ExtraData) + +from pip._vendor.msgpack import ExtType + + +EX_SKIP = 0 +EX_CONSTRUCT = 1 +EX_READ_ARRAY_HEADER = 2 +EX_READ_MAP_HEADER = 3 + +TYPE_IMMEDIATE = 0 +TYPE_ARRAY = 1 +TYPE_MAP = 2 +TYPE_RAW = 3 +TYPE_BIN = 4 +TYPE_EXT = 5 + +DEFAULT_RECURSE_LIMIT = 511 + + +def _check_type_strict(obj, t, type=type, tuple=tuple): + if type(t) is tuple: + return type(obj) in t + else: + return type(obj) is t + + +def _get_data_from_buffer(obj): + try: + view = memoryview(obj) + except TypeError: + # try to use legacy buffer protocol if 2.7, otherwise re-raise + if not PY3: + view = memoryview(buffer(obj)) + warnings.warn("using old buffer interface to unpack %s; " + "this leads to unpacking errors if slicing is used and " + "will be removed in a future version" % type(obj), + RuntimeWarning) + else: + raise + if view.itemsize != 1: + raise ValueError("cannot unpack from multi-byte object") + return view + + +def unpack(stream, **kwargs): + warnings.warn( + "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", + PendingDeprecationWarning) + data = stream.read() + return unpackb(data, **kwargs) + + +def unpackb(packed, **kwargs): + """ + Unpack an object from `packed`. + + Raises `ExtraData` when `packed` contains extra bytes. + See :class:`Unpacker` for options. + """ + unpacker = Unpacker(None, **kwargs) + unpacker.feed(packed) + try: + ret = unpacker._unpack() + except OutOfData: + raise UnpackValueError("Data is not enough.") + if unpacker._got_extradata(): + raise ExtraData(ret, unpacker._get_extradata()) + return ret + + +class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + Otherwise, unpack to Python tuple. (default: True) + + :param bool raw: + If true, unpack msgpack raw to Python bytes (default). + Otherwise, unpack to Python str (or unicode on Python 2) by decoding + with UTF-8 encoding (recommended). + Currently, the default is true, but it will be changed to false in + near future. So you must specify it explicitly for keeping backward + compatibility. + + *encoding* option which is deprecated overrides this option. + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + Unpacker calls it with a list of key-value pairs after unpacking msgpack map. + (See also simplejson) + + :param str encoding: + Encoding used for decoding msgpack raw. + If it is None (default), msgpack raw is deserialized to Python bytes. + + :param str unicode_errors: + (deprecated) Used for decoding msgpack raw with *encoding*. + (default: `'strict'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You should set this parameter when unpacking data from untrusted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like, raw=False) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker(raw=False) + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + + def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, + object_hook=None, object_pairs_hook=None, list_hook=None, + encoding=None, unicode_errors=None, max_buffer_size=0, + ext_hook=ExtType, + max_str_len=2147483647, # 2**32-1 + max_bin_len=2147483647, + max_array_len=2147483647, + max_map_len=2147483647, + max_ext_len=2147483647): + + if encoding is not None: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + if file_like is None: + self._feeding = True + else: + if not callable(file_like.read): + raise TypeError("`file_like.read` must be callable") + self.file_like = file_like + self._feeding = False + + #: array of bytes fed. + self._buffer = bytearray() + # Some very old pythons don't support `struct.unpack_from()` with a + # `bytearray`. So we wrap it in a `buffer()` there. + if sys.version_info < (2, 7, 6): + self._buffer_view = buffer(self._buffer) + else: + self._buffer_view = self._buffer + #: Which position we currently reads + self._buff_i = 0 + + # When Unpacker is used as an iterable, between the calls to next(), + # the buffer is not "consumed" completely, for efficiency sake. + # Instead, it is done sloppily. To make sure we raise BufferFull at + # the correct moments, we have to keep track of how sloppy we were. + # Furthermore, when the buffer is incomplete (that is: in the case + # we raise an OutOfData) we need to rollback the buffer to the correct + # state, which _buf_checkpoint records. + self._buf_checkpoint = 0 + + self._max_buffer_size = max_buffer_size or 2**31-1 + if read_size > self._max_buffer_size: + raise ValueError("read_size must be smaller than max_buffer_size") + self._read_size = read_size or min(self._max_buffer_size, 16*1024) + self._raw = bool(raw) + self._encoding = encoding + self._unicode_errors = unicode_errors + self._use_list = use_list + self._list_hook = list_hook + self._object_hook = object_hook + self._object_pairs_hook = object_pairs_hook + self._ext_hook = ext_hook + self._max_str_len = max_str_len + self._max_bin_len = max_bin_len + self._max_array_len = max_array_len + self._max_map_len = max_map_len + self._max_ext_len = max_ext_len + self._stream_offset = 0 + + if list_hook is not None and not callable(list_hook): + raise TypeError('`list_hook` is not callable') + if object_hook is not None and not callable(object_hook): + raise TypeError('`object_hook` is not callable') + if object_pairs_hook is not None and not callable(object_pairs_hook): + raise TypeError('`object_pairs_hook` is not callable') + if object_hook is not None and object_pairs_hook is not None: + raise TypeError("object_pairs_hook and object_hook are mutually " + "exclusive") + if not callable(ext_hook): + raise TypeError("`ext_hook` is not callable") + + def feed(self, next_bytes): + assert self._feeding + view = _get_data_from_buffer(next_bytes) + if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): + raise BufferFull + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + self._buffer += view + + def _consume(self): + """ Gets rid of the used parts of the buffer. """ + self._stream_offset += self._buff_i - self._buf_checkpoint + self._buf_checkpoint = self._buff_i + + def _got_extradata(self): + return self._buff_i < len(self._buffer) + + def _get_extradata(self): + return self._buffer[self._buff_i:] + + def read_bytes(self, n): + return self._read(n) + + def _read(self, n): + # (int) -> bytearray + self._reserve(n) + i = self._buff_i + self._buff_i = i+n + return self._buffer[i:i+n] + + def _reserve(self, n): + remain_bytes = len(self._buffer) - self._buff_i - n + + # Fast path: buffer has n bytes already + if remain_bytes >= 0: + return + + if self._feeding: + self._buff_i = self._buf_checkpoint + raise OutOfData + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + # Read from file + remain_bytes = -remain_bytes + while remain_bytes > 0: + to_read_bytes = max(self._read_size, remain_bytes) + read_data = self.file_like.read(to_read_bytes) + if not read_data: + break + assert isinstance(read_data, bytes) + self._buffer += read_data + remain_bytes -= len(read_data) + + if len(self._buffer) < n + self._buff_i: + self._buff_i = 0 # rollback + raise OutOfData + + def _read_header(self, execute=EX_CONSTRUCT): + typ = TYPE_IMMEDIATE + n = 0 + obj = None + self._reserve(1) + b = self._buffer[self._buff_i] + self._buff_i += 1 + if b & 0b10000000 == 0: + obj = b + elif b & 0b11100000 == 0b11100000: + obj = -1 - (b ^ 0xff) + elif b & 0b11100000 == 0b10100000: + n = b & 0b00011111 + typ = TYPE_RAW + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b & 0b11110000 == 0b10010000: + n = b & 0b00001111 + typ = TYPE_ARRAY + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b & 0b11110000 == 0b10000000: + n = b & 0b00001111 + typ = TYPE_MAP + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + elif b == 0xc0: + obj = None + elif b == 0xc2: + obj = False + elif b == 0xc3: + obj = True + elif b == 0xc4: + typ = TYPE_BIN + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc5: + typ = TYPE_BIN + self._reserve(2) + n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc6: + typ = TYPE_BIN + self._reserve(4) + n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc7: # ext 8 + typ = TYPE_EXT + self._reserve(2) + L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) + self._buff_i += 2 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc8: # ext 16 + typ = TYPE_EXT + self._reserve(3) + L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) + self._buff_i += 3 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc9: # ext 32 + typ = TYPE_EXT + self._reserve(5) + L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) + self._buff_i += 5 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xca: + self._reserve(4) + obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcb: + self._reserve(8) + obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xcc: + self._reserve(1) + obj = self._buffer[self._buff_i] + self._buff_i += 1 + elif b == 0xcd: + self._reserve(2) + obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xce: + self._reserve(4) + obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcf: + self._reserve(8) + obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd0: + self._reserve(1) + obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] + self._buff_i += 1 + elif b == 0xd1: + self._reserve(2) + obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xd2: + self._reserve(4) + obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xd3: + self._reserve(8) + obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd4: # fixext 1 + typ = TYPE_EXT + if self._max_ext_len < 1: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + self._reserve(2) + n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) + self._buff_i += 2 + elif b == 0xd5: # fixext 2 + typ = TYPE_EXT + if self._max_ext_len < 2: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + self._reserve(3) + n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) + self._buff_i += 3 + elif b == 0xd6: # fixext 4 + typ = TYPE_EXT + if self._max_ext_len < 4: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + self._reserve(5) + n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) + self._buff_i += 5 + elif b == 0xd7: # fixext 8 + typ = TYPE_EXT + if self._max_ext_len < 8: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + self._reserve(9) + n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) + self._buff_i += 9 + elif b == 0xd8: # fixext 16 + typ = TYPE_EXT + if self._max_ext_len < 16: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + self._reserve(17) + n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) + self._buff_i += 17 + elif b == 0xd9: + typ = TYPE_RAW + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xda: + typ = TYPE_RAW + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdb: + typ = TYPE_RAW + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdc: + typ = TYPE_ARRAY + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xdd: + typ = TYPE_ARRAY + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xde: + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + elif b == 0xdf: + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + else: + raise UnpackValueError("Unknown header: 0x%x" % b) + return typ, n, obj + + def _unpack(self, execute=EX_CONSTRUCT): + typ, n, obj = self._read_header(execute) + + if execute == EX_READ_ARRAY_HEADER: + if typ != TYPE_ARRAY: + raise UnpackValueError("Expected array") + return n + if execute == EX_READ_MAP_HEADER: + if typ != TYPE_MAP: + raise UnpackValueError("Expected map") + return n + # TODO should we eliminate the recursion? + if typ == TYPE_ARRAY: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call `list_hook` + self._unpack(EX_SKIP) + return + ret = newlist_hint(n) + for i in xrange(n): + ret.append(self._unpack(EX_CONSTRUCT)) + if self._list_hook is not None: + ret = self._list_hook(ret) + # TODO is the interaction between `list_hook` and `use_list` ok? + return ret if self._use_list else tuple(ret) + if typ == TYPE_MAP: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call hooks + self._unpack(EX_SKIP) + self._unpack(EX_SKIP) + return + if self._object_pairs_hook is not None: + ret = self._object_pairs_hook( + (self._unpack(EX_CONSTRUCT), + self._unpack(EX_CONSTRUCT)) + for _ in xrange(n)) + else: + ret = {} + for _ in xrange(n): + key = self._unpack(EX_CONSTRUCT) + ret[key] = self._unpack(EX_CONSTRUCT) + if self._object_hook is not None: + ret = self._object_hook(ret) + return ret + if execute == EX_SKIP: + return + if typ == TYPE_RAW: + if self._encoding is not None: + obj = obj.decode(self._encoding, self._unicode_errors) + elif self._raw: + obj = bytes(obj) + else: + obj = obj.decode('utf_8') + return obj + if typ == TYPE_EXT: + return self._ext_hook(n, bytes(obj)) + if typ == TYPE_BIN: + return bytes(obj) + assert typ == TYPE_IMMEDIATE + return obj + + def __iter__(self): + return self + + def __next__(self): + try: + ret = self._unpack(EX_CONSTRUCT) + self._consume() + return ret + except OutOfData: + self._consume() + raise StopIteration + + next = __next__ + + def skip(self, write_bytes=None): + self._unpack(EX_SKIP) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + + def unpack(self, write_bytes=None): + ret = self._unpack(EX_CONSTRUCT) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_array_header(self, write_bytes=None): + ret = self._unpack(EX_READ_ARRAY_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_map_header(self, write_bytes=None): + ret = self._unpack(EX_READ_MAP_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def tell(self): + return self._stream_offset + + +class Packer(object): + """ + MessagePack Packer + + usage: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + + :param bool use_single_float: + Use single precision float type for float. (default: False) + + :param bool autoreset: + Reset buffer after each pack and return its content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enables str8 type for unicode. + + :param bool strict_types: + If set to true, types will be checked to be exact. Derived classes + from serializeable types will not be serialized and will be + treated as unsupported type and forwarded to default. + Additionally tuples will not be serialized as lists. + This is useful when trying to implement accurate serialization + for python types. + + :param str encoding: + (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') + + :param str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + """ + def __init__(self, default=None, encoding=None, unicode_errors=None, + use_single_float=False, autoreset=True, use_bin_type=False, + strict_types=False): + if encoding is None: + encoding = 'utf_8' + else: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + self._strict_types = strict_types + self._use_float = use_single_float + self._autoreset = autoreset + self._use_bin_type = use_bin_type + self._encoding = encoding + self._unicode_errors = unicode_errors + self._buffer = StringIO() + if default is not None: + if not callable(default): + raise TypeError("default must be callable") + self._default = default + + def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, + check=isinstance, check_type_strict=_check_type_strict): + default_used = False + if self._strict_types: + check = check_type_strict + list_types = list + else: + list_types = (list, tuple) + while True: + if nest_limit < 0: + raise PackValueError("recursion limit exceeded") + if obj is None: + return self._buffer.write(b"\xc0") + if check(obj, bool): + if obj: + return self._buffer.write(b"\xc3") + return self._buffer.write(b"\xc2") + if check(obj, int_types): + if 0 <= obj < 0x80: + return self._buffer.write(struct.pack("B", obj)) + if -0x20 <= obj < 0: + return self._buffer.write(struct.pack("b", obj)) + if 0x80 <= obj <= 0xff: + return self._buffer.write(struct.pack("BB", 0xcc, obj)) + if -0x80 <= obj < 0: + return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) + if 0xff < obj <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xcd, obj)) + if -0x8000 <= obj < -0x80: + return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) + if 0xffff < obj <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xce, obj)) + if -0x80000000 <= obj < -0x8000: + return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) + if 0xffffffff < obj <= 0xffffffffffffffff: + return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) + if -0x8000000000000000 <= obj < -0x80000000: + return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = True + continue + raise PackOverflowError("Integer value out of range") + if check(obj, (bytes, bytearray)): + n = len(obj) + if n >= 2**32: + raise PackValueError("%s is too large" % type(obj).__name__) + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, Unicode): + if self._encoding is None: + raise TypeError( + "Can't encode unicode string: " + "no encoding is specified") + obj = obj.encode(self._encoding, self._unicode_errors) + n = len(obj) + if n >= 2**32: + raise PackValueError("String is too large") + self._pack_raw_header(n) + return self._buffer.write(obj) + if check(obj, memoryview): + n = len(obj) * obj.itemsize + if n >= 2**32: + raise PackValueError("Memoryview is too large") + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, float): + if self._use_float: + return self._buffer.write(struct.pack(">Bf", 0xca, obj)) + return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) + if check(obj, ExtType): + code = obj.code + data = obj.data + assert isinstance(code, int) + assert isinstance(data, bytes) + L = len(data) + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(struct.pack(">BB", 0xc7, L)) + elif L <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xc8, L)) + else: + self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack("b", code)) + self._buffer.write(data) + return + if check(obj, list_types): + n = len(obj) + self._pack_array_header(n) + for i in xrange(n): + self._pack(obj[i], nest_limit - 1) + return + if check(obj, dict): + return self._pack_map_pairs(len(obj), dict_iteritems(obj), + nest_limit - 1) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = 1 + continue + raise TypeError("Cannot serialize %r" % (obj, )) + + def pack(self, obj): + try: + self._pack(obj) + except: + self._buffer = StringIO() # force reset + raise + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_pairs(self, pairs): + self._pack_map_pairs(len(pairs), pairs) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_array_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_array_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_map_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise PackValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(b'\xc7' + struct.pack('B', L)) + elif L <= 0xffff: + self._buffer.write(b'\xc8' + struct.pack('>H', L)) + else: + self._buffer.write(b'\xc9' + struct.pack('>I', L)) + self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(data) + + def _pack_array_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x90 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xdc, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdd, n)) + raise PackValueError("Array is too large") + + def _pack_map_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x80 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xde, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdf, n)) + raise PackValueError("Dict is too large") + + def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): + self._pack_map_header(n) + for (k, v) in pairs: + self._pack(k, nest_limit - 1) + self._pack(v, nest_limit - 1) + + def _pack_raw_header(self, n): + if n <= 0x1f: + self._buffer.write(struct.pack('B', 0xa0 + n)) + elif self._use_bin_type and n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xd9, n)) + elif n <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xda, n)) + elif n <= 0xffffffff: + self._buffer.write(struct.pack(">BI", 0xdb, n)) + else: + raise PackValueError('Raw is too large') + + def _pack_bin_header(self, n): + if not self._use_bin_type: + return self._pack_raw_header(n) + elif n <= 0xff: + return self._buffer.write(struct.pack('>BB', 0xc4, n)) + elif n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xc5, n)) + elif n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xc6, n)) + else: + raise PackValueError('Bin is too large') + + def bytes(self): + return self._buffer.getvalue() + + def reset(self): + self._buffer = StringIO() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__about__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__about__.py new file mode 100755 index 0000000..7481c9e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__about__.py @@ -0,0 +1,27 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "19.0" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2019 %s" % __author__ diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__init__.py new file mode 100755 index 0000000..a0cf67d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/__init__.py @@ -0,0 +1,26 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, + __copyright__, + __email__, + __license__, + __summary__, + __title__, + __uri__, + __version__, +) + +__all__ = [ + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", +] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_compat.py new file mode 100755 index 0000000..25da473 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_compat.py @@ -0,0 +1,31 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = (str,) +else: + string_types = (basestring,) + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + return type.__new__(metaclass, "temporary_class", (), {}) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_structures.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_structures.py new file mode 100755 index 0000000..68dcca6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/_structures.py @@ -0,0 +1,68 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + + +Infinity = Infinity() + + +class NegativeInfinity(object): + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + + +NegativeInfinity = NegativeInfinity() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/markers.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/markers.py new file mode 100755 index 0000000..5482476 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/markers.py @@ -0,0 +1,296 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pip._vendor.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", + "UndefinedComparison", + "UndefinedEnvironmentName", + "Marker", + "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + def serialize(self): + return str(self) + + +class Value(Node): + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") + | L("platform_python_implementation") + | L("implementation_name") + | L("python_full_version") + | L("platform_release") + | L("platform_version") + | L("platform_machine") + | L("platform_system") + | L("python_version") + | L("sys_platform") + | L("os_name") + | L("os.name") + | L("sys.platform") # PEP-345 + | L("platform.version") # PEP-345 + | L("platform.machine") # PEP-345 + | L("platform.python_implementation") # PEP-345 + | L("python_implementation") # PEP-345 + | L("extra") # undocumented setuptools legacy +) +ALIASES = { + "os.name": "os_name", + "sys.platform": "sys_platform", + "platform.version": "platform_version", + "platform.machine": "platform_machine", + "platform.python_implementation": "platform_python_implementation", + "python_implementation": "platform_python_implementation", +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if ( + isinstance(marker, list) + and len(marker) == 1 + and isinstance(marker[0], (list, tuple)) + ): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = "{0.major}.{0.minor}.{0.micro}".format(info) + kind = info.releaselevel + if kind != "final": + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, "implementation"): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = "0" + implementation_name = "" + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc : e.loc + 8] + ) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/requirements.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/requirements.py new file mode 100755 index 0000000..dbc5f11 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/requirements.py @@ -0,0 +1,138 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pip._vendor.pyparsing import Literal as L # noqa +from pip._vendor.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r"[^ ]+")("url") +URL = AT + URI + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine( + VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False +)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start : t._original_end]) +) +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + 'Parse error at "{0!r}": {1}'.format( + requirement_string[e.loc : e.loc + 8], e.msg + ) + ) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if parsed_url.scheme == "file": + if urlparse.urlunparse(parsed_url) != req.url: + raise InvalidRequirement("Invalid URL given") + elif not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc + ): + raise InvalidRequirement("Invalid URL: {0}".format(req.url)) + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + if self.marker: + parts.append(" ") + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/specifiers.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/specifiers.py new file mode 100755 index 0000000..743576a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/specifiers.py @@ -0,0 +1,749 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = (match.group("operator").strip(), match.group("version").strip()) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if parsed_version.is_prerelease and not ( + prereleases or self.prereleases + ): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return self._get_operator(">=")(prospective, spec) and self._get_operator("==")( + prospective, prefix + ) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[: len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is technically greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]) :]) + right_split.append(right[len(right_split[0]) :]) + + # Insert our padding + left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0]))) + right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0]))) + + return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split))) + + +class SpecifierSet(BaseSpecifier): + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all(s.contains(item, prereleases=prereleases) for s in self._specs) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/utils.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/utils.py new file mode 100755 index 0000000..8841878 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/utils.py @@ -0,0 +1,57 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + +from .version import InvalidVersion, Version + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release))) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/version.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/version.py new file mode 100755 index 0000000..95157a1 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/packaging/version.py @@ -0,0 +1,420 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] + + +_Version = collections.namedtuple( + "_Version", ["epoch", "release", "dev", "pre", "post", "local"] +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + @property + def is_devrelease(self): + return False + + +_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) + +_legacy_version_replacement_map = { + "pre": "c", + "preview": "c", + "-": "final-", + "rc": "c", + "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")), + post=_parse_letter_version( + match.group("post_l"), match.group("post_n1") or match.group("post_n2") + ), + dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(".post{0}".format(self.post)) + + # Development release + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) + + # Local version segment + if self.local is not None: + parts.append("+{0}".format(self.local)) + + return "".join(parts) + + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self): + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self): + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local) + + return epoch, release, pre, post, dev, local diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/__init__.py new file mode 100755 index 0000000..9c1a098 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/__init__.py @@ -0,0 +1,4 @@ +"""Wrappers to build Python packages using PEP 517 hooks +""" + +__version__ = '0.5.0' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/_in_process.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/_in_process.py new file mode 100755 index 0000000..d6524b6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/_in_process.py @@ -0,0 +1,207 @@ +"""This is invoked in a subprocess to call the build backend hooks. + +It expects: +- Command line args: hook_name, control_dir +- Environment variable: PEP517_BUILD_BACKEND=entry.point:spec +- control_dir/input.json: + - {"kwargs": {...}} + +Results: +- control_dir/output.json + - {"return_val": ...} +""" +from glob import glob +from importlib import import_module +import os +from os.path import join as pjoin +import re +import shutil +import sys + +# This is run as a script, not a module, so it can't do a relative import +import compat + + +class BackendUnavailable(Exception): + """Raised if we cannot import the backend""" + + +def _build_backend(): + """Find and load the build backend""" + ep = os.environ['PEP517_BUILD_BACKEND'] + mod_path, _, obj_path = ep.partition(':') + try: + obj = import_module(mod_path) + except ImportError: + raise BackendUnavailable + if obj_path: + for path_part in obj_path.split('.'): + obj = getattr(obj, path_part) + return obj + + +def get_requires_for_build_wheel(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_wheel + except AttributeError: + return [] + else: + return hook(config_settings) + + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings): + """Invoke optional prepare_metadata_for_build_wheel + + Implements a fallback by building a wheel if the hook isn't defined. + """ + backend = _build_backend() + try: + hook = backend.prepare_metadata_for_build_wheel + except AttributeError: + return _get_wheel_metadata_from_wheel(backend, metadata_directory, + config_settings) + else: + return hook(metadata_directory, config_settings) + + +WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL' + + +def _dist_info_files(whl_zip): + """Identify the .dist-info folder inside a wheel ZipFile.""" + res = [] + for path in whl_zip.namelist(): + m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path) + if m: + res.append(path) + if res: + return res + raise Exception("No .dist-info folder found in wheel") + + +def _get_wheel_metadata_from_wheel( + backend, metadata_directory, config_settings): + """Build a wheel and extract the metadata from it. + + Fallback for when the build backend does not + define the 'get_wheel_metadata' hook. + """ + from zipfile import ZipFile + whl_basename = backend.build_wheel(metadata_directory, config_settings) + with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'): + pass # Touch marker file + + whl_file = os.path.join(metadata_directory, whl_basename) + with ZipFile(whl_file) as zipf: + dist_info = _dist_info_files(zipf) + zipf.extractall(path=metadata_directory, members=dist_info) + return dist_info[0].split('/')[0] + + +def _find_already_built_wheel(metadata_directory): + """Check for a wheel already built during the get_wheel_metadata hook. + """ + if not metadata_directory: + return None + metadata_parent = os.path.dirname(metadata_directory) + if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)): + return None + + whl_files = glob(os.path.join(metadata_parent, '*.whl')) + if not whl_files: + print('Found wheel built marker, but no .whl files') + return None + if len(whl_files) > 1: + print('Found multiple .whl files; unspecified behaviour. ' + 'Will call build_wheel.') + return None + + # Exactly one .whl file + return whl_files[0] + + +def build_wheel(wheel_directory, config_settings, metadata_directory=None): + """Invoke the mandatory build_wheel hook. + + If a wheel was already built in the + prepare_metadata_for_build_wheel fallback, this + will copy it rather than rebuilding the wheel. + """ + prebuilt_whl = _find_already_built_wheel(metadata_directory) + if prebuilt_whl: + shutil.copy2(prebuilt_whl, wheel_directory) + return os.path.basename(prebuilt_whl) + + return _build_backend().build_wheel(wheel_directory, config_settings, + metadata_directory) + + +def get_requires_for_build_sdist(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_sdist + except AttributeError: + return [] + else: + return hook(config_settings) + + +class _DummyException(Exception): + """Nothing should ever raise this exception""" + + +class GotUnsupportedOperation(Exception): + """For internal use when backend raises UnsupportedOperation""" + + +def build_sdist(sdist_directory, config_settings): + """Invoke the mandatory build_sdist hook.""" + backend = _build_backend() + try: + return backend.build_sdist(sdist_directory, config_settings) + except getattr(backend, 'UnsupportedOperation', _DummyException): + raise GotUnsupportedOperation + + +HOOK_NAMES = { + 'get_requires_for_build_wheel', + 'prepare_metadata_for_build_wheel', + 'build_wheel', + 'get_requires_for_build_sdist', + 'build_sdist', +} + + +def main(): + if len(sys.argv) < 3: + sys.exit("Needs args: hook_name, control_dir") + hook_name = sys.argv[1] + control_dir = sys.argv[2] + if hook_name not in HOOK_NAMES: + sys.exit("Unknown hook: %s" % hook_name) + hook = globals()[hook_name] + + hook_input = compat.read_json(pjoin(control_dir, 'input.json')) + + json_out = {'unsupported': False, 'return_val': None} + try: + json_out['return_val'] = hook(**hook_input['kwargs']) + except BackendUnavailable: + json_out['no_backend'] = True + except GotUnsupportedOperation: + json_out['unsupported'] = True + + compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) + + +if __name__ == '__main__': + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/build.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/build.py new file mode 100755 index 0000000..ac6c949 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/build.py @@ -0,0 +1,108 @@ +"""Build a project using PEP 517 hooks. +""" +import argparse +import logging +import os +import contextlib +from pip._vendor import pytoml +import shutil +import errno +import tempfile + +from .envbuild import BuildEnvironment +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + + +def _do_build(hooks, env, dist, dest): + get_requires_name = 'get_requires_for_build_{dist}'.format(**locals()) + get_requires = getattr(hooks, get_requires_name) + reqs = get_requires({}) + log.info('Got build requires: %s', reqs) + + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + + with tempdir() as td: + log.info('Trying to build %s in %s', dist, td) + build_name = 'build_{dist}'.format(**locals()) + build = getattr(hooks, build_name) + filename = build(td, {}) + source = os.path.join(td, filename) + shutil.move(source, os.path.join(dest, os.path.basename(filename))) + + +def mkdir_p(*args, **kwargs): + """Like `mkdir`, but does not raise an exception if the + directory already exists. + """ + try: + return os.mkdir(*args, **kwargs) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise + + +def build(source_dir, dist, dest=None): + pyproject = os.path.join(source_dir, 'pyproject.toml') + dest = os.path.join(source_dir, dest or 'dist') + mkdir_p(dest) + + with open(pyproject) as f: + pyproject_data = pytoml.load(f) + # Ensure the mandatory data can be loaded + buildsys = pyproject_data['build-system'] + requires = buildsys['requires'] + backend = buildsys['build-backend'] + + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + _do_build(hooks, env, dist, dest) + + +parser = argparse.ArgumentParser() +parser.add_argument( + 'source_dir', + help="A directory containing pyproject.toml", +) +parser.add_argument( + '--binary', '-b', + action='store_true', + default=False, +) +parser.add_argument( + '--source', '-s', + action='store_true', + default=False, +) +parser.add_argument( + '--out-dir', '-o', + help="Destination in which to save the builds relative to source dir", +) + + +def main(args): + # determine which dists to build + dists = list(filter(None, ( + 'sdist' if args.source or not args.binary else None, + 'wheel' if args.binary or not args.source else None, + ))) + + for dist in dists: + build(args.source_dir, dist, args.out_dir) + + +if __name__ == '__main__': + main(parser.parse_args()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/check.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/check.py new file mode 100755 index 0000000..f4cdc6b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/check.py @@ -0,0 +1,202 @@ +"""Check a project and backend by attempting to build using PEP 517 hooks. +""" +import argparse +import logging +import os +from os.path import isfile, join as pjoin +from pip._vendor.pytoml import TomlError, load as toml_load +import shutil +from subprocess import CalledProcessError +import sys +import tarfile +from tempfile import mkdtemp +import zipfile + +from .colorlog import enable_colourful_output +from .envbuild import BuildEnvironment +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + + +def check_build_sdist(hooks, build_sys_requires): + with BuildEnvironment() as env: + try: + env.pip_install(build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_sdist({}) + log.info('Got build requires: %s', reqs) + except Exception: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build sdist in %s', td) + try: + try: + filename = hooks.build_sdist(td, {}) + log.info('build_sdist returned %r', filename) + except Exception: + log.info('Failure in build_sdist', exc_info=True) + return False + + if not filename.endswith('.tar.gz'): + log.error( + "Filename %s doesn't have .tar.gz extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if tarfile.is_tarfile(path): + log.info("Output file is a tar file") + else: + log.error("Output file is not a tar file") + return False + + finally: + shutil.rmtree(td) + + return True + + +def check_build_wheel(hooks, build_sys_requires): + with BuildEnvironment() as env: + try: + env.pip_install(build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_wheel({}) + log.info('Got build requires: %s', reqs) + except Exception: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build wheel in %s', td) + try: + try: + filename = hooks.build_wheel(td, {}) + log.info('build_wheel returned %r', filename) + except Exception: + log.info('Failure in build_wheel', exc_info=True) + return False + + if not filename.endswith('.whl'): + log.error("Filename %s doesn't have .whl extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if zipfile.is_zipfile(path): + log.info("Output file is a zip file") + else: + log.error("Output file is not a zip file") + return False + + finally: + shutil.rmtree(td) + + return True + + +def check(source_dir): + pyproject = pjoin(source_dir, 'pyproject.toml') + if isfile(pyproject): + log.info('Found pyproject.toml') + else: + log.error('Missing pyproject.toml') + return False + + try: + with open(pyproject) as f: + pyproject_data = toml_load(f) + # Ensure the mandatory data can be loaded + buildsys = pyproject_data['build-system'] + requires = buildsys['requires'] + backend = buildsys['build-backend'] + log.info('Loaded pyproject.toml') + except (TomlError, KeyError): + log.error("Invalid pyproject.toml", exc_info=True) + return False + + hooks = Pep517HookCaller(source_dir, backend) + + sdist_ok = check_build_sdist(hooks, requires) + wheel_ok = check_build_wheel(hooks, requires) + + if not sdist_ok: + log.warning('Sdist checks failed; scroll up to see') + if not wheel_ok: + log.warning('Wheel checks failed') + + return sdist_ok + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument( + 'source_dir', + help="A directory containing pyproject.toml") + args = ap.parse_args(argv) + + enable_colourful_output() + + ok = check(args.source_dir) + + if ok: + print(ansi('Checks passed', 'green')) + else: + print(ansi('Checks failed', 'red')) + sys.exit(1) + + +ansi_codes = { + 'reset': '\x1b[0m', + 'bold': '\x1b[1m', + 'red': '\x1b[31m', + 'green': '\x1b[32m', +} + + +def ansi(s, attr): + if os.name != 'nt' and sys.stdout.isatty(): + return ansi_codes[attr] + str(s) + ansi_codes['reset'] + else: + return str(s) + + +if __name__ == '__main__': + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/colorlog.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/colorlog.py new file mode 100755 index 0000000..69c8a59 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/colorlog.py @@ -0,0 +1,115 @@ +"""Nicer log formatting with colours. + +Code copied from Tornado, Apache licensed. +""" +# Copyright 2012 Facebook +# +# 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. + +import logging +import sys + +try: + import curses +except ImportError: + curses = None + + +def _stderr_supports_color(): + color = False + if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty(): + try: + curses.setupterm() + if curses.tigetnum("colors") > 0: + color = True + except Exception: + pass + return color + + +class LogFormatter(logging.Formatter): + """Log formatter with colour support + """ + DEFAULT_COLORS = { + logging.INFO: 2, # Green + logging.WARNING: 3, # Yellow + logging.ERROR: 1, # Red + logging.CRITICAL: 1, + } + + def __init__(self, color=True, datefmt=None): + r""" + :arg bool color: Enables color support. + :arg string fmt: Log message format. + It will be applied to the attributes dict of log records. The + text between ``%(color)s`` and ``%(end_color)s`` will be colored + depending on the level if color support is on. + :arg dict colors: color mappings from logging level to terminal color + code + :arg string datefmt: Datetime format. + Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. + .. versionchanged:: 3.2 + Added ``fmt`` and ``datefmt`` arguments. + """ + logging.Formatter.__init__(self, datefmt=datefmt) + self._colors = {} + if color and _stderr_supports_color(): + # The curses module has some str/bytes confusion in + # python3. Until version 3.2.3, most methods return + # bytes, but only accept strings. In addition, we want to + # output these strings with the logging module, which + # works with unicode strings. The explicit calls to + # unicode() below are harmless in python2 but will do the + # right conversion in python 3. + fg_color = (curses.tigetstr("setaf") or + curses.tigetstr("setf") or "") + if (3, 0) < sys.version_info < (3, 2, 3): + fg_color = str(fg_color, "ascii") + + for levelno, code in self.DEFAULT_COLORS.items(): + self._colors[levelno] = str( + curses.tparm(fg_color, code), "ascii") + self._normal = str(curses.tigetstr("sgr0"), "ascii") + + scr = curses.initscr() + self.termwidth = scr.getmaxyx()[1] + curses.endwin() + else: + self._normal = '' + # Default width is usually 80, but too wide is + # worse than too narrow + self.termwidth = 70 + + def formatMessage(self, record): + mlen = len(record.message) + right_text = '{initial}-{name}'.format(initial=record.levelname[0], + name=record.name) + if mlen + len(right_text) < self.termwidth: + space = ' ' * (self.termwidth - (mlen + len(right_text))) + else: + space = ' ' + + if record.levelno in self._colors: + start_color = self._colors[record.levelno] + end_color = self._normal + else: + start_color = end_color = '' + + return record.message + space + start_color + right_text + end_color + + +def enable_colourful_output(level=logging.INFO): + handler = logging.StreamHandler() + handler.setFormatter(LogFormatter()) + logging.root.addHandler(handler) + logging.root.setLevel(level) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/compat.py new file mode 100755 index 0000000..01c66fc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/compat.py @@ -0,0 +1,23 @@ +"""Handle reading and writing JSON in UTF-8, on Python 3 and 2.""" +import json +import sys + +if sys.version_info[0] >= 3: + # Python 3 + def write_json(obj, path, **kwargs): + with open(path, 'w', encoding='utf-8') as f: + json.dump(obj, f, **kwargs) + + def read_json(path): + with open(path, 'r', encoding='utf-8') as f: + return json.load(f) + +else: + # Python 2 + def write_json(obj, path, **kwargs): + with open(path, 'wb') as f: + json.dump(obj, f, encoding='utf-8', **kwargs) + + def read_json(path): + with open(path, 'rb') as f: + return json.load(f) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/envbuild.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/envbuild.py new file mode 100755 index 0000000..f7ac5f4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/envbuild.py @@ -0,0 +1,158 @@ +"""Build wheels/sdists by installing build deps to a temporary environment. +""" + +import os +import logging +from pip._vendor import pytoml +import shutil +from subprocess import check_call +import sys +from sysconfig import get_paths +from tempfile import mkdtemp + +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + + +def _load_pyproject(source_dir): + with open(os.path.join(source_dir, 'pyproject.toml')) as f: + pyproject_data = pytoml.load(f) + buildsys = pyproject_data['build-system'] + return buildsys['requires'], buildsys['build-backend'] + + +class BuildEnvironment(object): + """Context manager to install build deps in a simple temporary environment + + Based on code I wrote for pip, which is MIT licensed. + """ + # Copyright (c) 2008-2016 The pip developers (see AUTHORS.txt file) + # + # 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. + + path = None + + def __init__(self, cleanup=True): + self._cleanup = cleanup + + def __enter__(self): + self.path = mkdtemp(prefix='pep517-build-env-') + log.info('Temporary build environment: %s', self.path) + + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + if install_dirs['purelib'] == install_dirs['platlib']: + lib_dirs = install_dirs['purelib'] + else: + lib_dirs = install_dirs['purelib'] + os.pathsep + \ + install_dirs['platlib'] + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + return self + + def pip_install(self, reqs): + """Install dependencies into this env by calling pip in a subprocess""" + if not reqs: + return + log.info('Calling pip to install %s', reqs) + check_call([ + sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--prefix', self.path] + list(reqs)) + + def __exit__(self, exc_type, exc_val, exc_tb): + needs_cleanup = ( + self._cleanup and + self.path is not None and + os.path.isdir(self.path) + ) + if needs_cleanup: + shutil.rmtree(self.path) + + if self.save_path is None: + os.environ.pop('PATH', None) + else: + os.environ['PATH'] = self.save_path + + if self.save_pythonpath is None: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = self.save_pythonpath + + +def build_wheel(source_dir, wheel_dir, config_settings=None): + """Build a wheel from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str wheel_dir: Target directory to create wheel in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_wheel(config_settings) + env.pip_install(reqs) + return hooks.build_wheel(wheel_dir, config_settings) + + +def build_sdist(source_dir, sdist_dir, config_settings=None): + """Build an sdist from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str sdist_dir: Target directory to place sdist in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_sdist(config_settings) + env.pip_install(reqs) + return hooks.build_sdist(sdist_dir, config_settings) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/wrappers.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/wrappers.py new file mode 100755 index 0000000..b14b899 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pep517/wrappers.py @@ -0,0 +1,163 @@ +from contextlib import contextmanager +import os +from os.path import dirname, abspath, join as pjoin +import shutil +from subprocess import check_call +import sys +from tempfile import mkdtemp + +from . import compat + +_in_proc_script = pjoin(dirname(abspath(__file__)), '_in_process.py') + + +@contextmanager +def tempdir(): + td = mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + + +class BackendUnavailable(Exception): + """Will be raised if the backend cannot be imported in the hook process.""" + + +class UnsupportedOperation(Exception): + """May be raised by build_sdist if the backend indicates that it can't.""" + + +def default_subprocess_runner(cmd, cwd=None, extra_environ=None): + """The default method of calling the wrapper subprocess.""" + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + + check_call(cmd, cwd=cwd, env=env) + + +class Pep517HookCaller(object): + """A wrapper around a source directory to be built with a PEP 517 backend. + + source_dir : The path to the source directory, containing pyproject.toml. + backend : The build backend spec, as per PEP 517, from pyproject.toml. + """ + def __init__(self, source_dir, build_backend): + self.source_dir = abspath(source_dir) + self.build_backend = build_backend + self._subprocess_runner = default_subprocess_runner + + # TODO: Is this over-engineered? Maybe frontends only need to + # set this when creating the wrapper, not on every call. + @contextmanager + def subprocess_runner(self, runner): + prev = self._subprocess_runner + self._subprocess_runner = runner + yield + self._subprocess_runner = prev + + def get_requires_for_build_wheel(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["wheel >= 0.25", "setuptools"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_wheel', { + 'config_settings': config_settings + }) + + def prepare_metadata_for_build_wheel( + self, metadata_directory, config_settings=None): + """Prepare a *.dist-info folder with metadata for this project. + + Returns the name of the newly created folder. + + If the build backend defines a hook with this name, it will be called + in a subprocess. If not, the backend will be asked to build a wheel, + and the dist-info extracted from that. + """ + return self._call_hook('prepare_metadata_for_build_wheel', { + 'metadata_directory': abspath(metadata_directory), + 'config_settings': config_settings, + }) + + def build_wheel( + self, wheel_directory, config_settings=None, + metadata_directory=None): + """Build a wheel from this project. + + Returns the name of the newly created file. + + In general, this will call the 'build_wheel' hook in the backend. + However, if that was previously called by + 'prepare_metadata_for_build_wheel', and the same metadata_directory is + used, the previously built wheel will be copied to wheel_directory. + """ + if metadata_directory is not None: + metadata_directory = abspath(metadata_directory) + return self._call_hook('build_wheel', { + 'wheel_directory': abspath(wheel_directory), + 'config_settings': config_settings, + 'metadata_directory': metadata_directory, + }) + + def get_requires_for_build_sdist(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["setuptools >= 26"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_sdist', { + 'config_settings': config_settings + }) + + def build_sdist(self, sdist_directory, config_settings=None): + """Build an sdist from this project. + + Returns the name of the newly created file. + + This calls the 'build_sdist' backend hook in a subprocess. + """ + return self._call_hook('build_sdist', { + 'sdist_directory': abspath(sdist_directory), + 'config_settings': config_settings, + }) + + def _call_hook(self, hook_name, kwargs): + # On Python 2, pytoml returns Unicode values (which is correct) but the + # environment passed to check_call needs to contain string values. We + # convert here by encoding using ASCII (the backend can only contain + # letters, digits and _, . and : characters, and will be used as a + # Python identifier, so non-ASCII content is wrong on Python 2 in + # any case). + if sys.version_info[0] == 2: + build_backend = self.build_backend.encode('ASCII') + else: + build_backend = self.build_backend + + with tempdir() as td: + compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'), + indent=2) + + # Run the hook in a subprocess + self._subprocess_runner( + [sys.executable, _in_proc_script, hook_name, td], + cwd=self.source_dir, + extra_environ={'PEP517_BUILD_BACKEND': build_backend} + ) + + data = compat.read_json(pjoin(td, 'output.json')) + if data.get('unsupported'): + raise UnsupportedOperation + if data.get('no_backend'): + raise BackendUnavailable + return data['return_val'] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/__init__.py new file mode 100755 index 0000000..9c4fd8e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/__init__.py @@ -0,0 +1,3171 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +try: + FileExistsError +except NameError: + FileExistsError = OSError + +from pip._vendor import six +from pip._vendor.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pip._vendor import appdirs +from pip._vendor import packaging +__import__('pip._vendor.packaging.version') +__import__('pip._vendor.packaging.specifiers') +__import__('pip._vendor.packaging.requirements') +__import__('pip._vendor.packaging.markers') + + +__metaclass__ = type + + +if (3, 0) < sys.version_info < (3, 4): + raise RuntimeError("Python 3.4 or later is required") + +if six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +def get_supported_platform(): + """Return this platform's maximum compatible version. + + distutils.util.get_platform() normally reports the minimum version + of Mac OS X that would be required to *use* extensions produced by + distutils. But what we want when checking compatibility is to know the + version of Mac OS X that we are *running*. To allow usage of packages that + explicitly require a newer version of Mac OS X, we must also know the + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_platform() + m = macosVersionString.match(plat) + if m is not None and sys.platform == "darwin": + try: + plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Warnings + 'PkgResourcesDeprecationWarning', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +def get_build_platform(): + """Return this platform's string for platform-specific distributions + + XXX Currently this is the same as ``distutils.util.get_platform()``, but it + needs some hacks for Linux and Mac OS X. + """ + from sysconfig import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + if not provMac: + # this is backwards compatibility for packages built before + # setuptools 0.6. All packages built after this point will + # use the new macosx designation. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet: + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + return ( + entry + for dist in self + for entry in dist.get_entry_map(group).values() + if name is None or name == entry.name + ) + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment: + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.6'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + mode = os.stat(path).st_mode + if mode & stat.S_IWOTH or mode & stat.S_IWGRP: + msg = ( + "%s is writable by group/others and vulnerable to attack " + "when " + "used with get_resource_filename. Consider a more secure " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + def get_metadata(self, name): + if not self.egg_info: + return "" + value = self._get(self._fn(self.egg_info, name)) + return value.decode('utf-8') if six.PY3 else value + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + self._setup_prefix() + + def _setup_prefix(self): + # we assume here that our metadata may be nested inside a "basket" + # of multiple eggs; that's why we use module_path instead of .archive + path = self.module_path + old = None + while path != old: + if _is_egg_path(path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path + break + old = path + path, base = os.path.split(path) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + for name in loader_names: + loader_cls = getattr(importlib_machinery, name, type(None)) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(path_item) + if importer is None: + return None + + # capture warnings due to #1111 + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + loader = importer.find_module(packageName) + + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + new_path = sorted(orig_path, key=position_in_sys_path) + new_path = [_normalize_cached(p) for p in new_path] + + if isinstance(module.__path__, list): + module.__path__[:] = new_path + else: + module.__path__ = new_path + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path = sys.path + parent, _, _ = packageName.rpartition('.') + + if parent: + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent or None, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +register_namespace_handler(object, null_ns_handler) + + +def normalize_path(filename): + """Normalize a file/dir name for comparison purposes""" + return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) + + +def _cygwin_patch(filename): # pragma: nocover + """ + Contrary to POSIX 2008, on Cygwin, getcwd (3) contains + symlink components. Using + os.path.abspath() works around this limitation. A fix in os.getcwd() + would probably better, in Cygwin even more so, except + that this seems to be by design... + """ + return os.path.abspath(filename) if sys.platform == 'cygwin' else filename + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint: + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + PkgResourcesDeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + return maps + + +def _remove_md5_fragment(location): + if not location: + return '' + parsed = urllib.parse.urlparse(location) + if parsed[-1].startswith('md5='): + return urllib.parse.urlunparse(parsed[:-1] + ('',)) + return location + + +def _version_from_file(lines): + """ + Given an iterable of lines from a Metadata file, return + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution: + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + def __dir__(self): + return list( + set(super(Distribution, self).__dir__()) + | set( + attr for attr in self._provider.__dir__() + if not attr.startswith('_') + ) + ) + + if not hasattr(object, '__dir__'): + # python 2.7 not supported + del __dir__ + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + warnings.warn(stacklevel=level + 1, *args, **kw) + + +class RequirementParseError(ValueError): + def __str__(self): + return ' '.join(self.args) + + +def parse_requirements(strs): + """Yield ``Requirement`` objects for each specification in `strs` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +class Requirement(packaging.requirements.Requirement): + def __init__(self, requirement_string): + """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" + try: + super(Requirement, self).__init__(requirement_string) + except packaging.requirements.InvalidRequirement as e: + raise RequirementParseError(str(e)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + try: + mkdir(dirname, 0o755) + except FileExistsError: + pass + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) + +class PkgResourcesDeprecationWarning(Warning): + """ + Base class for warning about deprecations in ``pkg_resources`` + + This class is not derived from ``DeprecationWarning``, and as such is + visible by default. + """ diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py new file mode 100755 index 0000000..a2d3007 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +import os +import errno +import sys + +from pip._vendor import six + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + six.PY2 or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/__init__.py new file mode 100755 index 0000000..a41f65d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/__init__.py @@ -0,0 +1,127 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, 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. + +from __future__ import division + +from collections import deque +from datetime import timedelta +from math import ceil +from sys import stderr +from time import time + + +__version__ = '1.4' + + +class Infinite(object): + file = stderr + sma_window = 10 # Simple Moving Average window + + def __init__(self, *args, **kwargs): + self.index = 0 + self.start_ts = time() + self.avg = 0 + self._ts = self.start_ts + self._xput = deque(maxlen=self.sma_window) + for key, val in kwargs.items(): + setattr(self, key, val) + + def __getitem__(self, key): + if key.startswith('_'): + return None + return getattr(self, key, None) + + @property + def elapsed(self): + return int(time() - self.start_ts) + + @property + def elapsed_td(self): + return timedelta(seconds=self.elapsed) + + def update_avg(self, n, dt): + if n > 0: + self._xput.append(dt / n) + self.avg = sum(self._xput) / len(self._xput) + + def update(self): + pass + + def start(self): + pass + + def finish(self): + pass + + def next(self, n=1): + now = time() + dt = now - self._ts + self.update_avg(n, dt) + self._ts = now + self.index = self.index + n + self.update() + + def iter(self, it): + try: + for x in it: + yield x + self.next() + finally: + self.finish() + + +class Progress(Infinite): + def __init__(self, *args, **kwargs): + super(Progress, self).__init__(*args, **kwargs) + self.max = kwargs.get('max', 100) + + @property + def eta(self): + return int(ceil(self.avg * self.remaining)) + + @property + def eta_td(self): + return timedelta(seconds=self.eta) + + @property + def percent(self): + return self.progress * 100 + + @property + def progress(self): + return min(1, self.index / self.max) + + @property + def remaining(self): + return max(self.max - self.index, 0) + + def start(self): + self.update() + + def goto(self, index): + incr = index - self.index + self.next(incr) + + def iter(self, it): + try: + self.max = len(it) + except TypeError: + pass + + try: + for x in it: + yield x + self.next() + finally: + self.finish() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/bar.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/bar.py new file mode 100755 index 0000000..025e61c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/bar.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, 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. + +from __future__ import unicode_literals + +import sys + +from . import Progress +from .helpers import WritelnMixin + + +class Bar(WritelnMixin, Progress): + width = 32 + message = '' + suffix = '%(index)d/%(max)d' + bar_prefix = ' |' + bar_suffix = '| ' + empty_fill = ' ' + fill = '#' + hide_cursor = True + + def update(self): + filled_length = int(self.width * self.progress) + empty_length = self.width - filled_length + + message = self.message % self + bar = self.fill * filled_length + empty = self.empty_fill * empty_length + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, + suffix]) + self.writeln(line) + + +class ChargingBar(Bar): + suffix = '%(percent)d%%' + bar_prefix = ' ' + bar_suffix = ' ' + empty_fill = '∙' + fill = '█' + + +class FillingSquaresBar(ChargingBar): + empty_fill = '▢' + fill = '▣' + + +class FillingCirclesBar(ChargingBar): + empty_fill = '◯' + fill = '◉' + + +class IncrementalBar(Bar): + if sys.platform.startswith('win'): + phases = (u' ', u'▌', u'█') + else: + phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') + + def update(self): + nphases = len(self.phases) + filled_len = self.width * self.progress + nfull = int(filled_len) # Number of full chars + phase = int((filled_len - nfull) * nphases) # Phase of last char + nempty = self.width - nfull # Number of empty chars + + message = self.message % self + bar = self.phases[-1] * nfull + current = self.phases[phase] if phase > 0 else '' + empty = self.empty_fill * max(0, nempty - len(current)) + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, current, empty, + self.bar_suffix, suffix]) + self.writeln(line) + + +class PixelBar(IncrementalBar): + phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') + + +class ShadyBar(IncrementalBar): + phases = (' ', '░', '▒', '▓', '█') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/counter.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/counter.py new file mode 100755 index 0000000..6b45a1e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/counter.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, 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. + +from __future__ import unicode_literals +from . import Infinite, Progress +from .helpers import WriteMixin + + +class Counter(WriteMixin, Infinite): + message = '' + hide_cursor = True + + def update(self): + self.write(str(self.index)) + + +class Countdown(WriteMixin, Progress): + hide_cursor = True + + def update(self): + self.write(str(self.remaining)) + + +class Stack(WriteMixin, Progress): + phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') + hide_cursor = True + + def update(self): + nphases = len(self.phases) + i = min(nphases - 1, int(self.progress * nphases)) + self.write(self.phases[i]) + + +class Pie(Stack): + phases = ('○', '◔', '◑', '◕', '●') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/helpers.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/helpers.py new file mode 100755 index 0000000..0cde44e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/helpers.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, 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. + +from __future__ import print_function + + +HIDE_CURSOR = '\x1b[?25l' +SHOW_CURSOR = '\x1b[?25h' + + +class WriteMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WriteMixin, self).__init__(**kwargs) + self._width = 0 + if message: + self.message = message + + if self.file and self.file.isatty(): + if self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + print(self.message, end='', file=self.file) + self.file.flush() + + def write(self, s): + if self.file and self.file.isatty(): + b = '\b' * self._width + c = s.ljust(self._width) + print(b + c, end='', file=self.file) + self._width = max(self._width, len(s)) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty() and self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +class WritelnMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WritelnMixin, self).__init__(**kwargs) + if message: + self.message = message + + if self.file and self.file.isatty() and self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + + def clearln(self): + if self.file and self.file.isatty(): + print('\r\x1b[K', end='', file=self.file) + + def writeln(self, line): + if self.file and self.file.isatty(): + self.clearln() + print(line, end='', file=self.file) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty(): + print(file=self.file) + if self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +from signal import signal, SIGINT +from sys import exit + + +class SigIntMixin(object): + """Registers a signal handler that calls finish on SIGINT""" + + def __init__(self, *args, **kwargs): + super(SigIntMixin, self).__init__(*args, **kwargs) + signal(SIGINT, self._sigint_handler) + + def _sigint_handler(self, signum, frame): + self.finish() + exit(0) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/spinner.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/spinner.py new file mode 100755 index 0000000..464c7b2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/progress/spinner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, 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. + +from __future__ import unicode_literals +from . import Infinite +from .helpers import WriteMixin + + +class Spinner(WriteMixin, Infinite): + message = '' + phases = ('-', '\\', '|', '/') + hide_cursor = True + + def update(self): + i = self.index % len(self.phases) + self.write(self.phases[i]) + + +class PieSpinner(Spinner): + phases = ['◷', '◶', '◵', '◴'] + + +class MoonSpinner(Spinner): + phases = ['◑', '◒', '◐', '◓'] + + +class LineSpinner(Spinner): + phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] + +class PixelSpinner(Spinner): + phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pyparsing.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pyparsing.py new file mode 100755 index 0000000..bea4d9c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pyparsing.py @@ -0,0 +1,6452 @@ +#-*- coding: utf-8 -*- +# module pyparsing.py +# +# Copyright (c) 2003-2019 Paul T. McGuire +# +# 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. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and +executing simple grammars, vs. the traditional lex/yacc approach, or the +use of regular expressions. With pyparsing, you don't need to learn +a new syntax for defining grammars or matching expressions - the parsing +module provides a library of classes that you use to construct the +grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +``"<salutation>, <addressee>!"``), built up using :class:`Word`, +:class:`Literal`, and :class:`And` elements +(the :class:`'+'<ParserElement.__add__>` operators create :class:`And` expressions, +and the strings are auto-converted to :class:`Literal` expressions):: + + from pip._vendor.pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the +self-explanatory class names, and the use of '+', '|' and '^' operators. + +The :class:`ParseResults` object returned from +:class:`ParserElement.parseString` can be +accessed as a nested list, a dictionary, or an object with named +attributes. + +The pyparsing module handles some of the problems that are typically +vexing when writing text parsers: + + - extra or missing whitespace (the above program will also handle + "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes :class:`ParserElement` and :class:`ParseResults` to +see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + + - construct literal match expressions from :class:`Literal` and + :class:`CaselessLiteral` classes + - construct character word-group expressions using the :class:`Word` + class + - see how to create repetitive expressions using :class:`ZeroOrMore` + and :class:`OneOrMore` classes + - use :class:`'+'<And>`, :class:`'|'<MatchFirst>`, :class:`'^'<Or>`, + and :class:`'&'<Each>` operators to combine simple expressions into + more complex ones + - associate names with your parsed results using + :class:`ParserElement.setResultsName` + - find some helpful expression short-cuts like :class:`delimitedList` + and :class:`oneOf` + - find more useful common expressions in the :class:`pyparsing_common` + namespace class +""" + +__version__ = "2.3.1" +__versionTime__ = "09 Jan 2019 23:26 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + # Python 3 + from itertools import filterfalse +except ImportError: + from itertools import ifilterfalse as filterfalse + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +try: + from types import SimpleNamespace +except ImportError: + class SimpleNamespace: pass + + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'PrecededBy', 'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', 'Char', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', 'pyparsing_unicode', 'unicode_set', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + unicode = str + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode + friendly. It first tries str(obj). If that fails with + a UnicodeEncodeError, then it tries unicode(obj). It then + < returns the unicode object | encodes it with the default + encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + + Expected integer (at char 0), (line:1, col:1) + column: 1 + + """ + + @staticmethod + def explain(exc, depth=16): + """ + Method to take an exception and translate the Python internal traceback into a list + of the pyparsing expressions that caused the exception to be raised. + + Parameters: + + - exc - exception raised during parsing (need not be a ParseException, in support + of Python exceptions that might be raised in a parse action) + - depth (default=16) - number of levels back in the stack trace to list expression + and function names; if None, the full stack trace names will be listed; if 0, only + the failing input line, marker, and exception string will be shown + + Returns a multi-line string listing the ParserElements and/or function names in the + exception's stack trace. + + Note: the diagnostic output will include string representations of the expressions + that failed to parse. These representations will be more helpful if you use `setName` to + give identifiable names to your expressions. Otherwise they will use the default string + forms, which may be cryptic to read. + + explain() is only supported under Python 3. + """ + import inspect + + if depth is None: + depth = sys.getrecursionlimit() + ret = [] + if isinstance(exc, ParseBaseException): + ret.append(exc.line) + ret.append(' ' * (exc.col - 1) + '^') + ret.append("{0}: {1}".format(type(exc).__name__, exc)) + + if depth > 0: + callers = inspect.getinnerframes(exc.__traceback__, context=depth) + seen = set() + for i, ff in enumerate(callers[-depth:]): + frm = ff.frame + + f_self = frm.f_locals.get('self', None) + if isinstance(f_self, ParserElement): + if frm.f_code.co_name not in ('parseImpl', '_parseNoCache'): + continue + if f_self in seen: + continue + seen.add(f_self) + + self_type = type(f_self) + ret.append("{0}.{1} - {2}".format(self_type.__module__, + self_type.__name__, + f_self)) + elif f_self is not None: + self_type = type(f_self) + ret.append("{0}.{1}".format(self_type.__module__, + self_type.__name__)) + else: + code = frm.f_code + if code.co_name in ('wrapper', '<module>'): + continue + + ret.append("{0}".format(code.co_name)) + + depth -= 1 + if not depth: + break + + return '\n'.join(ret) + + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like :class:`ParseFatalException`, but thrown internally + when an :class:`ErrorStop<And._ErrorStop>` ('-' operator) indicates + that parsing is to stop immediately because an unbacktrackable + syntax error has been found. + """ + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by :class:`ParserElement.validate` if the + grammar could be improperly recursive + """ + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """Structured parse results, to provide multiple means of access to + the parsed data: + + - as a list (``len(results)``) + - by list index (``results[0], results[1]``, etc.) + - by attribute (``results.<resultsName>`` - see :class:`ParserElement.setResultsName`) + + Example:: + + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + + prints:: + + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(ParseResults(toklist.__toklist), 0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys.""" + + values = _itervalues + """Returns an iterator of all named result values.""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples.""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default= ``last``). + Supports both ``list`` and ``dict`` semantics for ``pop()``. If + passed no argument or an integer argument, it will use ``list`` + semantics and pop tokens from the list of parsed tokens. If passed + a non-integer argument (most likely a string), it will use ``dict`` + semantics and pop the corresponding value from any defined results + names. A second default return value argument is supported, just as in + ``dict.pop()``. + + Example:: + + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + + prints:: + + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given ``defaultValue`` or ``None`` if no + ``defaultValue`` is specified. + + Similar to ``dict.get()``. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to ``list.insert()``. + + Example:: + + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a :class:`ParseResults` object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = dict(self.__tokdict.items()) + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + + prints:: + + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of + a :class:`ParseResults`. Accepts an optional ``indent`` argument so + that this string can be embedded in a nested display of other data. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + + prints:: + + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the + `pprint <https://docs.python.org/3/library/pprint.html>`_ module. + Accepts additional positional or keyword args as defined for + `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ . + + Example:: + + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + + prints:: + + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See + :class:`ParserElement.parseString` for more + information on parsing strings containing ``<TAB>`` s, and suggested + methods to maintain a consistent view of the parsed string, the parse + location, and line and column positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note - the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See :class:`ParserElement.parseString` + for more information on parsing strings containing ``<TAB>`` s, and + suggested methods to maintain a consistent view of the parsed string, the + parse location, and line and column positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = set(ParserElement.DEFAULT_WHITE_CHARS) + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this :class:`ParserElement`. Useful for defining + different parse actions for the same parsing pattern, using copies of + the original parse element. + + Example:: + + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + + prints:: + + [5120, 100, 655360, 268435456] + + Equivalent form of ``expr.copy()`` is just ``expr()``:: + + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original :class:`ParserElement` object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + ``expr("name")`` in place of ``expr.setResultsName("name")`` + - see :class:`__call__`. + + Example:: + + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set ``breakFlag`` to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as ``fn(s,loc,toks)`` , + ``fn(loc,toks)`` , ``fn(toks)`` , or just ``fn()`` , where: + + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a :class:`ParseResults` object + + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default= ``False`` ) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See :class:`parseString for more + information on parsing strings containing ``<TAB>`` s, and suggested + methods to maintain a consistent view of the parsed string, the parse + location, and line and column positions within the parsed string. + + Example:: + + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See :class:`setParseAction`. + + See examples in :class:`copy`. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + :class:`setParseAction` for function call signatures. Unlike ``setParseAction``, + functions passed to ``addCondition`` need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + fn = _trim_arity(fn) + def pa(s,l,t): + if not bool(fn(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + ``fn(s,loc,expr,err)`` where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw :class:`ParseFatalException` + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or preloc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + try: + tokens = fn( instring, tokensStart, retTokens ) + except IndexError as parse_action_exc: + exc = ParseException("exception raised in parse action") + exc.__cause__ = parse_action_exc + raise exc + + if tokens is not None and tokens is not retTokens: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + try: + tokens = fn( instring, tokensStart, retTokens ) + except IndexError as parse_action_exc: + exc = ParseException("exception raised in parse action") + exc.__cause__ = parse_action_exc + raise exc + + if tokens is not None and tokens is not retTokens: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + + - cache_size_limit - (default= ``128``) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method :class:`ParserElement.enablePackrat`. + For best results, call ``enablePackrat()`` immediately after + importing pyparsing. + + Example:: + + from pip._vendor import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set ``parseAll`` to True (equivalent to ending + the grammar with ``StringEnd()``). + + Note: ``parseString`` implicitly calls ``expandtabs()`` on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the ``loc`` argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + + - calling ``parseWithTabs`` on your grammar before calling ``parseString`` + (see :class:`parseWithTabs`) + - define your parse action using the full ``(s,loc,toks)`` signature, and + reference the input string using the parse action's ``s`` argument + - explictly expand the tabs in your input string before calling + ``parseString`` + + Example:: + + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + ``maxMatches`` argument, to clip scanning after 'n' matches are found. If + ``overlap`` is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See :class:`parseString` for more information on parsing + strings with embedded tabs. + + Example:: + + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to :class:`scanString`, to modify matching text with modified tokens that may + be returned from a parse action. To use ``transformString``, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking ``transformString()`` on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. ``transformString()`` returns the resulting transformed string. + + Example:: + + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + + prints:: + + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to :class:`scanString`, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + ``maxMatches`` argument, to clip searching after 'n' matches are found. + + Example:: + + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + + prints:: + + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional ``maxsplit`` argument, to limit the number of splits; + and the optional ``includeSeparators`` argument (default= ``False``), if the separating + matching text should be included in the split results. + + Example:: + + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + + prints:: + + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns :class:`And`. Adding strings to a ParserElement + converts them to :class:`Literal`s by default. + + Example:: + + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + + prints:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a :class:`ParserElement` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns :class:`And` with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a :class:`ParserElement` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of ``expr * 3`` in place of + ``expr + expr + expr``. Expressions may also me multiplied by a 2-integer + tuple, similar to ``{min,max}`` multipliers in regular expressions. Tuples + may also include ``None`` as in: + - ``expr*(n,None)`` or ``expr*(n,)`` is equivalent + to ``expr*n + ZeroOrMore(expr)`` + (read as "at least n instances of ``expr``") + - ``expr*(None,n)`` is equivalent to ``expr*(0,n)`` + (read as "0 to n instances of ``expr``") + - ``expr*(None,None)`` is equivalent to ``ZeroOrMore(expr)`` + - ``expr*(1,None)`` is equivalent to ``OneOrMore(expr)`` + + Note that ``expr*(None,n)`` does not raise an exception if + more than n exprs exist in the input stream; that is, + ``expr*(None,n)`` does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + ``expr*(None,n) + ~expr`` + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns :class:`MatchFirst` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a :class:`ParserElement` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns :class:`Or` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a :class:`ParserElement` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns :class:`Each` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a :class:`ParserElement` + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns :class:`NotAny` + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for :class:`setResultsName`, with ``listAllMatches=False``. + + If ``name`` is given with a trailing ``'*'`` character, then ``listAllMatches`` will be + passed as ``True``. + + If ``name` is omitted, same as calling :class:`copy`. + + Example:: + + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + :class:`ParserElement`'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand ``<TAB>``s to spaces before parsing the input string. + Must be called before ``parseString`` when the input grammar contains elements that + match ``<TAB>`` characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set ``flag`` to True to enable, False to disable. + + Example:: + + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using :class:`setDebugActions`. Prior to attempting + to match the ``wd`` expression, the debugging message ``"Match <exprname> at loc <n>(<line>,<col>)"`` + is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"`` + message is shown. Also note the use of :class:`setName` to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the :class:`Word` expression without calling ``setName`` is ``"W:(ABCD...)"``. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests + + Example:: + + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', + fullDump=True, printResults=True, failureTests=False, postParse=None): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests + - comment - (default= ``'#'``) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default= ``True``) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default= ``True``) prints test output to stdout + - failureTests - (default= ``False``) indicates if these tests are expected to fail parsing + - postParse - (default= ``None``) optional callback for successful parse results; called as + `fn(test_string, parse_results)` and returns a string to be added to the test output + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if ``failureTests`` is True), and the results contain a list of lines of each + test's output + + Example:: + + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + + prints:: + + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + # convert newline marks to actual newlines, and strip leading BOM if present + t = t.replace(r'\n','\n').lstrip('\ufeff') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + if postParse is not None: + try: + pp_value = postParse(t, result) + if pp_value is not None: + out.append(str(pp_value)) + except Exception as e: + out.append("{0} failed: {1}: {2}".format(postParse.__name__, type(e).__name__, e)) + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """Abstract :class:`ParserElement` subclass, for defining atomic + matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """Token to exactly match a specified string. + + Example:: + + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use :class:`CaselessLiteral`. + + For keyword matching (force word break before and after the matched string), + use :class:`Keyword` or :class:`CaselessKeyword`. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """Token to exactly match a specified string as a keyword, that is, + it must be immediately followed by a non-keyword character. Compare + with :class:`Literal`: + + - ``Literal("if")`` will match the leading ``'if'`` in + ``'ifAndOnlyIf'``. + - ``Keyword("if")`` will not; it will only match the leading + ``'if'`` in ``'if x=1'``, or ``'if(y==2)'`` + + Accepts two optional constructor arguments in addition to the + keyword string: + + - ``identChars`` is a string of characters that would be valid + identifier characters, defaulting to all alphanumerics + "_" and + "$" + - ``caseless`` allows case-insensitive matching, default is ``False``. + + Example:: + + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use :class:`CaselessKeyword`. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for :class:`CaselessKeyword`.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of :class:`Keyword`. + + Example:: + + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for :class:`CaselessLiteral`.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + +class CloseMatch(Token): + """A variation on :class:`Literal` which matches "close" matches, + that is, strings with at most 'n' mismatching characters. + :class:`CloseMatch` takes parameters: + + - ``match_string`` - string to be matched + - ``maxMismatches`` - (``default=1``) maximum number of + mismatches allowed to count as a match + + The results from a successful parse will contain the matched text + from the input string and the following named results: + + - ``mismatches`` - a list of the positions within the + match_string where mismatches were found + - ``original`` - the original match_string used to compare + against the input string + + If ``mismatches`` is an empty list, then the match was an exact + match. + + Example:: + + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, an + optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for ``min`` is + 1 (a minimum value < 1 is not valid); the default values for + ``max`` and ``exact`` are 0, meaning no maximum or exact + length restriction. An optional ``excludeChars`` parameter can + list characters that might be found in the input ``bodyChars`` + string; useful to define a word of all printables except for one or + two characters, for instance. + + :class:`srange` is useful for defining custom character set strings + for defining ``Word`` expressions, using range notation from + regular expression character sets. + + A common mistake is to use :class:`Word` to match a specific literal + string, as in ``Word("Address")``. Remember that :class:`Word` + uses the string argument to define *sets* of matchable characters. + This expression would match "Add", "AAA", "dAred", or any other word + made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an + exact literal string, use :class:`Literal` or :class:`Keyword`. + + pyparsing includes helper strings for building Words: + + - :class:`alphas` + - :class:`nums` + - :class:`alphanums` + - :class:`hexnums` + - :class:`alphas8bit` (alphabetic characters in ASCII range 128-255 + - accented, tilded, umlauted, etc.) + - :class:`punc8bit` (non-alphabetic characters in ASCII range + 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - :class:`printables` (any non-whitespace character) + + Example:: + + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Char(Word): + """A short-cut class for defining ``Word(characters, exact=1)``, + when defining a match of any single character in a string of + characters. + """ + def __init__(self, charset): + super(Char, self).__init__(charset, exact=1) + self.reString = "[%s]" % _escapeRegexRangeChars(self.initCharsOrig) + self.re = re.compile( self.reString ) + + +class Regex(Token): + r"""Token for matching strings that match a given regular + expression. Defined with string specifying the regular expression in + a form recognized by the stdlib Python `re module <https://docs.python.org/3/library/re.html>`_. + If the given regex contains named groups (defined using ``(?P<name>...)``), + these will be preserved as named parse results. + + Example:: + + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0, asGroupList=False, asMatch=False): + """The parameters ``pattern`` and ``flags`` are passed + to the ``re.compile()`` function as-is. See the Python + `re module <https://docs.python.org/3/library/re.html>`_ module for an + explanation of the acceptable patterns and flags. + """ + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + self.asGroupList = asGroupList + self.asMatch = asMatch + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + if self.asMatch: + ret = result + elif self.asGroupList: + ret = result.groups() + else: + ret = ParseResults(result.group()) + d = result.groupdict() + if d: + for k, v in d.items(): + ret[k] = v + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + def sub(self, repl): + """ + Return Regex with an attached parse action to transform the parsed + result as if called using `re.sub(expr, repl, string) <https://docs.python.org/3/library/re.html#re.sub>`_. + + Example:: + + make_html = Regex(r"(\w+):(.*?):").sub(r"<\1>\2</\1>") + print(make_html.transformString("h1:main title:")) + # prints "<h1>main title</h1>" + """ + if self.asGroupList: + warnings.warn("cannot use sub() with Regex(asGroupList=True)", + SyntaxWarning, stacklevel=2) + raise SyntaxError() + + if self.asMatch and callable(repl): + warnings.warn("cannot use sub() with a callable with Regex(asMatch=True)", + SyntaxWarning, stacklevel=2) + raise SyntaxError() + + if self.asMatch: + def pa(tokens): + return tokens[0].expand(repl) + else: + def pa(tokens): + return self.re.sub(repl, tokens[0]) + return self.addParseAction(pa) + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + + - quoteChar - string of one or more characters defining the + quote delimiting string + - escChar - character to escape quotes, typically backslash + (default= ``None`` ) + - escQuote - special quote sequence to escape an embedded quote + string (such as SQL's ``""`` to escape an embedded ``"``) + (default= ``None`` ) + - multiline - boolean indicating whether quotes can span + multiple lines (default= ``False`` ) + - unquoteResults - boolean indicating whether the matched text + should be unquoted (default= ``True`` ) + - endQuoteChar - string of one or more characters defining the + end of the quote delimited string (default= ``None`` => same as + quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace + (``'\t'``, ``'\n'``, etc.) to actual whitespace + (default= ``True`` ) + + Example:: + + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + + prints:: + + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """Token for matching words composed of characters *not* in a given + set (will include whitespace in matched characters if not listed in + the provided exclusion set - see example). Defined with string + containing all disallowed characters, and an optional minimum, + maximum, and/or exact length. The default value for ``min`` is + 1 (a minimum value < 1 is not valid); the default values for + ``max`` and ``exact`` are 0, meaning no maximum or exact + length restriction. + + Example:: + + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + + prints:: + + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError( + "cannot specify a minimum length < 1; use " + + "Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """Special matching class for matching whitespace. Normally, + whitespace is ignored by pyparsing grammars. This class is included + when some whitespace structures are significant. Define with + a string containing the whitespace characters to be matched; default + is ``" \\t\\r\\n"``. Also takes optional ``min``, + ``max``, and ``exact`` arguments, as defined for the + :class:`Word` class. + """ + whiteStrs = { + ' ' : '<SP>', + '\t': '<TAB>', + '\n': '<LF>', + '\r': '<CR>', + '\f': '<FF>', + 'u\00A0': '<NBSP>', + 'u\1680': '<OGHAM_SPACE_MARK>', + 'u\180E': '<MONGOLIAN_VOWEL_SEPARATOR>', + 'u\2000': '<EN_QUAD>', + 'u\2001': '<EM_QUAD>', + 'u\2002': '<EN_SPACE>', + 'u\2003': '<EM_SPACE>', + 'u\2004': '<THREE-PER-EM_SPACE>', + 'u\2005': '<FOUR-PER-EM_SPACE>', + 'u\2006': '<SIX-PER-EM_SPACE>', + 'u\2007': '<FIGURE_SPACE>', + 'u\2008': '<PUNCTUATION_SPACE>', + 'u\2009': '<THIN_SPACE>', + 'u\200A': '<HAIR_SPACE>', + 'u\200B': '<ZERO_WIDTH_SPACE>', + 'u\202F': '<NNBSP>', + 'u\205F': '<MMSP>', + 'u\3000': '<IDEOGRAPHIC_SPACE>', + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """Token to advance to a specific column of input text; useful for + tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """Matches if current position is at the beginning of a line within + the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + prints:: + + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """Matches if current position is at the end of a line within the + parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """Matches if current position is at the beginning of the parse + string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """Matches if the current position is at the beginning of a Word, + and is not preceded by any character in a given set of + ``wordChars`` (default= ``printables``). To emulate the + ``\b`` behavior of regular expressions, use + ``WordStart(alphanums)``. ``WordStart`` will also match at + the beginning of the string being parsed, or at the beginning of + a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """Matches if the current position is at the end of a Word, and is + not followed by any character in a given set of ``wordChars`` + (default= ``printables``). To emulate the ``\b`` behavior of + regular expressions, use ``WordEnd(alphanums)``. ``WordEnd`` + will also match at the end of the string being parsed, or at the end + of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """Abstract subclass of ParserElement, for combining and + post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends ``leaveWhitespace`` defined in base class, and also invokes ``leaveWhitespace`` on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given :class:`ParseExpression` s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the ``'+'`` operator. + May also be constructed using the ``'-'`` operator, which will + suppress backtracking. + + Example:: + + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def streamline(self): + super(And, self).streamline() + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + return self + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """Requires that at least one :class:`ParseExpression` is found. If + two expressions match, the expression that matches the longest + string will be used. May be constructed using the ``'^'`` + operator. + + Example:: + + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + + prints:: + + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def streamline(self): + super(Or, self).streamline() + self.saveAsList = any(e.saveAsList for e in self.exprs) + return self + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """Requires that at least one :class:`ParseExpression` is found. If + two expressions match, the first one listed is the one that will + match. May be constructed using the ``'|'`` operator. + + Example:: + + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + # self.saveAsList = any(e.saveAsList for e in self.exprs) + else: + self.mayReturnEmpty = True + + def streamline(self): + super(MatchFirst, self).streamline() + self.saveAsList = any(e.saveAsList for e in self.exprs) + return self + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """Requires all given :class:`ParseExpression` s to be found, but in + any order. Expressions may be separated by whitespace. + + May be constructed using the ``'&'`` operator. + + Example:: + + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + + prints:: + + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + self.saveAsList = True + + def streamline(self): + super(Each, self).streamline() + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + return self + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """Abstract subclass of :class:`ParserElement`, for combining and + post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """Lookahead matching of the given parse expression. + ``FollowedBy`` does *not* advance the parsing position within + the input string, it only verifies that the specified parse + expression matches at the current position. ``FollowedBy`` + always returns a null token list. If any results names are defined + in the lookahead expression, those *will* be returned for access by + name. + + Example:: + + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + + prints:: + + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + _, ret = self.expr._parse(instring, loc, doActions=doActions) + del ret[:] + return loc, ret + + +class PrecededBy(ParseElementEnhance): + """Lookbehind matching of the given parse expression. + ``PrecededBy`` does not advance the parsing position within the + input string, it only verifies that the specified parse expression + matches prior to the current position. ``PrecededBy`` always + returns a null token list, but if a results name is defined on the + given expression, it is returned. + + Parameters: + + - expr - expression that must match prior to the current parse + location + - retreat - (default= ``None``) - (int) maximum number of characters + to lookbehind prior to the current parse location + + If the lookbehind expression is a string, Literal, Keyword, or + a Word or CharsNotIn with a specified exact or maximum length, then + the retreat parameter is not required. Otherwise, retreat must be + specified to give a maximum number of characters to look back from + the current parse position for a lookbehind match. + + Example:: + + # VB-style variable names with type prefixes + int_var = PrecededBy("#") + pyparsing_common.identifier + str_var = PrecededBy("$") + pyparsing_common.identifier + + """ + def __init__(self, expr, retreat=None): + super(PrecededBy, self).__init__(expr) + self.expr = self.expr().leaveWhitespace() + self.mayReturnEmpty = True + self.mayIndexError = False + self.exact = False + if isinstance(expr, str): + retreat = len(expr) + self.exact = True + elif isinstance(expr, (Literal, Keyword)): + retreat = expr.matchLen + self.exact = True + elif isinstance(expr, (Word, CharsNotIn)) and expr.maxLen != _MAX_INT: + retreat = expr.maxLen + self.exact = True + elif isinstance(expr, _PositionToken): + retreat = 0 + self.exact = True + self.retreat = retreat + self.errmsg = "not preceded by " + str(expr) + self.skipWhitespace = False + + def parseImpl(self, instring, loc=0, doActions=True): + if self.exact: + if loc < self.retreat: + raise ParseException(instring, loc, self.errmsg) + start = loc - self.retreat + _, ret = self.expr._parse(instring, start) + else: + # retreat specified a maximum lookbehind window, iterate + test_expr = self.expr + StringEnd() + instring_slice = instring[:loc] + last_expr = ParseException(instring, loc, self.errmsg) + for offset in range(1, min(loc, self.retreat+1)): + try: + _, ret = test_expr._parse(instring_slice, loc-offset) + except ParseBaseException as pbe: + last_expr = pbe + else: + break + else: + raise last_expr + # return empty list of tokens, but preserve any defined results names + del ret[:] + return loc, ret + + +class NotAny(ParseElementEnhance): + """Lookahead to disallow matching with the given parse expression. + ``NotAny`` does *not* advance the parsing position within the + input string, it only verifies that the specified parse expression + does *not* match at the current position. Also, ``NotAny`` does + *not* skip over leading whitespace. ``NotAny`` always returns + a null token list. May be constructed using the '~' operator. + + Example:: + + AND, OR, NOT = map(CaselessKeyword, "AND OR NOT".split()) + + # take care not to mistake keywords for identifiers + ident = ~(AND | OR | NOT) + Word(alphas) + boolean_term = Optional(NOT) + ident + + # very crude boolean expression - to support parenthesis groups and + # operation hierarchy, use infixNotation + boolean_expr = boolean_term + ZeroOrMore((AND | OR) + boolean_term) + + # integers that are followed by "." are actually floats + integer = Word(nums) + ~Char(".") + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default= ``None``) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default= ``None``) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to :class:`OneOrMore` + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + + prints:: + + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """Token for skipping over all undefined text until the matched + expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default= ``False``) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default= ``None``) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default= ``None``) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + + prints:: + + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.saveAsList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the ``Forward`` + variable using the '<<' operator. + + Note: take care when assigning to ``Forward`` not to overlook + precedence of operators. + + Specifically, '|' has a lower precedence than '<<', so that:: + + fwdExpr << a | b | c + + will actually be evaluated as:: + + (fwdExpr << a) | b | c + + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the ``Forward``:: + + fwdExpr << (a | b | c) + + Converting to use the '<<=' operator instead will avoid this problem. + + See :class:`ParseResults.pprint` for an example of a recursive + parser created using ``Forward``. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of :class:`ParseExpression`, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the + input string; this can be disabled by specifying + ``'adjacent=False'`` in the constructor. + + Example:: + + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """Converter to return the matched tokens as a list - useful for + returning tokens of :class:`ZeroOrMore` and :class:`OneOrMore` expressions. + + Example:: + + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = expr.saveAsList + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """Converter to return a repetitive expression as a list, but also + as a dictionary. Each element can also be referenced using the first + token in the expression as its key. Useful for tabular report + scraping when the first column can be used as a item key. + + Example:: + + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + + prints:: + + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + + See more examples at :class:`ParseResults` of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """Converter for ignoring the results of a parsed expression. + + Example:: + + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + + prints:: + + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + + (See also :class:`delimitedList`.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """Decorator for debugging parse actions. + + When the parse action is called, this decorator will print + ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``. + When the parse action completes, the decorator will print + ``"<<"`` followed by the returned value, or any exception that the parse action raised. + + Example:: + + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + + prints:: + + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """Helper to define a delimited list of expressions - the delimiter + defaults to ','. By default, the list elements and delimiters can + have intervening whitespace, and comments, but this can be + overridden by passing ``combine=True`` in the constructor. If + ``combine`` is set to ``True``, the matching tokens are + returned as a single token string, with the delimiters included; + otherwise, the matching tokens are returned as a list of tokens, + with the delimiters suppressed. + + Example:: + + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """Helper to define a counted list of expressions. + + This helper defines a pattern of the form:: + + integer expr expr expr... + + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the + leading count token is suppressed. + + If ``intExpr`` is specified, it should be a pyparsing expression + that produces an integer value. + + Example:: + + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks for + a 'repeat' of a previous expression. For example:: + + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + + will match ``"1:1"``, but not ``"1:2"``. Because this + matches a previous literal, will also match the leading + ``"1:1"`` in ``"1:10"``. If this is not desired, use + :class:`matchPreviousExpr`. Do *not* use with packrat parsing + enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks for + a 'repeat' of a previous expression. For example:: + + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + + will match ``"1:1"``, but not ``"1:2"``. Because this + matches by expressions, will *not* match the leading ``"1:1"`` + in ``"1:10"``; the expressions are evaluated first, and then + compared, so ``"1"`` is compared with ``"10"``. Do *not* use + with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """Helper to quickly define a set of alternative Literals, and makes + sure to do longest-first testing when there is a conflict, + regardless of the input order, but returns + a :class:`MatchFirst` for best performance. + + Parameters: + + - strs - a string of space-delimited literals, or a collection of + string literals + - caseless - (default= ``False``) - treat all literals as + caseless + - useRegex - (default= ``True``) - as an optimization, will + generate a Regex object; otherwise, will generate + a :class:`MatchFirst` object (if ``caseless=True``, or if + creating a :class:`Regex` raises an exception) + + Example:: + + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + + prints:: + + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """Helper to easily and clearly define a dictionary by specifying + the respective patterns for the key and value. Takes care of + defining the :class:`Dict`, :class:`ZeroOrMore`, and + :class:`Group` tokens in the proper order. The key pattern + can include delimiting markers or punctuation, as long as they are + suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the :class:`Dict` results + can include named token fields. + + Example:: + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + + prints:: + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict(OneOrMore(Group(key + value))) + +def originalTextFor(expr, asString=True): + """Helper to return the original, untokenized text for a given + expression. Useful to restore the parsed fields of an HTML start + tag into the raw tag text itself, or to revert separate tokens with + intervening whitespace back to the original matching input text. By + default, returns astring containing the original parsed text. + + If the optional ``asString`` argument is passed as + ``False``, then the return value is + a :class:`ParseResults` containing any results names that + were originally matched, and a single token containing the original + matched text from the input string. So if the expression passed to + :class:`originalTextFor` contains expressions with defined + results names, you must set ``asString`` to ``False`` if you + want to preserve those results name values. + + Example:: + + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + + prints:: + + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """Helper to undo pyparsing's default grouping of And expressions, + even if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """Helper to decorate a returned token with its starting and ending + locations in the input string. + + This helper adds the following results names: + + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains ``<TAB>`` characters, you + may want to call :class:`ParserElement.parseWithTabs` + + Example:: + + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + + prints:: + + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r"""Helper to easily define string ranges for use in Word + construction. Borrows syntax from regexp '[]' string range + definitions:: + + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + + The input string must be enclosed in []'s, and the returned string + is the expanded character set joined into a single string. The + values enclosed in the []'s may be: + + - a single character + - an escaped character with a leading backslash (such as ``\-`` + or ``\]``) + - an escaped hex character with a leading ``'\x'`` + (``\x21``, which is a ``'!'`` character) (``\0x##`` + is also supported for backwards compatibility) + - an escaped octal character with a leading ``'\0'`` + (``\041``, which is a ``'!'`` character) + - a range of any of the above, separated by a dash (``'a-z'``, + etc.) + - any combination of the above (``'aeiouy'``, + ``'a-zA-Z0-9_$'``, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """Helper method for defining parse actions that require matching at + a specific column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """Helper method for common parse actions that simply return + a literal value. Especially useful when used with + :class:`transformString<ParserElement.transformString>` (). + + Example:: + + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """Helper parse action for removing quotation marks from parsed + quoted strings. + + Example:: + + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """Helper to define a parse action by mapping a function to all + elements of a ParseResults list. If any additional args are passed, + they are forwarded to the given function as additional arguments + after the token, as in + ``hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))``, + which will convert the parsed data to an integer using base 16. + + Example (compare the last to example in :class:`ParserElement.transformString`:: + + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + + prints:: + + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. +Deprecated in favor of :class:`pyparsing_common.upcaseTokens`""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. +Deprecated in favor of :class:`pyparsing_common.downcaseTokens`""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """Helper to construct opening and closing tag expressions for HTML, + given a tag name. Matches tags in either upper or lower case, + attributes with namespaces and with quoted or unquoted values. + + Example:: + + text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and + # closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are + # also accessible as named results + print(link.link_text, '->', link.href) + + prints:: + + pyparsing -> https://github.com/pyparsing/pyparsing/wiki + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """Helper to construct opening and closing tag expressions for XML, + given a tag name. Matches tags only in the given upper/lower case. + + Example: similar to :class:`makeHTMLTags` + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """Helper to create a validating parse action to be used with start + tags created with :class:`makeXMLTags` or + :class:`makeHTMLTags`. Use ``withAttribute`` to qualify + a starting tag with a required attribute value, to avoid false + matches on common tags such as ``<TD>`` or ``<DIV>``. + + Call ``withAttribute`` with a series of attribute names and + values. Specify the list of filter attributes names and values as: + + - keyword arguments, as in ``(align="right")``, or + - as an explicit dict with ``**`` operator, when an attribute + name is also a Python reserved word, as in ``**{"class":"Customer", "align":"right"}`` + - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align","right"))`` + + For attribute names with a namespace prefix, you must use the second + form. Attribute names are matched insensitive to upper/lower case. + + If just testing for ``class`` (with or without a namespace), use + :class:`withClass`. + + To verify that the attribute exists, but without specifying a value, + pass ``withAttribute.ANY_VALUE`` as the value. + + Example:: + + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + + prints:: + + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """Simplified version of :class:`withAttribute` when + matching on a div class - made difficult because ``class`` is + a reserved word in Python. + + Example:: + + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + + prints:: + + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = SimpleNamespace() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary + or binary, left- or right-associative. Parse actions can also be + attached to operator expressions. The generated parser will also + recognize the use of parentheses to override operator precedences + (see example below). + + Note: if you define a deep operator list, you may see performance + issues when using infixNotation. See + :class:`ParserElement.enablePackrat` for a mechanism to potentially + improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the + nested + - opList - list of tuples, one for each operator precedence level + in the expression grammar; each tuple is of the form ``(opExpr, + numTerms, rightLeftAssoc, parseAction)``, where: + + - opExpr is the pyparsing expression for the operator; may also + be a string, which will be converted to a Literal; if numTerms + is 3, opExpr is a tuple of two expressions, for the two + operators separating the 3 terms + - numTerms is the number of terms for this operator (must be 1, + 2, or 3) + - rightLeftAssoc is the indicator whether the operator is right + or left associative, using the pyparsing-defined constants + ``opAssoc.RIGHT`` and ``opAssoc.LEFT``. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the parse action + tuple member may be omitted); if the parse action is passed + a tuple or list of functions, this is equivalent to calling + ``setParseAction(*fn)`` + (:class:`ParserElement.setParseAction`) + - lpar - expression for matching left-parentheses + (default= ``Suppress('(')``) + - rpar - expression for matching right-parentheses + (default= ``Suppress(')')``) + + Example:: + + # simple example of four-function arithmetic with ints and + # variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + + prints:: + + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + # captive version of FollowedBy that does not do parse actions or capture results names + class _FB(FollowedBy): + def parseImpl(self, instring, loc, doActions=True): + self.expr.tryParse(instring, loc) + return loc, [] + + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError( + "if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = _FB(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = _FB(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = _FB(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = _FB(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = _FB(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = _FB(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of :class:`infixNotation`, will be +dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """Helper method for defining nested lists enclosed in opening and + closing delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list + (default= ``"("``); can also be a pyparsing expression + - closer - closing character for a nested list + (default= ``")"``); can also be a pyparsing expression + - content - expression for items within the nested lists + (default= ``None``) + - ignoreExpr - expression for ignoring opening and closing + delimiters (default= :class:`quotedString`) + + If an expression is not provided for the content argument, the + nested expression will capture all whitespace-delimited content + between delimiters as a list of separate values. + + Use the ``ignoreExpr`` argument to define expressions that may + contain opening or closing characters that should not be treated as + opening or closing characters for nesting, such as quotedString or + a comment expression. Specify multiple expressions using an + :class:`Or` or :class:`MatchFirst`. The default is + :class:`quotedString`, but if no expressions are to be ignored, then + pass ``None`` for this argument. + + Example:: + + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + + prints:: + + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """Helper method for defining space-delimited indentation blocks, + such as those used to define block statements in Python source code. + + Parameters: + + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single + grammar should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond + the the current level; set to False for block of left-most + statements (default= ``True``) + + A valid block must contain at least one ``blockStatement``. + + Example:: + + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + + prints:: + + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form ``/* ... */``" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form ``<!-- ... -->``" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form ``// ... (to end of line)``" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form :class:`cStyleComment` or :class:`dblSlashComment`" + +javaStyleComment = cppStyleComment +"Same as :class:`cppStyleComment`" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form ``# ... (to end of line)``" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or +quoted strings, separated by commas. + +This expression is deprecated in favor of :class:`pyparsing_common.comma_separated_list`. +""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """Here are some common low-level expressions that may be useful in + jump-starting parser development: + + - numeric forms (:class:`integers<integer>`, :class:`reals<real>`, + :class:`scientific notation<sci_real>`) + - common :class:`programming identifiers<identifier>` + - network addresses (:class:`MAC<mac_address>`, + :class:`IPv4<ipv4_address>`, :class:`IPv6<ipv6_address>`) + - ISO8601 :class:`dates<iso8601_date>` and + :class:`datetime<iso8601_datetime>` + - :class:`UUID<uuid>` + - :class:`comma-separated list<comma_separated_list>` + + Parse actions: + + - :class:`convertToInteger` + - :class:`convertToFloat` + - :class:`convertToDate` + - :class:`convertToDatetime` + - :class:`stripHTMLTags` + - :class:`upcaseTokens` + - :class:`downcaseTokens` + + Example:: + + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + + prints:: + + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional + scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (``0.0.0.0 - 255.255.255.255``)" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%d"``) + + Example:: + + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + + prints:: + + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """Helper to create a parse action for converting parsed + datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%dT%H:%M:%S.%f"``) + + Example:: + + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + + prints:: + + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (``yyyy-mm-dd``)" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (``yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)``) - trailing seconds, milliseconds, and timezone optional; accepts separating ``'T'`` or ``' '``" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``)" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """Parse action to remove HTML tags from web page HTML source + + Example:: + + # strip HTML links from normal text + text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + print(table_text.parseString(text).body) + + Prints:: + + More info at the pyparsing wiki page + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +class _lazyclassproperty(object): + def __init__(self, fn): + self.fn = fn + self.__doc__ = fn.__doc__ + self.__name__ = fn.__name__ + + def __get__(self, obj, cls): + if cls is None: + cls = type(obj) + if not hasattr(cls, '_intern') or any(cls._intern is getattr(superclass, '_intern', []) for superclass in cls.__mro__[1:]): + cls._intern = {} + attrname = self.fn.__name__ + if attrname not in cls._intern: + cls._intern[attrname] = self.fn(cls) + return cls._intern[attrname] + + +class unicode_set(object): + """ + A set of Unicode characters, for language-specific strings for + ``alphas``, ``nums``, ``alphanums``, and ``printables``. + A unicode_set is defined by a list of ranges in the Unicode character + set, in a class attribute ``_ranges``, such as:: + + _ranges = [(0x0020, 0x007e), (0x00a0, 0x00ff),] + + A unicode set can also be defined using multiple inheritance of other unicode sets:: + + class CJK(Chinese, Japanese, Korean): + pass + """ + _ranges = [] + + @classmethod + def _get_chars_for_ranges(cls): + ret = [] + for cc in cls.__mro__: + if cc is unicode_set: + break + for rr in cc._ranges: + ret.extend(range(rr[0], rr[-1]+1)) + return [unichr(c) for c in sorted(set(ret))] + + @_lazyclassproperty + def printables(cls): + "all non-whitespace characters in this range" + return u''.join(filterfalse(unicode.isspace, cls._get_chars_for_ranges())) + + @_lazyclassproperty + def alphas(cls): + "all alphabetic characters in this range" + return u''.join(filter(unicode.isalpha, cls._get_chars_for_ranges())) + + @_lazyclassproperty + def nums(cls): + "all numeric digit characters in this range" + return u''.join(filter(unicode.isdigit, cls._get_chars_for_ranges())) + + @_lazyclassproperty + def alphanums(cls): + "all alphanumeric characters in this range" + return cls.alphas + cls.nums + + +class pyparsing_unicode(unicode_set): + """ + A namespace class for defining common language unicode_sets. + """ + _ranges = [(32, sys.maxunicode)] + + class Latin1(unicode_set): + "Unicode set for Latin-1 Unicode Character Range" + _ranges = [(0x0020, 0x007e), (0x00a0, 0x00ff),] + + class LatinA(unicode_set): + "Unicode set for Latin-A Unicode Character Range" + _ranges = [(0x0100, 0x017f),] + + class LatinB(unicode_set): + "Unicode set for Latin-B Unicode Character Range" + _ranges = [(0x0180, 0x024f),] + + class Greek(unicode_set): + "Unicode set for Greek Unicode Character Ranges" + _ranges = [ + (0x0370, 0x03ff), (0x1f00, 0x1f15), (0x1f18, 0x1f1d), (0x1f20, 0x1f45), (0x1f48, 0x1f4d), + (0x1f50, 0x1f57), (0x1f59,), (0x1f5b,), (0x1f5d,), (0x1f5f, 0x1f7d), (0x1f80, 0x1fb4), (0x1fb6, 0x1fc4), + (0x1fc6, 0x1fd3), (0x1fd6, 0x1fdb), (0x1fdd, 0x1fef), (0x1ff2, 0x1ff4), (0x1ff6, 0x1ffe), + ] + + class Cyrillic(unicode_set): + "Unicode set for Cyrillic Unicode Character Range" + _ranges = [(0x0400, 0x04ff)] + + class Chinese(unicode_set): + "Unicode set for Chinese Unicode Character Range" + _ranges = [(0x4e00, 0x9fff), (0x3000, 0x303f), ] + + class Japanese(unicode_set): + "Unicode set for Japanese Unicode Character Range, combining Kanji, Hiragana, and Katakana ranges" + _ranges = [ ] + + class Kanji(unicode_set): + "Unicode set for Kanji Unicode Character Range" + _ranges = [(0x4E00, 0x9Fbf), (0x3000, 0x303f), ] + + class Hiragana(unicode_set): + "Unicode set for Hiragana Unicode Character Range" + _ranges = [(0x3040, 0x309f), ] + + class Katakana(unicode_set): + "Unicode set for Katakana Unicode Character Range" + _ranges = [(0x30a0, 0x30ff), ] + + class Korean(unicode_set): + "Unicode set for Korean Unicode Character Range" + _ranges = [(0xac00, 0xd7af), (0x1100, 0x11ff), (0x3130, 0x318f), (0xa960, 0xa97f), (0xd7b0, 0xd7ff), (0x3000, 0x303f), ] + + class CJK(Chinese, Japanese, Korean): + "Unicode set for combined Chinese, Japanese, and Korean (CJK) Unicode Character Range" + pass + + class Thai(unicode_set): + "Unicode set for Thai Unicode Character Range" + _ranges = [(0x0e01, 0x0e3a), (0x0e3f, 0x0e5b), ] + + class Arabic(unicode_set): + "Unicode set for Arabic Unicode Character Range" + _ranges = [(0x0600, 0x061b), (0x061e, 0x06ff), (0x0700, 0x077f), ] + + class Hebrew(unicode_set): + "Unicode set for Hebrew Unicode Character Range" + _ranges = [(0x0590, 0x05ff), ] + + class Devanagari(unicode_set): + "Unicode set for Devanagari Unicode Character Range" + _ranges = [(0x0900, 0x097f), (0xa8e0, 0xa8ff)] + +pyparsing_unicode.Japanese._ranges = (pyparsing_unicode.Japanese.Kanji._ranges + + pyparsing_unicode.Japanese.Hiragana._ranges + + pyparsing_unicode.Japanese.Katakana._ranges) + +# define ranges in language character sets +if PY_3: + setattr(pyparsing_unicode, "العربية", pyparsing_unicode.Arabic) + setattr(pyparsing_unicode, "中文", pyparsing_unicode.Chinese) + setattr(pyparsing_unicode, "кириллица", pyparsing_unicode.Cyrillic) + setattr(pyparsing_unicode, "Ελληνικά", pyparsing_unicode.Greek) + setattr(pyparsing_unicode, "עִברִית", pyparsing_unicode.Hebrew) + setattr(pyparsing_unicode, "日本語", pyparsing_unicode.Japanese) + setattr(pyparsing_unicode.Japanese, "漢字", pyparsing_unicode.Japanese.Kanji) + setattr(pyparsing_unicode.Japanese, "カタカナ", pyparsing_unicode.Japanese.Katakana) + setattr(pyparsing_unicode.Japanese, "ひらがな", pyparsing_unicode.Japanese.Hiragana) + setattr(pyparsing_unicode, "한국어", pyparsing_unicode.Korean) + setattr(pyparsing_unicode, "ไทย", pyparsing_unicode.Thai) + setattr(pyparsing_unicode, "देवनागरी", pyparsing_unicode.Devanagari) + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/__init__.py new file mode 100755 index 0000000..8ed060f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/__init__.py @@ -0,0 +1,4 @@ +from .core import TomlError +from .parser import load, loads +from .test import translate_to_test +from .writer import dump, dumps \ No newline at end of file diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/core.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/core.py new file mode 100755 index 0000000..c182734 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/core.py @@ -0,0 +1,13 @@ +class TomlError(RuntimeError): + def __init__(self, message, line, col, filename): + RuntimeError.__init__(self, message, line, col, filename) + self.message = message + self.line = line + self.col = col + self.filename = filename + + def __str__(self): + return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) + + def __repr__(self): + return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/parser.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/parser.py new file mode 100755 index 0000000..3493aa6 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/parser.py @@ -0,0 +1,341 @@ +import string, re, sys, datetime +from .core import TomlError +from .utils import rfc3339_re, parse_rfc3339_re + +if sys.version_info[0] == 2: + _chr = unichr +else: + _chr = chr + +def load(fin, translate=lambda t, x, v: v, object_pairs_hook=dict): + return loads(fin.read(), translate=translate, object_pairs_hook=object_pairs_hook, filename=getattr(fin, 'name', repr(fin))) + +def loads(s, filename='<string>', translate=lambda t, x, v: v, object_pairs_hook=dict): + if isinstance(s, bytes): + s = s.decode('utf-8') + + s = s.replace('\r\n', '\n') + + root = object_pairs_hook() + tables = object_pairs_hook() + scope = root + + src = _Source(s, filename=filename) + ast = _p_toml(src, object_pairs_hook=object_pairs_hook) + + def error(msg): + raise TomlError(msg, pos[0], pos[1], filename) + + def process_value(v, object_pairs_hook): + kind, text, value, pos = v + if kind == 'str' and value.startswith('\n'): + value = value[1:] + if kind == 'array': + if value and any(k != value[0][0] for k, t, v, p in value[1:]): + error('array-type-mismatch') + value = [process_value(item, object_pairs_hook=object_pairs_hook) for item in value] + elif kind == 'table': + value = object_pairs_hook([(k, process_value(value[k], object_pairs_hook=object_pairs_hook)) for k in value]) + return translate(kind, text, value) + + for kind, value, pos in ast: + if kind == 'kv': + k, v = value + if k in scope: + error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) + scope[k] = process_value(v, object_pairs_hook=object_pairs_hook) + else: + is_table_array = (kind == 'table_array') + cur = tables + for name in value[:-1]: + if isinstance(cur.get(name), list): + d, cur = cur[name][-1] + else: + d, cur = cur.setdefault(name, (None, object_pairs_hook())) + + scope = object_pairs_hook() + name = value[-1] + if name not in cur: + if is_table_array: + cur[name] = [(scope, object_pairs_hook())] + else: + cur[name] = (scope, object_pairs_hook()) + elif isinstance(cur[name], list): + if not is_table_array: + error('table_type_mismatch') + cur[name].append((scope, object_pairs_hook())) + else: + if is_table_array: + error('table_type_mismatch') + old_scope, next_table = cur[name] + if old_scope is not None: + error('duplicate_tables') + cur[name] = (scope, next_table) + + def merge_tables(scope, tables): + if scope is None: + scope = object_pairs_hook() + for k in tables: + if k in scope: + error('key_table_conflict') + v = tables[k] + if isinstance(v, list): + scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] + else: + scope[k] = merge_tables(v[0], v[1]) + return scope + + return merge_tables(root, tables) + +class _Source: + def __init__(self, s, filename=None): + self.s = s + self._pos = (1, 1) + self._last = None + self._filename = filename + self.backtrack_stack = [] + + def last(self): + return self._last + + def pos(self): + return self._pos + + def fail(self): + return self._expect(None) + + def consume_dot(self): + if self.s: + self._last = self.s[0] + self.s = self[1:] + self._advance(self._last) + return self._last + return None + + def expect_dot(self): + return self._expect(self.consume_dot()) + + def consume_eof(self): + if not self.s: + self._last = '' + return True + return False + + def expect_eof(self): + return self._expect(self.consume_eof()) + + def consume(self, s): + if self.s.startswith(s): + self.s = self.s[len(s):] + self._last = s + self._advance(s) + return True + return False + + def expect(self, s): + return self._expect(self.consume(s)) + + def consume_re(self, re): + m = re.match(self.s) + if m: + self.s = self.s[len(m.group(0)):] + self._last = m + self._advance(m.group(0)) + return m + return None + + def expect_re(self, re): + return self._expect(self.consume_re(re)) + + def __enter__(self): + self.backtrack_stack.append((self.s, self._pos)) + + def __exit__(self, type, value, traceback): + if type is None: + self.backtrack_stack.pop() + else: + self.s, self._pos = self.backtrack_stack.pop() + return type == TomlError + + def commit(self): + self.backtrack_stack[-1] = (self.s, self._pos) + + def _expect(self, r): + if not r: + raise TomlError('msg', self._pos[0], self._pos[1], self._filename) + return r + + def _advance(self, s): + suffix_pos = s.rfind('\n') + if suffix_pos == -1: + self._pos = (self._pos[0], self._pos[1] + len(s)) + else: + self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) + +_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') +def _p_ews(s): + s.expect_re(_ews_re) + +_ws_re = re.compile(r'[ \t]*') +def _p_ws(s): + s.expect_re(_ws_re) + +_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', + '\\': '\\', 'f': '\f' } + +_basicstr_re = re.compile(r'[^"\\\000-\037]*') +_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') +_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') +_escapes_re = re.compile(r'[btnfr\"\\]') +_newline_esc_re = re.compile('\n[ \t\n]*') +def _p_basicstr_content(s, content=_basicstr_re): + res = [] + while True: + res.append(s.expect_re(content).group(0)) + if not s.consume('\\'): + break + if s.consume_re(_newline_esc_re): + pass + elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): + v = int(s.last().group(1), 16) + if 0xd800 <= v < 0xe000: + s.fail() + res.append(_chr(v)) + else: + s.expect_re(_escapes_re) + res.append(_escapes[s.last().group(0)]) + return ''.join(res) + +_key_re = re.compile(r'[0-9a-zA-Z-_]+') +def _p_key(s): + with s: + s.expect('"') + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return r + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return r + return s.expect_re(_key_re).group(0) + +_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') + +_basicstr_ml_re = re.compile(r'(?:""?(?!")|[^"\\\000-\011\013-\037])*') +_litstr_re = re.compile(r"[^'\000\010\012-\037]*") +_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\010\013-\037]))*") +def _p_value(s, object_pairs_hook): + pos = s.pos() + + if s.consume('true'): + return 'bool', s.last(), True, pos + if s.consume('false'): + return 'bool', s.last(), False, pos + + if s.consume('"'): + if s.consume('""'): + r = _p_basicstr_content(s, _basicstr_ml_re) + s.expect('"""') + else: + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return 'str', r, r, pos + + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return 'str', r, r, pos + + if s.consume_re(rfc3339_re): + m = s.last() + return 'datetime', m.group(0), parse_rfc3339_re(m), pos + + if s.consume_re(_float_re): + m = s.last().group(0) + r = m.replace('_','') + if '.' in m or 'e' in m or 'E' in m: + return 'float', m, float(r), pos + else: + return 'int', m, int(r, 10), pos + + if s.consume('['): + items = [] + with s: + while True: + _p_ews(s) + items.append(_p_value(s, object_pairs_hook=object_pairs_hook)) + s.commit() + _p_ews(s) + s.expect(',') + s.commit() + _p_ews(s) + s.expect(']') + return 'array', None, items, pos + + if s.consume('{'): + _p_ws(s) + items = object_pairs_hook() + if not s.consume('}'): + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) + _p_ws(s) + while s.consume(','): + _p_ws(s) + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) + _p_ws(s) + s.expect('}') + return 'table', None, items, pos + + s.fail() + +def _p_stmt(s, object_pairs_hook): + pos = s.pos() + if s.consume( '['): + is_array = s.consume('[') + _p_ws(s) + keys = [_p_key(s)] + _p_ws(s) + while s.consume('.'): + _p_ws(s) + keys.append(_p_key(s)) + _p_ws(s) + s.expect(']') + if is_array: + s.expect(']') + return 'table_array' if is_array else 'table', keys, pos + + key = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + value = _p_value(s, object_pairs_hook=object_pairs_hook) + return 'kv', (key, value), pos + +_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') +def _p_toml(s, object_pairs_hook): + stmts = [] + _p_ews(s) + with s: + stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) + while True: + s.commit() + s.expect_re(_stmtsep_re) + stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) + _p_ews(s) + s.expect_eof() + return stmts diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/test.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/test.py new file mode 100755 index 0000000..ec8abfc --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/test.py @@ -0,0 +1,30 @@ +import datetime +from .utils import format_rfc3339 + +try: + _string_types = (str, unicode) + _int_types = (int, long) +except NameError: + _string_types = str + _int_types = int + +def translate_to_test(v): + if isinstance(v, dict): + return { k: translate_to_test(v) for k, v in v.items() } + if isinstance(v, list): + a = [translate_to_test(x) for x in v] + if v and isinstance(v[0], dict): + return a + else: + return {'type': 'array', 'value': a} + if isinstance(v, datetime.datetime): + return {'type': 'datetime', 'value': format_rfc3339(v)} + if isinstance(v, bool): + return {'type': 'bool', 'value': 'true' if v else 'false'} + if isinstance(v, _int_types): + return {'type': 'integer', 'value': str(v)} + if isinstance(v, float): + return {'type': 'float', 'value': '{:.17}'.format(v)} + if isinstance(v, _string_types): + return {'type': 'string', 'value': v} + raise RuntimeError('unexpected value: {!r}'.format(v)) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/utils.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/utils.py new file mode 100755 index 0000000..636a680 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/utils.py @@ -0,0 +1,67 @@ +import datetime +import re + +rfc3339_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') + +def parse_rfc3339(v): + m = rfc3339_re.match(v) + if not m or m.group(0) != v: + return None + return parse_rfc3339_re(m) + +def parse_rfc3339_re(m): + r = map(int, m.groups()[:6]) + if m.group(7): + micro = float(m.group(7)) + else: + micro = 0 + + if m.group(8): + g = int(m.group(8), 10) * 60 + int(m.group(9), 10) + tz = _TimeZone(datetime.timedelta(0, g * 60)) + else: + tz = _TimeZone(datetime.timedelta(0, 0)) + + y, m, d, H, M, S = r + return datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) + + +def format_rfc3339(v): + offs = v.utcoffset() + offs = int(offs.total_seconds()) // 60 if offs is not None else 0 + + if offs == 0: + suffix = 'Z' + else: + if offs > 0: + suffix = '+' + else: + suffix = '-' + offs = -offs + suffix = '{0}{1:02}:{2:02}'.format(suffix, offs // 60, offs % 60) + + if v.microsecond: + return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix + else: + return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix + +class _TimeZone(datetime.tzinfo): + def __init__(self, offset): + self._offset = offset + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return None + + def tzname(self, dt): + m = self._offset.total_seconds() // 60 + if m < 0: + res = '-' + m = -m + else: + res = '+' + h = m // 60 + m = m - h * 60 + return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/writer.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/writer.py new file mode 100755 index 0000000..73b5089 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/pytoml/writer.py @@ -0,0 +1,106 @@ +from __future__ import unicode_literals +import io, datetime, math, string, sys + +from .utils import format_rfc3339 + +if sys.version_info[0] == 3: + long = int + unicode = str + + +def dumps(obj, sort_keys=False): + fout = io.StringIO() + dump(obj, fout, sort_keys=sort_keys) + return fout.getvalue() + + +_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} + + +def _escape_string(s): + res = [] + start = 0 + + def flush(): + if start != i: + res.append(s[start:i]) + return i + 1 + + i = 0 + while i < len(s): + c = s[i] + if c in '"\\\n\r\t\b\f': + start = flush() + res.append('\\' + _escapes[c]) + elif ord(c) < 0x20: + start = flush() + res.append('\\u%04x' % ord(c)) + i += 1 + + flush() + return '"' + ''.join(res) + '"' + + +_key_chars = string.digits + string.ascii_letters + '-_' +def _escape_id(s): + if any(c not in _key_chars for c in s): + return _escape_string(s) + return s + + +def _format_value(v): + if isinstance(v, bool): + return 'true' if v else 'false' + if isinstance(v, int) or isinstance(v, long): + return unicode(v) + if isinstance(v, float): + if math.isnan(v) or math.isinf(v): + raise ValueError("{0} is not a valid TOML value".format(v)) + else: + return repr(v) + elif isinstance(v, unicode) or isinstance(v, bytes): + return _escape_string(v) + elif isinstance(v, datetime.datetime): + return format_rfc3339(v) + elif isinstance(v, list): + return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) + elif isinstance(v, dict): + return '{{{0}}}'.format(', '.join('{} = {}'.format(_escape_id(k), _format_value(obj)) for k, obj in v.items())) + else: + raise RuntimeError(v) + + +def dump(obj, fout, sort_keys=False): + tables = [((), obj, False)] + + while tables: + name, table, is_array = tables.pop() + if name: + section_name = '.'.join(_escape_id(c) for c in name) + if is_array: + fout.write('[[{0}]]\n'.format(section_name)) + else: + fout.write('[{0}]\n'.format(section_name)) + + table_keys = sorted(table.keys()) if sort_keys else table.keys() + new_tables = [] + has_kv = False + for k in table_keys: + v = table[k] + if isinstance(v, dict): + new_tables.append((name + (k,), v, False)) + elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): + new_tables.extend((name + (k,), d, True) for d in v) + elif v is None: + # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 + fout.write( + '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) + has_kv = True + else: + fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) + has_kv = True + + tables.extend(reversed(new_tables)) + + if (name or has_kv) and tables: + fout.write('\n') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__init__.py new file mode 100755 index 0000000..80c4ce1 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__init__.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. Basic GET +usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> 'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('https://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at <http://python-requests.org>. + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +from pip._vendor import urllib3 +from pip._vendor import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.24 + assert major == 1 + assert minor >= 21 + assert minor <= 24 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +def _check_cryptography(cryptography_version): + # cryptography < 1.3.4 + try: + cryptography_version = list(map(int, cryptography_version.split('.'))) + except ValueError: + return + + if cryptography_version < [1, 3, 4]: + warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version) + warnings.warn(warning, RequestsDependencyWarning) + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's SNI support, if possible +from pip._internal.utils.compat import WINDOWS +if not WINDOWS: + try: + from pip._vendor.urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() + + # Check cryptography version + from cryptography import __version__ as cryptography_version + _check_cryptography(cryptography_version) + except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +from logging import NullHandler + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__version__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__version__.py new file mode 100755 index 0000000..f5b5d03 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'http://python-requests.org' +__version__ = '2.21.0' +__build__ = 0x022100 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2018 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/_internal_utils.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/_internal_utils.py new file mode 100755 index 0000000..759d9a5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/adapters.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/adapters.py new file mode 100755 index 0000000..c30e7c9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/adapters.py @@ -0,0 +1,533 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url +from pip._vendor.urllib3.response import HTTPResponse +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.util import Timeout as TimeoutSauce +from pip._vendor.urllib3.util.retry import Retry +from pip._vendor.urllib3.exceptions import ClosedPoolError +from pip._vendor.urllib3.exceptions import ConnectTimeoutError +from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError +from pip._vendor.urllib3.exceptions import MaxRetryError +from pip._vendor.urllib3.exceptions import NewConnectionError +from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError +from pip._vendor.urllib3.exceptions import ProtocolError +from pip._vendor.urllib3.exceptions import ReadTimeoutError +from pip._vendor.urllib3.exceptions import SSLError as _SSLError +from pip._vendor.urllib3.exceptions import ResponseError +from pip._vendor.urllib3.exceptions import LocationValueError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths, + get_encoding_from_headers, prepend_scheme_if_needed, + get_auth_from_url, urldefragauth, select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema, InvalidProxyURL, + InvalidURL) +from .auth import _basic_auth_str + +try: + from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session <Session>` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response <requests.Response>` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` + + :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_url = parse_url(proxy) + if not proxy_url.host: + raise InvalidProxyURL("Please check proxy URL. It is malformed" + " and could be missing the host.") + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + try: + conn = self.get_connection(request.url, proxies) + except LocationValueError as e: + raise InvalidURL(e, request=request) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7, use buffering of HTTP responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 3.3+ + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/api.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/api.py new file mode 100755 index 0000000..abada96 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/api.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request <Request>`. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the body of the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response <Response>` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'https://httpbin.org/get') + <Response [200]> + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/auth.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/auth.py new file mode 100755 index 0000000..bdde51c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/auth.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(password), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + elif _algorithm == 'SHA-256': + def sha256_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha256(x).hexdigest() + hash_utf8 = sha256_utf8 + elif _algorithm == 'SHA-512': + def sha512_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha512(x).hexdigest() + hash_utf8 = sha512_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/requests/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/certs.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/certs.py new file mode 100755 index 0000000..06a594e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from pip._vendor.certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/compat.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/compat.py new file mode 100755 index 0000000..6a86893 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/compat.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +from pip._vendor import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +# Note: We've patched out simplejson support in pip because it prevents +# upgrading simplejson on Windows. +# try: +# import simplejson as json +# except (ImportError, SyntaxError): +# # simplejson does not support Python 3.2, it throws a SyntaxError +# # because of u'...' Unicode literals. +import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + from collections import Callable, Mapping, MutableMapping, OrderedDict + + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + from collections import OrderedDict + from collections.abc import Callable, Mapping, MutableMapping + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/cookies.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/cookies.py new file mode 100755 index 0000000..56fccd9 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/cookies.py @@ -0,0 +1,549 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.set_policy(self.get_policy()) + new_cj.update(self) + return new_cj + + def get_policy(self): + """Return the CookiePolicy instance used.""" + return self._policy + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = { + 'version': 0, + 'name': name, + 'value': value, + 'port': None, + 'domain': '', + 'path': '/', + 'secure': False, + 'expires': None, + 'discard': True, + 'comment': None, + 'comment_url': None, + 'rest': {'HttpOnly': None}, + 'rfc2109': False, + } + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + :rtype: CookieJar + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + :rtype: CookieJar + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/exceptions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/exceptions.py new file mode 100755 index 0000000..a91e1fd --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/exceptions.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class InvalidProxyURL(InvalidURL): + """The proxy URL provided is invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body""" + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + pass + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + pass + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/help.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/help.py new file mode 100755 index 0000000..3c3072b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/help.py @@ -0,0 +1,119 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +from pip._vendor import idna +from pip._vendor import urllib3 +from pip._vendor import chardet + +from . import __version__ as requests_version + +try: + from pip._vendor.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + system_ssl = ssl.OPENSSL_VERSION_NUMBER + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/hooks.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/hooks.py new file mode 100755 index 0000000..7a51f21 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return {event: [] for event in HOOKS} + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or {} + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/models.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/models.py new file mode 100755 index 0000000..0839957 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/models.py @@ -0,0 +1,953 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +import encodings.idna + +from pip._vendor.urllib3.fields import RequestField +from pip._vendor.urllib3.filepost import encode_multipart_formdata +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + Callable, Mapping, + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + elif hasattr(fp, 'read'): + fdata = fp.read() + elif fp is None: + continue + else: + fdata = fp + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request <Request>` object. + + Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: URL parameters to append to the URL. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> req.prepare() + <PreparedRequest [GET]> + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '<Request [%s]>' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request <Request>` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> r = req.prepare() + <PreparedRequest [GET]> + + >>> s = requests.Session() + >>> s.send(r) + <Response [200]> + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '<PreparedRequest [%s]>' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + from pip._vendor import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/requests/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response <Response>` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + # This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response <Response>` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '<Response [%s]>' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400, False if not. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/packages.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/packages.py new file mode 100755 index 0000000..9582fa7 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/packages.py @@ -0,0 +1,16 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + vendored_package = "pip._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): + unprefixed_mod = mod[len("pip._vendor."):] + sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/sessions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/sessions.py new file mode 100755 index 0000000..d73d700 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/sessions.py @@ -0,0 +1,770 @@ +# -*- coding: utf-8 -*- + +""" +requests.session +~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import sys +import time +from datetime import timedelta + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers, DEFAULT_PORTS +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if sys.platform == 'win32': + try: # Python 3.4+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def should_strip_auth(self, old_url, new_url): + """Decide whether Authorization header should be removed when redirecting""" + old_parsed = urlparse(old_url) + new_parsed = urlparse(new_url) + if old_parsed.hostname != new_parsed.hostname: + return True + # Special case: allow http -> https redirect when using the standard + # ports. This isn't specified by RFC 7235, but is kept to avoid + # breaking backwards compatibility with older versions of requests + # that allowed any redirects on the same host. + if (old_parsed.scheme == 'http' and old_parsed.port in (80, None) + and new_parsed.scheme == 'https' and new_parsed.port in (443, None)): + return False + + # Handle default port usage corresponding to scheme. + changed_port = old_parsed.port != new_parsed.port + changed_scheme = old_parsed.scheme != new_parsed.scheme + default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) + if (not changed_scheme and old_parsed.port in default_port + and new_parsed.port in default_port): + return False + + # Standard case: root URI must match + return changed_port or changed_scheme + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + previous_fragment = urlparse(req.url).fragment + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + + # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) + parsed = urlparse(url) + if parsed.fragment == '' and previous_fragment: + parsed = parsed._replace(fragment=previous_fragment) + elif parsed.fragment: + previous_fragment = parsed.fragment + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + try: + del headers['Cookie'] + except KeyError: + pass + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers and self.should_strip_auth(response.request.url, url): + # If we get redirected to a new host, we should strip out any + # authentication headers. + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # https://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('https://httpbin.org/get') + <Response [200]> + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('https://httpbin.org/get') + <Response [200]> + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request <Request>` sent from this + #: :class:`Session <Session>`. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request <Request>`. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request <Request>`. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request <Request>`. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request <Request>` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request <Request>`, prepares it and sends it. + Returns :class:`Response <Response>` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + + # Resolve redirects if allowed. + history = [resp for resp in gen] if allow_redirects else [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix.lower()): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = {attr: getattr(self, attr, None) for attr in self.__attrs__} + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + .. deprecated:: 1.0.0 + + This method has been deprecated since version 1.0.0 and is only kept for + backwards compatibility. New code should use :class:`~requests.sessions.Session` + to create a session. This may be removed at a future date. + + :rtype: Session + """ + return Session() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/status_codes.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/status_codes.py new file mode 100755 index 0000000..813e8c4 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/status_codes.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- + +r""" +The ``codes`` object defines a mapping from common names for HTTP statuses +to their numerical codes, accessible either as attributes or as dictionary +items. + +>>> requests.codes['temporary_redirect'] +307 +>>> requests.codes.teapot +418 +>>> requests.codes['\o/'] +200 + +Some codes have multiple names, and both upper- and lower-case versions of +the names are allowed. For example, ``codes.ok``, ``codes.OK``, and +``codes.okay`` all correspond to the HTTP status code 200. +""" + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +def _init(): + for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) + + def doc(code): + names = ', '.join('``%s``' % n for n in _codes[code]) + return '* %d: %s' % (code, names) + + global __doc__ + __doc__ = (__doc__ + '\n' + + '\n'.join(doc(code) for code in sorted(_codes)) + if __doc__ is not None else None) + +_init() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/structures.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/structures.py new file mode 100755 index 0000000..da930e2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/structures.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +from .compat import OrderedDict, Mapping, MutableMapping + + +class CaseInsensitiveDict(MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '<lookup \'%s\'>' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/utils.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/utils.py new file mode 100755 index 0000000..8170a8d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/requests/utils.py @@ -0,0 +1,977 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import codecs +import contextlib +import io +import os +import re +import socket +import struct +import sys +import tempfile +import warnings +import zipfile + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import to_native_string +from .compat import parse_http_list as _parse_list_header +from .compat import ( + quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment, Mapping) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + +DEFAULT_PORTS = {'http': 80, 'https': 443} + + +if sys.platform == 'win32': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + try: + if is_py3: + import winreg + else: + import _winreg as winreg + except ImportError: + return False + + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it + proxyEnable = int(winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0]) + # ProxyOverride is almost always a string + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See https://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def extract_zipped_paths(path): + """Replace nonexistent paths that look like they refer to a member of a zip + archive with the location of an extracted copy of the target, or else + just return the provided path unchanged. + """ + if os.path.exists(path): + # this is already a valid path, no need to do anything further + return path + + # find the first valid part of the provided path and treat that as a zip archive + # assume the rest of the path is the name of a member in the archive + archive, member = os.path.split(path) + while archive and not os.path.exists(archive): + archive, prefix = os.path.split(archive) + member = '/'.join([prefix, member]) + + if not zipfile.is_zipfile(archive): + return path + + zip_file = zipfile.ZipFile(archive) + if member not in zip_file.namelist(): + return path + + # we have a valid zip archive and a valid member of that archive + tmp = tempfile.gettempdir() + extracted_path = os.path.join(tmp, *member.split('/')) + if not os.path.exists(extracted_path): + extracted_path = zip_file.extract(member, path=tmp) + + return extracted_path + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) + pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def _parse_content_type_header(header): + """Returns content type and parameters from given header + + :param header: string + :return: tuple containing content type and dictionary of + parameters + """ + + tokens = header.split(';') + content_type, params = tokens[0].strip(), tokens[1:] + params_dict = {} + items_to_strip = "\"' " + + for param in params: + param = param.strip() + if param: + key, value = param, True + index_of_equals = param.find("=") + if index_of_equals != -1: + key = param[:index_of_equals].strip(items_to_strip) + value = param[index_of_equals + 1:].strip(items_to_strip) + params_dict[key.lower()] = value + return content_type, params_dict + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = _parse_content_type_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + # Prioritize lowercase environment variables over uppercase + # to keep a consistent behaviour with other http projects (curl, wget). + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + parsed = urlparse(url) + + if parsed.hostname is None: + # URLs don't always have hostnames, e.g. file:/// urls. + return True + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the hostname, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + if is_ipv4_address(parsed.hostname): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(parsed.hostname, proxy_ip): + return True + elif parsed.hostname == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + host_with_port = parsed.hostname + if parsed.port: + host_with_port += ':{}'.format(parsed.port) + + for host in no_proxy: + if parsed.hostname.endswith(host) or host_with_port.endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + with set_environ('no_proxy', no_proxy_arg): + # parsed.hostname can be `None` in cases such as a file URI. + try: + bypass = proxy_bypass(parsed.hostname) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a list of parsed link headers proxies. + + i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + value = value.strip(replace_chars) + if not value: + return links + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/retrying.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/retrying.py new file mode 100755 index 0000000..6d1e627 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/retrying.py @@ -0,0 +1,267 @@ +## Copyright 2013-2014 Ray Holder +## +## 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. + +import random +from pip._vendor import six +import sys +import time +import traceback + + +# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... +MAX_WAIT = 1073741823 + + +def retry(*dargs, **dkw): + """ + Decorator function that instantiates the Retrying object + @param *dargs: positional arguments passed to Retrying object + @param **dkw: keyword arguments passed to the Retrying object + """ + # support both @retry and @retry() as valid syntax + if len(dargs) == 1 and callable(dargs[0]): + def wrap_simple(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying().call(f, *args, **kw) + + return wrapped_f + + return wrap_simple(dargs[0]) + + else: + def wrap(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying(*dargs, **dkw).call(f, *args, **kw) + + return wrapped_f + + return wrap + + +class Retrying(object): + + def __init__(self, + stop=None, wait=None, + stop_max_attempt_number=None, + stop_max_delay=None, + wait_fixed=None, + wait_random_min=None, wait_random_max=None, + wait_incrementing_start=None, wait_incrementing_increment=None, + wait_exponential_multiplier=None, wait_exponential_max=None, + retry_on_exception=None, + retry_on_result=None, + wrap_exception=False, + stop_func=None, + wait_func=None, + wait_jitter_max=None): + + self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number + self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay + self._wait_fixed = 1000 if wait_fixed is None else wait_fixed + self._wait_random_min = 0 if wait_random_min is None else wait_random_min + self._wait_random_max = 1000 if wait_random_max is None else wait_random_max + self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start + self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment + self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier + self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max + self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max + + # TODO add chaining of stop behaviors + # stop behavior + stop_funcs = [] + if stop_max_attempt_number is not None: + stop_funcs.append(self.stop_after_attempt) + + if stop_max_delay is not None: + stop_funcs.append(self.stop_after_delay) + + if stop_func is not None: + self.stop = stop_func + + elif stop is None: + self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) + + else: + self.stop = getattr(self, stop) + + # TODO add chaining of wait behaviors + # wait behavior + wait_funcs = [lambda *args, **kwargs: 0] + if wait_fixed is not None: + wait_funcs.append(self.fixed_sleep) + + if wait_random_min is not None or wait_random_max is not None: + wait_funcs.append(self.random_sleep) + + if wait_incrementing_start is not None or wait_incrementing_increment is not None: + wait_funcs.append(self.incrementing_sleep) + + if wait_exponential_multiplier is not None or wait_exponential_max is not None: + wait_funcs.append(self.exponential_sleep) + + if wait_func is not None: + self.wait = wait_func + + elif wait is None: + self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) + + else: + self.wait = getattr(self, wait) + + # retry on exception filter + if retry_on_exception is None: + self._retry_on_exception = self.always_reject + else: + self._retry_on_exception = retry_on_exception + + # TODO simplify retrying by Exception types + # retry on result filter + if retry_on_result is None: + self._retry_on_result = self.never_reject + else: + self._retry_on_result = retry_on_result + + self._wrap_exception = wrap_exception + + def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the previous attempt >= stop_max_attempt_number.""" + return previous_attempt_number >= self._stop_max_attempt_number + + def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the time from the first attempt >= stop_max_delay.""" + return delay_since_first_attempt_ms >= self._stop_max_delay + + def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Don't sleep at all before retrying.""" + return 0 + + def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a fixed amount of time between each retry.""" + return self._wait_fixed + + def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a random amount of time between wait_random_min and wait_random_max""" + return random.randint(self._wait_random_min, self._wait_random_max) + + def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """ + Sleep an incremental amount of time after each attempt, starting at + wait_incrementing_start and incrementing by wait_incrementing_increment + """ + result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) + if result < 0: + result = 0 + return result + + def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + exp = 2 ** previous_attempt_number + result = self._wait_exponential_multiplier * exp + if result > self._wait_exponential_max: + result = self._wait_exponential_max + if result < 0: + result = 0 + return result + + def never_reject(self, result): + return False + + def always_reject(self, result): + return True + + def should_reject(self, attempt): + reject = False + if attempt.has_exception: + reject |= self._retry_on_exception(attempt.value[1]) + else: + reject |= self._retry_on_result(attempt.value) + + return reject + + def call(self, fn, *args, **kwargs): + start_time = int(round(time.time() * 1000)) + attempt_number = 1 + while True: + try: + attempt = Attempt(fn(*args, **kwargs), attempt_number, False) + except: + tb = sys.exc_info() + attempt = Attempt(tb, attempt_number, True) + + if not self.should_reject(attempt): + return attempt.get(self._wrap_exception) + + delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time + if self.stop(attempt_number, delay_since_first_attempt_ms): + if not self._wrap_exception and attempt.has_exception: + # get() on an attempt with an exception should cause it to be raised, but raise just in case + raise attempt.get() + else: + raise RetryError(attempt) + else: + sleep = self.wait(attempt_number, delay_since_first_attempt_ms) + if self._wait_jitter_max: + jitter = random.random() * self._wait_jitter_max + sleep = sleep + max(0, jitter) + time.sleep(sleep / 1000.0) + + attempt_number += 1 + + +class Attempt(object): + """ + An Attempt encapsulates a call to a target function that may end as a + normal return value from the function or an Exception depending on what + occurred during the execution. + """ + + def __init__(self, value, attempt_number, has_exception): + self.value = value + self.attempt_number = attempt_number + self.has_exception = has_exception + + def get(self, wrap_exception=False): + """ + Return the return value of this Attempt instance or raise an Exception. + If wrap_exception is true, this Attempt is wrapped inside of a + RetryError before being raised. + """ + if self.has_exception: + if wrap_exception: + raise RetryError(self) + else: + six.reraise(self.value[0], self.value[1], self.value[2]) + else: + return self.value + + def __repr__(self): + if self.has_exception: + return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) + else: + return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) + + +class RetryError(Exception): + """ + A RetryError encapsulates the last Attempt instance right before giving up. + """ + + def __init__(self, last_attempt): + self.last_attempt = last_attempt + + def __str__(self): + return "RetryError[{0}]".format(self.last_attempt) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/six.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/six.py new file mode 100755 index 0000000..89b2188 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/six.py @@ -0,0 +1,952 @@ +# Copyright (c) 2010-2018 Benjamin Peterson +# +# 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. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.12.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + if hasattr(cls, '__qualname__'): + orig_vars['__qualname__'] = cls.__qualname__ + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, text_type): + return s.encode(encoding, errors) + elif isinstance(s, binary_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if PY2 and isinstance(s, text_type): + s = s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + s = s.decode(encoding, errors) + return s + + +def ensure_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/__init__.py new file mode 100755 index 0000000..148a9c3 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/__init__.py @@ -0,0 +1,92 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +from __future__ import absolute_import +import warnings + +from .connectionpool import ( + HTTPConnectionPool, + HTTPSConnectionPool, + connection_from_url +) + +from . import exceptions +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry + + +# Set default logging handler to avoid "No handler found" warnings. +import logging +from logging import NullHandler + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '1.24.1' + +__all__ = ( + 'HTTPConnectionPool', + 'HTTPSConnectionPool', + 'PoolManager', + 'ProxyManager', + 'HTTPResponse', + 'Retry', + 'Timeout', + 'add_stderr_logger', + 'connection_from_url', + 'disable_warnings', + 'encode_multipart_formdata', + 'get_host', + 'make_headers', + 'proxy_from_url', +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # even if urllib3 is vendored within another package. + logger = logging.getLogger(__name__) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug('Added a stderr logging handler to logger: %s', __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# shouldn't be: otherwise, it's very hard for users to use most Python +# mechanisms to silence them. +# SecurityWarning's always go off by default. +warnings.simplefilter('always', exceptions.SecurityWarning, append=True) +# SubjectAltNameWarning's should go off once per host +warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) +# InsecurePlatformWarning's don't vary between requests, so we keep it default. +warnings.simplefilter('default', exceptions.InsecurePlatformWarning, + append=True) +# SNIMissingWarnings should go off only once. +warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/_collections.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/_collections.py new file mode 100755 index 0000000..34f2381 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/_collections.py @@ -0,0 +1,329 @@ +from __future__ import absolute_import +try: + from collections.abc import Mapping, MutableMapping +except ImportError: + from collections import Mapping, MutableMapping +try: + from threading import RLock +except ImportError: # Platform-specific: No threads available + class RLock: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + + +from collections import OrderedDict +from .exceptions import InvalidHeader +from .packages.six import iterkeys, itervalues, PY3 + + +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] + + +_Null = object() + + +class RecentlyUsedContainer(MutableMapping): + """ + Provides a thread-safe dict-like container which maintains up to + ``maxsize`` keys while throwing away the least-recently-used keys beyond + ``maxsize``. + + :param maxsize: + Maximum number of recent elements to retain. + + :param dispose_func: + Every time an item is evicted from the container, + ``dispose_func(value)`` is called. Callback which will get called + """ + + ContainerCls = OrderedDict + + def __init__(self, maxsize=10, dispose_func=None): + self._maxsize = maxsize + self.dispose_func = dispose_func + + self._container = self.ContainerCls() + self.lock = RLock() + + def __getitem__(self, key): + # Re-insert the item, moving it to the end of the eviction line. + with self.lock: + item = self._container.pop(key) + self._container[key] = item + return item + + def __setitem__(self, key, value): + evicted_value = _Null + with self.lock: + # Possibly evict the existing value of 'key' + evicted_value = self._container.get(key, _Null) + self._container[key] = value + + # If we didn't evict an existing value, we might have to evict the + # least recently used item from the beginning of the container. + if len(self._container) > self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ', '.join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + if not isinstance(other, Mapping) and not hasattr(other, 'keys'): + return False + if not isinstance(other, type(self)): + other = type(self)(other) + return (dict((k.lower(), v) for k, v in self.itermerged()) == + dict((k.lower(), v) for k, v in other.itermerged())) + + def __ne__(self, other): + return not self.__eq__(other) + + if not PY3: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + # Using the MutableMapping function directly fails due to the private marker. + # Using ordinary dict.pop would expose the internal structures. + # So let's reinvent the wheel. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + with self.add instead of self.__setitem__ + """ + if len(args) > 1: + raise TypeError("extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args))) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ', '.join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # python2.7 does not expose a proper API for exporting multiheaders + # efficiently. This function re-reads raw lines from the message + # object and extracts the multiheaders properly. + obs_fold_continued_leaders = (' ', '\t') + headers = [] + + for line in message.headers: + if line.startswith(obs_fold_continued_leaders): + if not headers: + # We received a header line that starts with OWS as described + # in RFC-7230 S3.2.4. This indicates a multiline header, but + # there exists no previous header to which we can attach it. + raise InvalidHeader( + 'Header continuation with no previous header: %s' % line + ) + else: + key, value = headers[-1] + headers[-1] = (key, value + ' ' + line.strip()) + continue + + key, value = line.split(':', 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connection.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connection.py new file mode 100755 index 0000000..02b3665 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connection.py @@ -0,0 +1,391 @@ +from __future__ import absolute_import +import datetime +import logging +import os +import socket +from socket import error as SocketError, timeout as SocketTimeout +import warnings +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +from .packages.six.moves.http_client import HTTPException # noqa: F401 + +try: # Compiled with SSL? + import ssl + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None + + class BaseSSLError(BaseException): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass + + +from .exceptions import ( + NewConnectionError, + ConnectTimeoutError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .packages.ssl_match_hostname import match_hostname, CertificateError + +from .util.ssl_ import ( + resolve_cert_reqs, + resolve_ssl_version, + assert_fingerprint, + create_urllib3_context, + ssl_wrap_socket +) + + +from .util import connection + +from ._collections import HTTPHeaderDict + +log = logging.getLogger(__name__) + +port_by_scheme = { + 'http': 80, + 'https': 443, +} + +# When updating RECENT_DATE, move it to within two years of the current date, +# and not less than 6 months ago. +# Example: if Today is 2018-01-01, then RECENT_DATE should be any date on or +# after 2016-01-01 (today - 2 years) AND before 2017-07-01 (today - 6 months) +RECENT_DATE = datetime.date(2017, 6, 30) + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + pass + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme['http'] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address. + self.source_address = kw.get('source_address') + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop('socket_options', self.default_socket_options) + + _HTTPConnection.__init__(self, *args, **kw) + + @property + def host(self): + """ + Getter method to remove any trailing dots that indicate the hostname is an FQDN. + + In general, SSL certificates don't include the trailing dot indicating a + fully-qualified domain name, and thus, they don't validate properly when + checked against a domain name that includes the dot. In addition, some + servers may not expect to receive the trailing dot when provided. + + However, the hostname with trailing dot is critical to DNS resolution; doing a + lookup with the trailing dot will properly only resolve the appropriate FQDN, + whereas a lookup without a trailing dot will search the system's search domain + list. Thus, it's important to keep the original host around for use only in + those cases where it's appropriate (i.e., when doing DNS lookup to establish the + actual TCP connection across which we're going to send HTTP requests). + """ + return self._dns_host.rstrip('.') + + @host.setter + def host(self, value): + """ + Setter for the `host` property. + + We assume that only urllib3 uses the _dns_host attribute; httplib itself + only uses `host`, and it seems reasonable that other libraries follow suit. + """ + self._dns_host = value + + def _new_conn(self): + """ Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = connection.create_connection( + (self._dns_host, self.port), self.timeout, **extra_kw) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except SocketError as e: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + def _prepare_conn(self, conn): + self.sock = conn + if self._tunnel_host: + # TODO: Fix tunnel so it doesn't depend on self.sock state. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + def request_chunked(self, method, url, body=None, headers=None): + """ + Alternative to the common request method, which sends the + body with chunked encoding and not as one block + """ + headers = HTTPHeaderDict(headers if headers is not None else {}) + skip_accept_encoding = 'accept-encoding' in headers + skip_host = 'host' in headers + self.putrequest( + method, + url, + skip_accept_encoding=skip_accept_encoding, + skip_host=skip_host + ) + for header, value in headers.items(): + self.putheader(header, value) + if 'transfer-encoding' not in headers: + self.putheader('Transfer-Encoding', 'chunked') + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (bytes,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, bytes): + chunk = chunk.encode('utf8') + len_str = hex(len(chunk))[2:] + self.send(len_str.encode('utf-8')) + self.send(b'\r\n') + self.send(chunk) + self.send(b'\r\n') + + # After the if clause, to always have a closed body + self.send(b'0\r\n\r\n') + + +class HTTPSConnection(HTTPConnection): + default_port = port_by_scheme['https'] + + ssl_version = None + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, server_hostname=None, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.ssl_context = ssl_context + self.server_hostname = server_hostname + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(None), + cert_reqs=resolve_cert_reqs(None), + ) + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ssl_context=self.ssl_context, + server_hostname=self.server_hostname + ) + + +class VerifiedHTTPSConnection(HTTPSConnection): + """ + Based on httplib.HTTPSConnection but wraps the socket with + SSL certification. + """ + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ssl_version = None + assert_fingerprint = None + + def set_cert(self, key_file=None, cert_file=None, + cert_reqs=None, ca_certs=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided, we can try to guess. If the user gave + # us a cert database, we assume they want to use it: otherwise, if + # they gave us an SSL Context object we should use whatever is set for + # it. + if cert_reqs is None: + if ca_certs or ca_cert_dir: + cert_reqs = 'CERT_REQUIRED' + elif self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ca_certs = ca_certs and os.path.expanduser(ca_certs) + self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + + def connect(self): + # Add certificate verification + conn = self._new_conn() + hostname = self.host + + if self._tunnel_host: + self.sock = conn + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + server_hostname = hostname + if self.server_hostname is not None: + server_hostname = self.server_hostname + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn(( + 'System time is way off (before {0}). This will probably ' + 'lead to SSL verification errors').format(RECENT_DATE), + SystemTimeWarning + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + server_hostname=server_hostname, + ssl_context=context) + + if self.assert_fingerprint: + assert_fingerprint(self.sock.getpeercert(binary_form=True), + self.assert_fingerprint) + elif context.verify_mode != ssl.CERT_NONE \ + and not getattr(context, 'check_hostname', False) \ + and self.assert_hostname is not False: + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = self.sock.getpeercert() + if not cert.get('subjectAltName', ()): + warnings.warn(( + 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' + '`commonName` for now. This feature is being removed by major browsers and ' + 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' + 'for details.)'.format(hostname)), + SubjectAltNameWarning + ) + _match_hostname(cert, self.assert_hostname or server_hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED or + self.assert_fingerprint is not None + ) + + +def _match_hostname(cert, asserted_hostname): + try: + match_hostname(cert, asserted_hostname) + except CertificateError as e: + log.error( + 'Certificate did not match expected hostname: %s. ' + 'Certificate: %s', asserted_hostname, cert + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +if ssl: + # Make a copy for testing. + UnverifiedHTTPSConnection = HTTPSConnection + HTTPSConnection = VerifiedHTTPSConnection +else: + HTTPSConnection = DummyConnection diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connectionpool.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connectionpool.py new file mode 100755 index 0000000..f7a8f19 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/connectionpool.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import +import errno +import logging +import sys +import warnings + +from socket import error as SocketError, timeout as SocketTimeout +import socket + + +from .exceptions import ( + ClosedPoolError, + ProtocolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + LocationValueError, + MaxRetryError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, + InsecureRequestWarning, + NewConnectionError, +) +from .packages.ssl_match_hostname import CertificateError +from .packages import six +from .packages.six.moves import queue +from .connection import ( + port_by_scheme, + DummyConnection, + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, +) +from .request import RequestMethods +from .response import HTTPResponse + +from .util.connection import is_connection_dropped +from .util.request import set_file_position +from .util.response import assert_header_parsing +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host, Url, NORMALIZABLE_SCHEMES +from .util.queue import LifoQueue + + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + """ + + scheme = None + QueueCls = LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _ipv6_host(host, self.scheme) + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return '%s(host=%r, port=%r)' % (type(self).__name__, + self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`httplib.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`httplib.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`httplib.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.connectionpool.ProxyManager`" + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + scheme = 'http' + ConnectionCls = HTTPConnection + ResponseCls = HTTPResponse + + def __init__(self, host, port=None, strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, + headers=None, retries=None, + _proxy=None, _proxy_headers=None, + **conn_kw): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault('socket_options', []) + + def _new_conn(self): + """ + Return a fresh :class:`HTTPConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTP connection (%d): %s:%s", + self.num_connections, self.host, self.port or "80") + + conn = self.ConnectionCls(host=self.host, port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + return conn + + def _get_conn(self, timeout=None): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + raise EmptyPoolError(self, + "Pool reached maximum size and no more " + "connections are allowed.") + pass # Oh well, we'll create a new connection then + + # If this is a persistent connection, check if it got disconnected + if conn and is_connection_dropped(conn): + log.debug("Resetting dropped connection: %s", self.host) + conn.close() + if getattr(conn, 'auto_open', 1) == 0: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s", + self.host) + + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """ Helper that always returns a :class:`urllib3.util.Timeout` """ + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, 'errno') and err.errno in _blocking_errnos: + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python < 2.7.4 + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + def _make_request(self, conn, method, url, timeout=_Default, chunked=False, + **httplib_request_kw): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + if getattr(conn, 'sock', None): + # In Python 3 socket.py will catch EAGAIN and return None when you + # try and read into the file pointer created by http.client, which + # instead raises a BadStatusLine exception. Instead of catching + # the exception and assuming all BadStatusLine exceptions are read + # timeouts, check for a zero timeout before making the request. + if read_timeout == 0: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % read_timeout) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: # Python 3 + try: + httplib_response = conn.getresponse() + except Exception as e: + # Remove the TypeError from the exception chain in Python 3; + # otherwise it looks like a programming error was the cause. + six.raise_from(e, None) + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) + raise + + # AppEngine doesn't have a version attr. + http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') + log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, + method, url, http_version, httplib_response.status, + httplib_response.length) + + try: + assert_header_parsing(httplib_response.msg) + except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 + log.warning( + 'Failed to parse headers (url=%s): %s', + self._absolute_url(url), hpe, exc_info=True) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + if self.pool is None: + return + # Disable access to the pool + old_pool, self.pool = self.pool, None + + try: + while True: + conn = old_pool.get(block=False) + if conn: + conn.close() + + except queue.Empty: + pass # Done. + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith('/'): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + + host = _ipv6_host(host, self.scheme) + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + return (scheme, host, port) == (self.scheme, self.host, self.port) + + def urlopen(self, method, url, body=None, headers=None, retries=None, + redirect=True, assert_same_host=True, timeout=_Default, + pool_timeout=None, release_conn=None, chunked=False, + body_pos=None, **response_kw): + """ + Get a connection from the pool and perform an HTTP request. This is the + lowest level call for making a request, so you'll need to specify all + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param body: + Data to send in the request body (useful for creating + POST requests, see HTTPConnectionPool.post_url for + more convenience). + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When False, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + release_conn = response_kw.get('preload_content', True) + + # Check host + if assert_same_host and not self.is_same_host(url): + raise HostChangedError(self, url, retries) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] <https://github.com/shazow/urllib3/issues/651> + release_this_conn = release_conn + + # Merge the proxy headers. Only do this in HTTP. We have to copy the + # headers dict so we can safely change it without those changes being + # reflected in anyone else's copy. + if self.scheme == 'http': + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + if is_new_proxy_conn: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. + httplib_response = self._make_request(conn, method, url, + timeout=timeout_obj, + body=body, headers=headers, + chunked=chunked) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + response_kw['request_method'] = method + + # Import httplib's response into our own wrapper object + response = self.ResponseCls.from_httplib(httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw) + + # Everything went great! + clean_exit = True + + except queue.Empty: + # Timed out by queue. + raise EmptyPoolError(self, "No pool connections are available.") + + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError, CertificateError) as e: + # Discard the connection for these exceptions. It will be + # replaced during the next _get_conn() call. + clean_exit = False + if isinstance(e, (BaseSSLError, CertificateError)): + e = SSLError(e) + elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: + e = ProxyError('Cannot connect to proxy.', e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) + + retries = retries.increment(method, url, error=e, _pool=self, + _stacktrace=sys.exc_info()[2]) + retries.sleep() + + # Keep track of the error for the retry warning. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + if not conn: + # Try again + log.warning("Retrying (%r) after connection " + "broken by '%r': %s", retries, err, url) + return self.urlopen(method, url, body, headers, retries, + redirect, assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + def drain_and_release_conn(response): + try: + # discard any remaining response body, the connection will be + # released back to the pool once the entire response is read + response.read() + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError) as e: + pass + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( + method, redirect_location, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(response.getheader('Retry-After')) + if retries.is_retry(method, response.status, has_retry_after): + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_status: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, url, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, + body_pos=body_pos, **response_kw) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + When Python is compiled with the :mod:`ssl` module, then + :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, + instead of :class:`.HTTPSConnection`. + + :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is + available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + scheme = 'https' + ConnectionCls = HTTPSConnection + + def __init__(self, host, port=None, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, + block=False, headers=None, retries=None, + _proxy=None, _proxy_headers=None, + key_file=None, cert_file=None, cert_reqs=None, + ca_certs=None, ssl_version=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None, **conn_kw): + + HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, + block, headers, retries, _proxy, _proxy_headers, + **conn_kw) + + if ca_certs and cert_reqs is None: + cert_reqs = 'CERT_REQUIRED' + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert(key_file=self.key_file, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint) + conn.ssl_version = self.ssl_version + return conn + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers) + conn.connect() + + def _new_conn(self): + """ + Return a fresh :class:`httplib.HTTPSConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTPS connection (%d): %s:%s", + self.num_connections, self.host, self.port or "443") + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError("Can't connect to HTTPS URL because the SSL " + "module is not available.") + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + actual_host = self.proxy.host + actual_port = self.proxy.port + + conn = self.ConnectionCls(host=actual_host, port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn(( + 'Unverified HTTPS request is being made. ' + 'Adding certificate verification is strongly advised. See: ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings'), + InsecureRequestWarning) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == 'https': + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host, scheme): + """ + Process IPv6 address literals + """ + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + if scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return host diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py new file mode 100755 index 0000000..f3e0094 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py @@ -0,0 +1,30 @@ +""" +This module provides means to detect the App Engine environment. +""" + +import os + + +def is_appengine(): + return (is_local_appengine() or + is_prod_appengine() or + is_prod_appengine_mvms()) + + +def is_appengine_sandbox(): + return is_appengine() and not is_prod_appengine_mvms() + + +def is_local_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) + + +def is_prod_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and + not is_prod_appengine_mvms()) + + +def is_prod_appengine_mvms(): + return os.environ.get('GAE_VM', False) == 'true' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py new file mode 100755 index 0000000..bcf41c0 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -0,0 +1,593 @@ +""" +This module uses ctypes to bind a whole bunch of functions and constants from +SecureTransport. The goal here is to provide the low-level API to +SecureTransport. These are essentially the C-level functions and constants, and +they're pretty gross to work with. + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + + Copyright (c) 2015-2016 Will Bond <will@wbond.net> + + 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. +""" +from __future__ import absolute_import + +import platform +from ctypes.util import find_library +from ctypes import ( + c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, + c_bool +) +from ctypes import CDLL, POINTER, CFUNCTYPE + + +security_path = find_library('Security') +if not security_path: + raise ImportError('The library Security could not be found') + + +core_foundation_path = find_library('CoreFoundation') +if not core_foundation_path: + raise ImportError('The library CoreFoundation could not be found') + + +version = platform.mac_ver()[0] +version_info = tuple(map(int, version.split('.'))) +if version_info < (10, 8): + raise OSError( + 'Only OS X 10.8 and newer are supported, not %s.%s' % ( + version_info[0], version_info[1] + ) + ) + +Security = CDLL(security_path, use_errno=True) +CoreFoundation = CDLL(core_foundation_path, use_errno=True) + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [ + CFAllocatorRef, + CFDataRef + ] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [ + SecCertificateRef + ] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef) + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef) + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [ + SecKeychainRef + ] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + POINTER(CFArrayRef) + ] + Security.SecPKCS12Import.restype = OSStatus + + SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) + + Security.SSLSetIOFuncs.argtypes = [ + SSLContextRef, + SSLReadFunc, + SSLWriteFunc + ] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [ + SSLContextRef, + CFArrayRef + ] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [ + SSLContextRef, + CFTypeRef, + Boolean + ] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [ + SSLContextRef, + SSLConnectionRef + ] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [ + SSLContextRef + ] + Security.SSLHandshake.restype = OSStatus + + Security.SSLRead.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLRead.restype = OSStatus + + Security.SSLWrite.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLWrite.restype = OSStatus + + Security.SSLClose.argtypes = [ + SSLContextRef + ] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite) + ] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol) + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [ + SSLContextRef, + POINTER(SecTrustRef) + ] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [ + SecTrustRef, + CFArrayRef + ] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ + SecTrustRef, + Boolean + ] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [ + SecTrustRef, + POINTER(SecTrustResultType) + ] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [ + SecTrustRef + ] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [ + SecTrustRef, + CFIndex + ] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [ + SSLContextRef, + SSLSessionOption, + Boolean + ] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, 'kSecImportExportPassphrase' + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, 'kSecImportItemIdentity' + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [ + CFStringRef, + CFStringEncoding + ] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [ + CFAllocatorRef, + c_char_p, + CFIndex + ] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [ + CFDictionaryRef, + CFTypeRef + ] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [ + CFMutableArrayRef, + c_void_p + ] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [ + CFArrayRef + ] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ + CFArrayRef, + CFIndex + ] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, 'kCFAllocatorDefault' + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError('Error initializing ctypes') + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py new file mode 100755 index 0000000..b13cd9e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,346 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import re +import os +import ssl +import tempfile + +from .bindings import Security, CoreFoundation, CFConst + + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + value_as_void_p, + CFConst.kCFStringEncodingUTF8 + ) + if string is None: + buffer = ctypes.create_string_buffer(1024) + result = CoreFoundation.CFStringGetCString( + value_as_void_p, + buffer, + 1024, + CFConst.kCFStringEncodingUTF8 + ) + if not result: + raise OSError('Error copying C string from CFStringRef') + string = buffer.value + if string is not None: + string = string.decode('utf-8') + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, None) + output = _cf_string_to_unicode(cf_error_string) + CoreFoundation.CFRelease(cf_error_string) + + if output is None or output == u'': + output = u'OSStatus %s' % error + + if exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + # Normalize the PEM bundle's line endings. + pem_bundle = pem_bundle.replace(b"\r\n", b"\n") + + der_certs = [ + base64.b64decode(match.group(1)) + for match in _PEM_CERTS_RE.finditer(pem_bundle) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # some random bytes to password-protect the keychain we're creating, so we + # ask for 40 random bytes. + random_bytes = os.urandom(40) + filename = base64.b16encode(random_bytes[:8]).decode('utf-8') + password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') + + # We now want to create the keychain itself. + keychain = Security.SecKeychainRef() + status = Security.SecKeychainCreate( + keychain_path, + len(password), + password, + False, + None, + ctypes.byref(keychain) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, 'rb') as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, + raw_filedata, + len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array) # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex( + result_array, index + ) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file( + keychain, file_path + ) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, + certificates[0], + ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py new file mode 100755 index 0000000..9b42952 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py @@ -0,0 +1,289 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + +Example usage:: + + from pip._vendor.urllib3 import PoolManager + from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations <https://cloud.google.com/appengine/docs/python/\ +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + <https://cloud.google.com/appengine/docs/python/sockets/\ + #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import +import io +import logging +import warnings +from ..packages.six.moves.urllib.parse import urljoin + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + TimeoutError, + SSLError +) + +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.timeout import Timeout +from ..util.retry import Retry +from . import _appengine_environ + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabtyes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + def __init__(self, headers=None, retries=None, validate_certificate=True, + urlfetch_retries=True): + if not urlfetch: + raise AppEnginePlatformError( + "URLFetch is not available in this environment.") + + if is_prod_appengine_mvms(): + raise AppEnginePlatformError( + "Use normal urllib3.PoolManager instead of AppEngineManager" + "on Managed VMs, as using URLFetch is not necessary in " + "this environment.") + + warnings.warn( + "urllib3 is using URLFetch on Google App Engine sandbox instead " + "of sockets. To use sockets directly instead of URLFetch see " + "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", + AppEnginePlatformWarning) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # Return False to re-raise any potential exceptions + return False + + def urlopen(self, method, url, body=None, headers=None, + retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = ( + redirect and + retries.redirect != 0 and + retries.total) + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if 'too large' in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", e) + raise ProtocolError(e) + + except urlfetch.DownloadError as e: + if 'Too many redirects' in str(e): + raise MaxRetryError(self, url, reason=e) + raise ProtocolError(e) + + except urlfetch.ResponseTooLargeError as e: + raise AppEnginePlatformError( + "URLFetch response too large, URLFetch only supports" + "responses up to 32mb in size.", e) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e) + + http_response = self._urlfetch_response_to_http_response( + response, retries=retries, **response_kw) + + # Handle redirect? + redirect_location = redirect and http_response.get_redirect_location() + if redirect_location: + # Check for redirect response + if (self.urlfetch_retries and retries.raise_on_redirect): + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=http_response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + log.debug("Redirecting %s -> %s", url, redirect_location) + redirect_url = urljoin(url, redirect_location) + return self.urlopen( + method, redirect_url, body, headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(http_response.getheader('Retry-After')) + if retries.is_retry(method, http_response.status, has_retry_after): + retries = retries.increment( + method, url, response=http_response, _pool=self) + log.debug("Retry: %s", url) + retries.sleep(http_response) + return self.urlopen( + method, url, + body=body, headers=headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + if is_prod_appengine(): + # Production GAE handles deflate encoding automatically, but does + # not remove the encoding header. + content_encoding = urlfetch_resp.headers.get('content-encoding') + + if content_encoding == 'deflate': + del urlfetch_resp.headers['content-encoding'] + + transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') + # We have a full response's content, + # so let's make sure we don't report ourselves as chunked data. + if transfer_encoding == 'chunked': + encodings = transfer_encoding.split(",") + encodings.remove('chunked') + urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) + + original_response = HTTPResponse( + # In order for decoding to work, we must present the content as + # a file-like object. + body=io.BytesIO(urlfetch_resp.content), + msg=urlfetch_resp.header_msg, + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + return HTTPResponse( + body=io.BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + original_response=original_response, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + AppEnginePlatformWarning) + return timeout.total + return timeout + + def _get_retries(self, retries, redirect): + if not isinstance(retries, Retry): + retries = Retry.from_int( + retries, redirect=redirect, default=self.retries) + + if retries.connect or retries.read or retries.redirect: + warnings.warn( + "URLFetch only supports total retries and does not " + "recognize connect, read, or redirect retry parameters.", + AppEnginePlatformWarning) + + return retries + + +# Alias methods from _appengine_environ to maintain public API interface. + +is_appengine = _appengine_environ.is_appengine +is_appengine_sandbox = _appengine_environ.is_appengine_sandbox +is_local_appengine = _appengine_environ.is_local_appengine +is_prod_appengine = _appengine_environ.is_prod_appengine +is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py new file mode 100755 index 0000000..8ea127c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -0,0 +1,111 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +from logging import getLogger +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = 'https' + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split('\\', 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # Performs the NTLM handshake that secures the connection. The socket + # must be kept open while requests are performed. + self.num_connections += 1 + log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', + self.num_connections, self.host, self.authurl) + + headers = {'Connection': 'Keep-Alive'} + req_header = 'Authorization' + resp_header = 'www-authenticate' + + conn = HTTPSConnection(host=self.host, port=self.port) + + # Send negotiation message + headers[req_header] = ( + 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + reshdr = dict(res.getheaders()) + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', reshdr) + log.debug('Response data: %s [...]', res.read(100)) + + # Remove the reference to the socket, so that it can not be closed by + # the response object (we want to keep the socket open) + res.fp = None + + # Server should respond with a challenge message + auth_header_values = reshdr[resp_header].split(', ') + auth_header_value = None + for s in auth_header_values: + if s[:5] == 'NTLM ': + auth_header_value = s[5:] + if auth_header_value is None: + raise Exception('Unexpected %s response header: %s' % + (resp_header, reshdr[resp_header])) + + # Send authentication message + ServerChallenge, NegotiateFlags = \ + ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, + self.user, + self.domain, + self.pw, + NegotiateFlags) + headers[req_header] = 'NTLM %s' % auth_msg + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', dict(res.getheaders())) + log.debug('Response data: %s [...]', res.read()[:100]) + if res.status != 200: + if res.status == 401: + raise Exception('Server rejected request: wrong ' + 'username or password') + raise Exception('Wrong server response: %s %s' % + (res.status, res.reason)) + + res.fp = None + log.debug('Connection established') + return conn + + def urlopen(self, method, url, body=None, headers=None, retries=3, + redirect=True, assert_same_host=True): + if headers is None: + headers = {} + headers['Connection'] = 'Keep-Alive' + return super(NTLMConnectionPool, self).urlopen(method, url, body, + headers, retries, + redirect, + assert_same_host) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py new file mode 100755 index 0000000..363667c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -0,0 +1,466 @@ +""" +SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* pyOpenSSL (tested with 16.0.0) +* cryptography (minimum 1.3.4, from pyopenssl) +* idna (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + + pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +If you want to configure the default list of supported cipher suites, you can +set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +""" +from __future__ import absolute_import + +import OpenSSL.SSL +from cryptography import x509 +from cryptography.hazmat.backends.openssl import backend as openssl_backend +from cryptography.hazmat.backends.openssl.x509 import _Certificate +try: + from cryptography.x509 import UnsupportedExtension +except ImportError: + # UnsupportedExtension is gone in cryptography >= 2.1.0 + class UnsupportedExtension(Exception): + pass + +from socket import timeout, error as SocketError +from io import BytesIO + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +from ..packages import six +import sys + +from .. import util + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, +} + +if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD + +if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + +try: + _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) +except AttributeError: + pass + +_stdlib_to_openssl_verify = { + ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, + ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, + ssl.CERT_REQUIRED: + OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, +} +_openssl_to_stdlib_verify = dict( + (v, k) for k, v in _stdlib_to_openssl_verify.items() +) + +# OpenSSL will only write 16K at a time +SSL_WRITE_BLOCKSIZE = 16384 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + + _validate_dependencies_met() + + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + 'Undo monkey-patching by :func:`inject_into_urllib3`.' + + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError("'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer.") + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError("'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer.") + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + + If the name cannot be idna-encoded then we return None signalling that + the name given should be skipped. + """ + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + from pip._vendor import idna + + try: + for prefix in [u'*.', u'.']: + if name.startswith(prefix): + name = name[len(prefix):] + return prefix.encode('ascii') + idna.encode(name) + return idna.encode(name) + except idna.core.IDNAError: + return None + + name = idna_encode(name) + if name is None: + return None + elif sys.version_info >= (3, 0): + name = name.decode('utf-8') + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + # This is technically using private APIs, but should work across all + # relevant versions before PyOpenSSL got a proper API for this. + cert = _Certificate(openssl_backend, peer_cert._x509) + + # We want to find the SAN extension. Ask Cryptography to locate it (it's + # faster than looping in Python) + try: + ext = cert.extensions.get_extension_for_class( + x509.SubjectAlternativeName + ).value + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + except (x509.DuplicateExtension, UnsupportedExtension, + x509.UnsupportedGeneralNameType, UnicodeError) as e: + # A problem has been found with the quality of the certificate. Assume + # no SAN field is present. + log.warning( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + # We also want to skip over names which cannot be idna encoded. + names = [ + ('DNS', name) for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) + if name is not None + ] + names.extend( + ('IP Address', str(name)) + for name in ext.get_values_for_type(x509.IPAddress) + ) + + return names + + +class WrappedSocket(object): + '''API-compatibility wrapper for Python OpenSSL's Connection-class. + + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + ''' + + def __init__(self, connection, socket, suppress_ragged_eofs=True): + self.connection = connection + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return b'' + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout('The read operation timed out') + else: + return self.recv(*args, **kwargs) + else: + return data + + def recv_into(self, *args, **kwargs): + try: + return self.connection.recv_into(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout('The read operation timed out') + else: + return self.recv_into(*args, **kwargs) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + if not util.wait_for_write(self.socket, self.socket.gettimeout()): + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_ASN1, + x509) + + return { + 'subject': ( + (('commonName', x509.get_subject().CN),), + ), + 'subjectAltName': get_subj_alt_name(x509) + } + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + makefile = backport_makefile + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + for translating the interface of the standard library ``SSLContext`` object + to calls into PyOpenSSL. + """ + def __init__(self, protocol): + self.protocol = _openssl_versions[protocol] + self._ctx = OpenSSL.SSL.Context(self.protocol) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + self._ctx.set_verify( + _stdlib_to_openssl_verify[value], + _verify_callback + ) + + def set_default_verify_paths(self): + self._ctx.set_default_verify_paths() + + def set_ciphers(self, ciphers): + if isinstance(ciphers, six.text_type): + ciphers = ciphers.encode('utf-8') + self._ctx.set_cipher_list(ciphers) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + if cafile is not None: + cafile = cafile.encode('utf-8') + if capath is not None: + capath = capath.encode('utf-8') + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_chain_file(certfile) + if password is not None: + self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password) + self._ctx.use_privatekey_file(keyfile or certfile) + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + cnx = OpenSSL.SSL.Connection(self._ctx, sock) + + if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 + server_hostname = server_hostname.encode('utf-8') + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(sock, sock.gettimeout()): + raise timeout('select timed out') + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError('bad handshake: %r' % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py new file mode 100755 index 0000000..77cb59e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py @@ -0,0 +1,804 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import threading +import weakref + +from .. import util +from ._securetransport.bindings import ( + Security, SecurityConst, CoreFoundation +) +from ._securetransport.low_level import ( + _assert_no_error, _cert_array_from_pem, _temporary_keychain, + _load_client_cert_chain +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this because this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +_protocol_to_min_max = { + ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + ) +if hasattr(ssl, "PROTOCOL_TLS"): + _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + + try: + while read_count < requested_length: + if timeout is None or timeout >= 0: + if not util.wait_for_read(base_socket, timeout): + raise socket.error(errno.EAGAIN, 'timed out') + + remaining = requested_length - read_count + buffer = (ctypes.c_char * remaining).from_address( + data_buffer + read_count + ) + chunk_size = base_socket.recv_into(buffer, remaining) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = read_count + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + while sent < bytes_to_write: + if timeout is None or timeout >= 0: + if not util.wait_for_write(base_socket, timeout): + raise socket.error(errno.EAGAIN, 'timed out') + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = sent + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket object. + + Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage + collector of PyPy. + """ + def __init__(self, socket): + self.socket = socket + self.context = None + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, 'rb') as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # created for this connection, shove our CAs into it, tell ST to + # ignore everything else it knows, and then ask if it can build a + # chain. This is a buuuunch of code. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate( + trust, ctypes.byref(trust_result) + ) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is not None: + CoreFoundation.CFRelease(cert_array) + + # Ok, now we can look at what the result was. + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed + ) + if trust_result.value not in successes: + raise ssl.SSLError( + "certificate verify failed, error code: %d" % + trust_result.value + ) + + def handshake(self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # If we have a server hostname, we should set that too. + if server_hostname: + if not isinstance(server_hostname, bytes): + server_hostname = server_hostname.encode('utf-8') + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, + SecurityConst.kSSLSessionOptionBreakOnServerAuth, + True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate( + self.context, self._client_cert_chain + ) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # There are some result codes that we want to treat as "not always + # errors". Specifically, those are errSSLWouldBlock, + # errSSLClosedGraceful, and errSSLClosedNoNotify. + if (result == SecurityConst.errSSLWouldBlock): + # If we didn't process any bytes, then this was just a time out. + # However, we can get errSSLWouldBlock in situations when we *did* + # read some data, and in those cases we should just read "short" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): + # The remote peer has closed this connection. We should do so as + # well. Note that we don't actually return here because in + # principle this could actually be fired along with return data. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # instead to just flag to urllib3 that it shouldn't do its own hostname + # validation when using SecureTransport. + if not binary_form: + raise ValueError( + "SecureTransport only supports dumping binary certs" + ) + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + # Probably we haven't done the handshake yet. No biggie. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + def makefile(self, mode="r", buffering=None, *args, **kwargs): + # We disable buffering with SecureTransport because it conflicts with + # the buffering that ST does internally (see issue #1153 for more). + buffering = 0 + return backport_makefile(self, mode, buffering, *args, **kwargs) + +WrappedSocket.makefile = makefile + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + interface of the standard library ``SSLContext`` object to calls into + SecureTransport. + """ + def __init__(self, protocol): + self._min_version, self._max_version = _protocol_to_min_max[protocol] + self._options = 0 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + def set_ciphers(self, ciphers): + # For now, we just require the default cipher string. + if ciphers != util.ssl_.DEFAULT_CIPHERS: + raise ValueError( + "SecureTransport doesn't support custom cipher strings" + ) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + # OK, we only really support cadata and cafile. + if capath is not None: + raise ValueError( + "SecureTransport does not support cert directories" + ) + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + self._client_key = keyfile + self._client_cert_passphrase = password + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + # So, what do we do here? Firstly, we assert some properties. This is a + # stripped down shim, so there is some functionality we don't support. + # See PEP 543 for the real deal. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # Now we can handshake + wrapped_socket.handshake( + server_hostname, self._verify, self._trust_bundle, + self._min_version, self._max_version, self._client_cert, + self._client_key, self._client_key_passphrase + ) + return wrapped_socket diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py new file mode 100755 index 0000000..811e312 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4 +- SOCKS4a +- SOCKS5 +- Usernames and passwords for the SOCKS proxy + +Known Limitations: + +- Currently PySocks does not support contacting remote websites via literal + IPv6 addresses. Any such connection attempt will fail. You must use a domain + name. +- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any + such connection attempt will fail. +""" +from __future__ import absolute_import + +try: + import socks +except ImportError: + import warnings + from ..exceptions import DependencyWarning + + warnings.warn(( + 'SOCKS support in urllib3 requires the installation of optional ' + 'dependencies: specifically, PySocks. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' + ), + DependencyWarning + ) + raise + +from socket import error as SocketError, timeout as SocketTimeout + +from ..connection import ( + HTTPConnection, HTTPSConnection +) +from ..connectionpool import ( + HTTPConnectionPool, HTTPSConnectionPool +) +from ..exceptions import ConnectTimeoutError, NewConnectionError +from ..poolmanager import PoolManager +from ..util.url import parse_url + +try: + import ssl +except ImportError: + ssl = None + + +class SOCKSConnection(HTTPConnection): + """ + A plain-text HTTP connection that connects via a SOCKS proxy. + """ + def __init__(self, *args, **kwargs): + self._socks_options = kwargs.pop('_socks_options') + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = socks.create_connection( + (self.host, self.port), + proxy_type=self._socks_options['socks_version'], + proxy_addr=self._socks_options['proxy_host'], + proxy_port=self._socks_options['proxy_port'], + proxy_username=self._socks_options['username'], + proxy_password=self._socks_options['password'], + proxy_rdns=self._socks_options['rdns'], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except socks.ProxyError as e: + # This is fragile as hell, but it seems to be the only way to raise + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout) + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % e + ) + + except SocketError as e: # Defensive: PySocks should catch all these. + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +class SOCKSProxyManager(PoolManager): + """ + A version of the urllib3 ProxyManager that routes connections via the + defined SOCKS proxy. + """ + pool_classes_by_scheme = { + 'http': SOCKSHTTPConnectionPool, + 'https': SOCKSHTTPSConnectionPool, + } + + def __init__(self, proxy_url, username=None, password=None, + num_pools=10, headers=None, **connection_pool_kw): + parsed = parse_url(proxy_url) + + if username is None and password is None and parsed.auth is not None: + split = parsed.auth.split(':') + if len(split) == 2: + username, password = split + if parsed.scheme == 'socks5': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == 'socks4': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + raise ValueError( + "Unable to determine SOCKS version from %s" % proxy_url + ) + + self.proxy_url = proxy_url + + socks_options = { + 'socks_version': socks_version, + 'proxy_host': parsed.host, + 'proxy_port': parsed.port, + 'username': username, + 'password': password, + 'rdns': rdns + } + connection_pool_kw['_socks_options'] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/exceptions.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/exceptions.py new file mode 100755 index 0000000..7bbaa98 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/exceptions.py @@ -0,0 +1,246 @@ +from __future__ import absolute_import +from .packages.six.moves.http_client import ( + IncompleteRead as httplib_IncompleteRead +) +# Base Exceptions + + +class HTTPError(Exception): + "Base exception used by this module." + pass + + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + +class PoolError(HTTPError): + "Base exception for errors caused within a pool." + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + "Raised when we fail to establish a new connection. Usually ECONNREFUSED." + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when performing security reducing actions" + pass + + +class SubjectAltNameWarning(SecurityWarning): + "Warned when connecting to a host with a certificate missing a SAN." + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class SNIMissingWarning(HTTPWarning): + "Warned when making a HTTPS request without SNI available." + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be httplib.HTTPResponse like (have an fp attribute which + returns raw chunks) for read_chunked(). + """ + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of http_client.IncompleteRead to allow int value + for `partial` to avoid creating large objects on streamed + reads. + """ + def __init__(self, partial, expected): + super(IncompleteRead, self).__init__(partial, expected) + + def __repr__(self): + return ('IncompleteRead(%i bytes read, ' + '%i more expected)' % (self.partial, self.expected)) + + +class InvalidHeader(HTTPError): + "The header provided was somehow invalid." + pass + + +class ProxySchemeUnknown(AssertionError, ValueError): + "ProxyManager does not support the supplied scheme" + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + message = "Not supported proxy scheme %s" % scheme + super(ProxySchemeUnknown, self).__init__(message) + + +class HeaderParsingError(HTTPError): + "Raised by assert_header_parsing, but we convert it to a log.warning statement." + def __init__(self, defects, unparsed_data): + message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/fields.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/fields.py new file mode 100755 index 0000000..37fe64a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/fields.py @@ -0,0 +1,178 @@ +from __future__ import absolute_import +import email.utils +import mimetypes + +from .packages import six + + +def guess_content_type(filename, default='application/octet-stream'): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param(name, value): + """ + Helper function to format and quote a single header parameter. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows RFC 2231, as + suggested by RFC 2388 Section 4.4. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value = email.utils.encode_rfc2231(value, 'utf-8') + value = '%s*=%s' % (name, value) + return value + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. + :param headers: + An optional dict-like object of headers to initially use for the field. + """ + def __init__(self, name, data, filename=None, headers=None): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + + @classmethod + def from_tuples(cls, fieldname, value): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls(fieldname, data, filename=filename) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + return format_header_param(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return '; '.join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append('%s: %s' % (sort_key, self.headers[sort_key])) + + for header_name, header_value in self.headers.items(): + if header_name not in sort_keys: + if header_value: + lines.append('%s: %s' % (header_name, header_value)) + + lines.append('\r\n') + return '\r\n'.join(lines) + + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers['Content-Disposition'] = content_disposition or 'form-data' + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) + self.headers['Content-Type'] = content_type + self.headers['Content-Location'] = content_location diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/filepost.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/filepost.py new file mode 100755 index 0000000..78f1e19 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/filepost.py @@ -0,0 +1,98 @@ +from __future__ import absolute_import +import binascii +import codecs +import os + +from io import BytesIO + +from .packages import six +from .packages.six import b +from .fields import RequestField + +writer = codecs.lookup('utf-8')[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + boundary = binascii.hexlify(os.urandom(16)) + if six.PY3: + boundary = boundary.decode('ascii') + return boundary + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`urllib3.filepost.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b('--%s\r\n' % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b'\r\n') + + body.write(b('--%s--\r\n' % (boundary))) + + content_type = str('multipart/form-data; boundary=%s' % boundary) + + return body.getvalue(), content_type diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py new file mode 100755 index 0000000..170e974 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from . import ssl_match_hostname + +__all__ = ('ssl_match_hostname', ) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py new file mode 100755 index 0000000..740db37 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io + +from socket import SocketIO + + +def backport_makefile(self, mode="r", buffering=None, encoding=None, + errors=None, newline=None): + """ + Backport of ``socket.makefile`` from Python 3.5. + """ + if not set(mode) <= {"r", "w", "b"}: + raise ValueError( + "invalid mode %r (only r, w, b allowed)" % (mode,) + ) + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/six.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/six.py new file mode 100755 index 0000000..190c023 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# 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. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py new file mode 100755 index 0000000..d6594eb --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -0,0 +1,19 @@ +import sys + +try: + # Our match_hostname function is the same as 3.5's, so we only want to + # import the match_hostname function if it's at least that good. + if sys.version_info < (3, 5): + raise ImportError("Fallback to vendored code") + + from ssl import CertificateError, match_hostname +except ImportError: + try: + # Backport of the function from a pypi module + from backports.ssl_match_hostname import CertificateError, match_hostname + except ImportError: + # Our vendored copy + from ._implementation import CertificateError, match_hostname + +# Not needed, but documenting what we provide. +__all__ = ('CertificateError', 'match_hostname') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py new file mode 100755 index 0000000..970cf65 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -0,0 +1,156 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# backports.ssl_match_hostname to continue to be used in Python 2.7. +try: + from pip._vendor import ipaddress +except ImportError: + ipaddress = None + +__version__ = '3.5.0.1' + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + obj = unicode(obj, encoding='ascii', errors='strict') + return obj + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except ValueError: + # Not an IP address (common case) + host_ip = None + except UnicodeError: + # Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: + raise + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/poolmanager.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/poolmanager.py new file mode 100755 index 0000000..fe5491c --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/poolmanager.py @@ -0,0 +1,450 @@ +from __future__ import absolute_import +import collections +import functools +import logging + +from ._collections import RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connectionpool import port_by_scheme +from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.url import parse_url +from .util.retry import Retry + + +__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] + + +log = logging.getLogger(__name__) + +SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', + 'ssl_version', 'ca_cert_dir', 'ssl_context') + +# All known keyword arguments that could be provided to the pool manager, its +# pools, or the underlying connections. This is used to construct a pool key. +_key_fields = ( + 'key_scheme', # str + 'key_host', # str + 'key_port', # int + 'key_timeout', # int or float or Timeout + 'key_retries', # int or Retry + 'key_strict', # bool + 'key_block', # bool + 'key_source_address', # str + 'key_key_file', # str + 'key_cert_file', # str + 'key_cert_reqs', # str + 'key_ca_certs', # str + 'key_ssl_version', # str + 'key_ca_cert_dir', # str + 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + 'key_maxsize', # int + 'key_headers', # dict + 'key__proxy', # parsed proxy url + 'key__proxy_headers', # dict + 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples + 'key__socks_options', # dict + 'key_assert_hostname', # bool or string + 'key_assert_fingerprint', # str + 'key_server_hostname', #str +) + +#: The namedtuple class used to construct keys for the connection pool. +#: All custom key schemes should include the fields in this key at a minimum. +PoolKey = collections.namedtuple('PoolKey', _key_fields) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + context['scheme'] = context['scheme'].lower() + context['host'] = context['host'].lower() + + # These are both dictionaries and need to be transformed into frozensets + for key in ('headers', '_proxy_headers', '_socks_options'): + if key in context and context[key] is not None: + context[key] = frozenset(context[key].items()) + + # The socket_options key may be a list and needs to be transformed into a + # tuple. + socket_opts = context.get('socket_options') + if socket_opts is not None: + context['socket_options'] = tuple(socket_opts) + + # Map the kwargs to the names in the namedtuple - this is necessary since + # namedtuples can't have fields starting with '_'. + for key in list(context.keys()): + context['key_' + key] = context.pop(key) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: Each PoolManager makes a copy of this dictionary so they can be configured +#: globally here, or individually on the instance. +key_fn_by_scheme = { + 'http': functools.partial(_default_key_normalizer, PoolKey), + 'https': functools.partial(_default_key_normalizer, PoolKey), +} + +pool_classes_by_scheme = { + 'http': HTTPConnectionPool, + 'https': HTTPSConnectionPool, +} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + + def __init__(self, num_pools=10, headers=None, **connection_pool_kw): + RequestMethods.__init__(self, headers) + self.connection_pool_kw = connection_pool_kw + self.pools = RecentlyUsedContainer(num_pools, + dispose_func=lambda p: p.close()) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # this function has historically only used the scheme, host, and port + # in the positional args. When an API change is acceptable these can + # be removed. + for key in ('scheme', 'host', 'port'): + request_context.pop(key, None) + + if scheme == 'http': + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + """ + Get a :class:`ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + request_context['scheme'] = scheme or 'http' + if not port: + port = port_by_scheme.get(request_context['scheme'].lower(), 80) + request_context['port'] = port + request_context['host'] = host + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`ConnectionPool` based on the request context. + + ``request_context`` must at least contain the ``scheme`` key and its + value must be a key in ``key_fn_by_scheme`` instance variable. + """ + scheme = request_context['scheme'].lower() + pool_key_constructor = self.key_fn_by_scheme[scheme] + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + scheme = request_context['scheme'] + host = request_context['host'] + port = request_context['port'] + pool = self._new_pool(scheme, host, port, request_context=request_context) + self.pools[pool_key] = pool + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, + pool_kwargs=pool_kwargs) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + u = parse_url(url) + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) + + kw['assert_same_host'] = False + kw['redirect'] = False + + if 'headers' not in kw: + kw['headers'] = self.headers.copy() + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + # RFC 7231, Section 6.4.4 + if response.status == 303: + method = 'GET' + + retries = kw.get('retries') + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + # Strip headers marked as unsafe to forward to the redirected location. + # Check remove_headers_on_redirect to avoid a potential network call within + # conn.is_same_host() which may use socket.gethostbyname() in the future. + if (retries.remove_headers_on_redirect + and not conn.is_same_host(redirect_location)): + for header in retries.remove_headers_on_redirect: + kw['headers'].pop(header, None) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + + kw['retries'] = retries + kw['redirect'] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary containing headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + def __init__(self, proxy_url, num_pools=10, headers=None, + proxy_headers=None, **connection_pool_kw): + + if isinstance(proxy_url, HTTPConnectionPool): + proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, + proxy_url.port) + proxy = parse_url(proxy_url) + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + + connection_pool_kw['_proxy'] = self.proxy + connection_pool_kw['_proxy_headers'] = self.proxy_headers + + super(ProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw) + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + if scheme == "https": + return super(ProxyManager, self).connection_from_host( + host, port, scheme, pool_kwargs=pool_kwargs) + + return super(ProxyManager, self).connection_from_host( + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) + + def _set_proxy_headers(self, url, headers=None): + """ + Sets headers needed by proxies: specifically, the Accept and Host + headers. Only sets headers not provided by the user. + """ + headers_ = {'Accept': '*/*'} + + netloc = parse_url(url).netloc + if netloc: + headers_['Host'] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + + if u.scheme == "http": + # For proxied HTTPS requests, httplib sets the necessary headers + # on the CONNECT to the proxy. For HTTP, we'll definitely + # need to set 'Host' at the very least. + headers = kw.get('headers', self.headers) + kw['headers'] = self._set_proxy_headers(url, headers) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/request.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/request.py new file mode 100755 index 0000000..8f2f44b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/request.py @@ -0,0 +1,150 @@ +from __future__ import absolute_import + +from .filepost import encode_multipart_formdata +from .packages.six.moves.urllib.parse import urlencode + + +__all__ = ['RequestMethods'] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`~urllib3.connectionpool.HTTPConnectionPool` and + :class:`~urllib3.poolmanager.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'} + + def __init__(self, headers=None): + self.headers = headers or {} + + def urlopen(self, method, url, body=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **kw): # Abstract + raise NotImplementedError("Classes extending RequestMethods must implement " + "their own ``urlopen`` method.") + + def request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + urlopen_kw['request_url'] = url + + if method in self._encode_url_methods: + return self.request_encode_url(method, url, fields=fields, + headers=headers, + **urlopen_kw) + else: + return self.request_encode_body(method, url, fields=fields, + headers=headers, + **urlopen_kw) + + def request_encode_url(self, method, url, fields=None, headers=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': headers} + extra_kw.update(urlopen_kw) + + if fields: + url += '?' + urlencode(fields) + + return self.urlopen(method, url, **extra_kw) + + def request_encode_body(self, method, url, fields=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :meth:`urllib.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimic behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError( + "request got values for both 'fields' and 'body', can only specify one.") + + if encode_multipart: + body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/response.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/response.py new file mode 100755 index 0000000..c112690 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/response.py @@ -0,0 +1,705 @@ +from __future__ import absolute_import +from contextlib import contextmanager +import zlib +import io +import logging +from socket import timeout as SocketTimeout +from socket import error as SocketError + +from ._collections import HTTPHeaderDict +from .exceptions import ( + BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, + ResponseNotChunked, IncompleteRead, InvalidHeader +) +from .packages.six import string_types as basestring, PY3 +from .packages.six.moves import http_client as httplib +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + + def __init__(self): + self._first_try = True + self._data = b'' + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoderState(object): + + FIRST_MEMBER = 0 + OTHER_MEMBERS = 1 + SWALLOW_DATA = 2 + + +class GzipDecoder(object): + + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + self._state = GzipDecoderState.FIRST_MEMBER + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + ret = bytearray() + if self._state == GzipDecoderState.SWALLOW_DATA or not data: + return bytes(ret) + while True: + try: + ret += self._obj.decompress(data) + except zlib.error: + previous_state = self._state + # Ignore data after the first error + self._state = GzipDecoderState.SWALLOW_DATA + if previous_state == GzipDecoderState.OTHER_MEMBERS: + # Allow trailing garbage acceptable in other gzip clients + return bytes(ret) + raise + data = self._obj.unused_data + if not data: + return bytes(ret) + self._state = GzipDecoderState.OTHER_MEMBERS + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + +class MultiDecoder(object): + """ + From RFC7231: + If one or more encodings have been applied to a representation, the + sender that applied the encodings MUST generate a Content-Encoding + header field that lists the content codings in the order in which + they were applied. + """ + + def __init__(self, modes): + self._decoders = [_get_decoder(m.strip()) for m in modes.split(',')] + + def flush(self): + return self._decoders[0].flush() + + def decompress(self, data): + for d in reversed(self._decoders): + data = d.decompress(data) + return data + + +def _get_decoder(mode): + if ',' in mode: + return MultiDecoder(mode) + + if mode == 'gzip': + return GzipDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible to httplib's HTTPResponse but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in httplib.HTTPResponse: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param original_response: + When this HTTPResponse wrapper is generated from an httplib.HTTPResponse + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ['gzip', 'deflate'] + REDIRECT_STATUSES = [301, 302, 303, 307, 308] + + def __init__(self, body='', headers=None, status=0, version=0, reason=None, + strict=0, preload_content=True, decode_content=True, + original_response=None, pool=None, connection=None, msg=None, + retries=None, enforce_content_length=False, + request_method=None, request_url=None): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + self.msg = msg + self._request_url = request_url + + if body and isinstance(body, (basestring, bytes)): + self._body = body + + self._pool = pool + self._connection = connection + + if hasattr(body, 'read'): + self._fp = body + + # Are we using the chunked-style of transfer encoding? + self.chunked = False + self.chunk_left = None + tr_enc = self.headers.get('transfer-encoding', '').lower() + # Don't incur the penalty of creating a list and then discarding it + encodings = (enc.strip() for enc in tr_enc.split(",")) + if "chunked" in encodings: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get('location') + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + @property + def data(self): + # For backwords-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def isclosed(self): + return is_fp_closed(self._fp) + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``HTTPResponse.read`` if bytes + are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + length = self.headers.get('content-length') + + if length is not None: + if self.chunked: + # This Response will fail with an IncompleteRead if it can't be + # received as chunked. This method falls back to attempt reading + # the response before raising an exception. + log.warning("Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked.") + return None + + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (e.g. Content-Length: 42, 42). This line ensures the values + # are all valid ints and that as long as the `set` length is 1, + # all values are the same. Otherwise, the header is invalid. + lengths = set([int(val) for val in length.split(',')]) + if len(lengths) > 1: + raise InvalidHeader("Content-Length contained multiple " + "unmatching values (%s)" % length) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get('content-encoding', '').lower() + if self._decoder is None: + if content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + elif ',' in content_encoding: + encodings = [e.strip() for e in content_encoding.split(',') if e.strip() in self.CONTENT_DECODERS] + if len(encodings): + self._decoder = _get_decoder(content_encoding) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + try: + if decode_content and self._decoder: + data = self._decoder.decompress(data) + except (IOError, zlib.error) as e: + content_encoding = self.headers.get('content-encoding', '').lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, e) + + if flush_decoder and decode_content: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b'') + return buf + self._decoder.flush() + + return b'' + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if 'read operation timed out' not in str(e): # Defensive: + # This shouldn't happen but just in case we're missing an edge + # case, let's avoid swallowing SSL errors. + raise + + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`httplib.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + data = None + + with self._error_catcher(): + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() + flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + if self.enforce_content_length and self.length_remaining not in (0, None): + # This is an edge case that httplib failed to cover due + # to concerns of backward compatibility. We're + # addressing it here to make sure IncompleteRead is + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + def stream(self, amt=2**16, decode_content=None): + """ + A generator wrapper for the read() method. A call will block until + ``amt`` bytes have been read from the connection or until the + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`httplib.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if PY3: # Python 3 + headers = HTTPHeaderDict(headers.items()) + else: # Python 2 + headers = HTTPHeaderDict.from_httplib(headers) + + # HTTPResponse objects in Python 3 don't have a .strict attribute + strict = getattr(r, 'strict', 0) + resp = ResponseCls(body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw) + return resp + + # Backwards-compatibility methods for httplib.HTTPResponse + def getheaders(self): + return self.headers + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + @property + def closed(self): + if self._fp is None: + return True + elif hasattr(self._fp, 'isclosed'): + return self._fp.isclosed() + elif hasattr(self._fp, 'closed'): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + elif hasattr(self._fp, "fileno"): + return self._fp.fileno() + else: + raise IOError("The file-like object this HTTPResponse is wrapped " + "around has no file descriptor") + + def flush(self): + if self._fp is not None and hasattr(self._fp, 'flush'): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + httplib.HTTPResponse object. We do this by testing for the fp + attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, 'fp') + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b';', 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise httplib.IncompleteRead(line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "Header 'transfer-encoding: chunked' is missing.") + if not self.supports_chunked_reads(): + raise BodyNotHttplibCompatible( + "Body should be httplib.HTTPResponse like. " + "It should have have an fp attribute which returns raw chunks.") + + with self._error_catcher(): + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + # If a response is already read and closed + # then return immediately. + if self._fp.fp is None: + return + + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode(chunk, decode_content=decode_content, + flush_decoder=False) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b'\r\n': + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() + + def geturl(self): + """ + Returns the URL that was the source of this response. + If the request that generated this response redirected, this method + will return the final redirect location. + """ + if self.retries is not None and len(self.retries.history): + return self.retries.history[-1].redirect_location + else: + return self._request_url diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/__init__.py new file mode 100755 index 0000000..2f2770b --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/__init__.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import make_headers +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import ( + current_time, + Timeout, +) + +from .retry import Retry +from .url import ( + get_host, + parse_url, + split_first, + Url, +) +from .wait import ( + wait_for_read, + wait_for_write +) + +__all__ = ( + 'HAS_SNI', + 'IS_PYOPENSSL', + 'IS_SECURETRANSPORT', + 'SSLContext', + 'Retry', + 'Timeout', + 'Url', + 'assert_fingerprint', + 'current_time', + 'is_connection_dropped', + 'is_fp_closed', + 'get_host', + 'parse_url', + 'make_headers', + 'resolve_cert_reqs', + 'resolve_ssl_version', + 'split_first', + 'ssl_wrap_socket', + 'wait_for_read', + 'wait_for_write' +) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/connection.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/connection.py new file mode 100755 index 0000000..5ad70b2 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/connection.py @@ -0,0 +1,134 @@ +from __future__ import absolute_import +import socket +from .wait import NoWayToWaitForSocketError, wait_for_read +from ..contrib import _appengine_environ + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, 'sock', False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + try: + # Returns True if readable, which here means it's been dropped + return wait_for_read(sock, timeout=0.0) + except NoWayToWaitForSocketError: # Platform-specific: AppEngine + return False + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +# One additional modification is that we avoid binding to IPv6 servers +# discovered in DNS if the system doesn't have IPv6 functionality. +def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, socket_options=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith('['): + host = host.strip('[]') + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """ Returns True if the system can bind an IPv6 address. """ + sock = None + has_ipv6 = False + + # App Engine doesn't support IPV6 sockets and actually has a quota on the + # number of sockets that can be used, so just early out here instead of + # creating a socket needlessly. + # See https://github.com/urllib3/urllib3/issues/1446 + if _appengine_environ.is_appengine_sandbox(): + return False + + if socket.has_ipv6: + # has_ipv6 returns true if cPython was compiled with IPv6 support. + # It does not tell us if the system has IPv6 support enabled. To + # determine that we must bind to an IPv6 address. + # https://github.com/shazow/urllib3/pull/611 + # https://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6('::1') diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/queue.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/queue.py new file mode 100755 index 0000000..d3d379a --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/queue.py @@ -0,0 +1,21 @@ +import collections +from ..packages import six +from ..packages.six.moves import queue + +if six.PY2: + # Queue is imported for side effects on MS Windows. See issue #229. + import Queue as _unused_module_Queue # noqa: F401 + + +class LifoQueue(queue.Queue): + def _init(self, _): + self.queue = collections.deque() + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/request.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/request.py new file mode 100755 index 0000000..3ddfcd5 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/request.py @@ -0,0 +1,118 @@ +from __future__ import absolute_import +from base64 import b64encode + +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError + +ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() + + +def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, + basic_auth=None, proxy_basic_auth=None, disable_cache=None): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + headers['authorization'] = 'Basic ' + \ + b64encode(b(basic_auth)).decode('utf-8') + + if proxy_basic_auth: + headers['proxy-authorization'] = 'Basic ' + \ + b64encode(b(proxy_basic_auth)).decode('utf-8') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, 'seek', None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect/retry.") + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError("Unable to record file position for rewinding " + "request body during a redirect/retry.") + else: + raise ValueError("body_pos must be of type integer, " + "instead it was %s." % type(body_pos)) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/response.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/response.py new file mode 100755 index 0000000..3d54864 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/response.py @@ -0,0 +1,87 @@ +from __future__ import absolute_import +from ..packages.six.moves import http_client as httplib + +from ..exceptions import HeaderParsingError + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param headers: Headers to verify. + :type headers: `httplib.HTTPMessage`. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # This will fail silently if we pass in the wrong kind of parameter. + # To make debugging easier add an explicit check. + if not isinstance(headers, httplib.HTTPMessage): + raise TypeError('expected httplib.Message, got {0}.'.format( + type(headers))) + + defects = getattr(headers, 'defects', None) + get_payload = getattr(headers, 'get_payload', None) + + unparsed_data = None + if get_payload: + # get_payload is actually email.message.Message.get_payload; + # we're only interested in the result if it's not a multipart message + if not headers.is_multipart(): + payload = get_payload() + + if isinstance(payload, (bytes, str)): + unparsed_data = payload + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param conn: + :type conn: :class:`httplib.HTTPResponse` + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == 'HEAD' diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/retry.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/retry.py new file mode 100755 index 0000000..e7d0abd --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/retry.py @@ -0,0 +1,411 @@ +from __future__ import absolute_import +import time +import logging +from collections import namedtuple +from itertools import takewhile +import email +import re + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, + InvalidHeader, +) +from ..packages import six + + +log = logging.getLogger(__name__) + + +# Data structure for representing the metadata of requests that result in a retry. +RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + Set to a ``False`` value to retry on any verb. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``method_whitelist`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ** ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + :param iterable remove_headers_on_redirect: + Sequence of headers to remove from the request when a response + indicating a redirect is returned before firing off the redirected + request. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) + + #: Maximum backoff time. + BACKOFF_MAX = 120 + + def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True, + remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): + + self.total = total + self.connect = connect + self.read = read + self.status = status + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header + self.remove_headers_on_redirect = remove_headers_on_redirect + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, + method_whitelist=self.method_whitelist, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, + remove_headers_on_redirect=self.remove_headers_on_redirect + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :rtype: float + """ + # We want to consider only the last consecutive errors sequence (Ignore redirects). + consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, + reversed(self.history)))) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + retry_date = time.mktime(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """ Get the value of Retry-After in seconds. """ + + retry_after = response.getheader("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """ Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + if self.status_forcelist and status_code in self.status_forcelist: + return True + + return (self.total and self.respect_retry_after_header and + has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment(self, method=None, url=None, response=None, error=None, + _pool=None, _stacktrace=None): + """ Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + cause = 'unknown' + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + status = response.status + + history = self.history + (RequestHistory(method, url, error, status, redirect_location),) + + new_retry = self.new( + total=total, + connect=connect, read=read, redirect=redirect, status=status_count, + history=history) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + return new_retry + + def __repr__(self): + return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' + 'read={self.read}, redirect={self.redirect}, status={self.status})').format( + cls=type(self), self=self) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py new file mode 100755 index 0000000..dfc553f --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py @@ -0,0 +1,381 @@ +from __future__ import absolute_import +import errno +import warnings +import hmac +import socket + +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning +from ..packages import six + + +SSLContext = None +HAS_SNI = False +IS_PYOPENSSL = False +IS_SECURETRANSPORT = False + +# Maps the length of a digest to a possible hash function producing this digest +HASHFUNC_MAP = { + 32: md5, + 40: sha1, + 64: sha256, +} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for l, r in zip(bytearray(a), bytearray(b)): + result |= l ^ r + return result == 0 + + +_const_compare_digest = getattr(hmac, 'compare_digest', + _const_compare_digest_backport) + + +try: # Test for SSL features + import ssl + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + + +# Python 2.7 doesn't have inet_pton on non-Linux so we fallback on inet_aton in +# those cases. This means that we can only detect IPv4 addresses in this case. +if hasattr(socket, 'inet_pton'): + inet_pton = socket.inet_pton +else: + # Maybe we can use ipaddress if the user has urllib3[secure]? + try: + from pip._vendor import ipaddress + + def inet_pton(_, host): + if isinstance(host, bytes): + host = host.decode('ascii') + return ipaddress.ip_address(host) + + except ImportError: # Platform-specific: Non-Linux + def inet_pton(_, host): + return socket.inet_aton(host) + + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer TLS 1.3 cipher suites +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_CIPHERS = ':'.join([ + 'TLS13-AES-256-GCM-SHA384', + 'TLS13-CHACHA20-POLY1305-SHA256', + 'TLS13-AES-128-GCM-SHA256', + 'ECDH+AESGCM', + 'ECDH+CHACHA20', + 'DH+AESGCM', + 'DH+CHACHA20', + 'ECDH+AES256', + 'DH+AES256', + 'ECDH+AES128', + 'DH+AES', + 'RSA+AESGCM', + 'RSA+AES', + '!aNULL', + '!eNULL', + '!MD5', +]) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None, server_side=False): + warnings.warn( + 'A true SSLContext object is not available. This prevents ' + 'urllib3 from configuring SSL appropriately and may cause ' + 'certain SSL connections to fail. You can upgrade to a newer ' + 'version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + InsecurePlatformWarning + ) + kwargs = { + 'keyfile': self.keyfile, + 'certfile': self.certfile, + 'ca_certs': self.ca_certs, + 'cert_reqs': self.verify_mode, + 'ssl_version': self.protocol, + 'server_side': server_side, + } + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + fingerprint = fingerprint.replace(':', '').lower() + digest_length = len(fingerprint) + hashfunc = HASHFUNC_MAP.get(digest_length) + if not hashfunc: + raise SSLError( + 'Fingerprint of invalid length: {0}'.format(fingerprint)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + cert_digest = hashfunc(cert).digest() + + if not _const_compare_digest(cert_digest, fingerprint_bytes): + raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' + .format(fingerprint, hexlify(cert_digest))) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_NONE`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbreviation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +def create_urllib3_context(ssl_version=None, cert_reqs=None, + options=None, ciphers=None): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from pip._vendor.urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + context.verify_mode = cert_reqs + if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + # We do our own verification, including fingerprints and alternative + # hostnames. So disable it here + context.check_hostname = False + return context + + +def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, + ca_certs=None, server_hostname=None, + ssl_version=None, ciphers=None, ssl_context=None, + ca_cert_dir=None): + """ + All arguments except for server_hostname, ssl_context, and ca_cert_dir have + the same meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument to + SSLContext.load_verify_locations(). + """ + context = ssl_context + if context is None: + # Note: This branch of code and all the variables in it are no longer + # used by urllib3 itself. We should consider deprecating and removing + # this code. + context = create_urllib3_context(ssl_version, cert_reqs, + ciphers=ciphers) + + if ca_certs or ca_cert_dir: + try: + context.load_verify_locations(ca_certs, ca_cert_dir) + except IOError as e: # Platform-specific: Python 2.7 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + elif getattr(context, 'load_default_certs', None) is not None: + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + if certfile: + context.load_cert_chain(certfile, keyfile) + + # If we detect server_hostname is an IP address then the SNI + # extension should not be used according to RFC3546 Section 3.1 + # We shouldn't warn the user if SNI isn't available but we would + # not be using SNI anyways due to IP address for server_hostname. + if ((server_hostname is not None and not is_ipaddress(server_hostname)) + or IS_SECURETRANSPORT): + if HAS_SNI and server_hostname is not None: + return context.wrap_socket(sock, server_hostname=server_hostname) + + warnings.warn( + 'An HTTPS request has been made, but the SNI (Server Name ' + 'Indication) extension to TLS is not available on this platform. ' + 'This may cause the server to present an incorrect TLS ' + 'certificate, which can cause validation failures. You can upgrade to ' + 'a newer version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + SNIMissingWarning + ) + + return context.wrap_socket(sock) + + +def is_ipaddress(hostname): + """Detects whether the hostname given is an IP address. + + :param str hostname: Hostname to examine. + :return: True if the hostname is an IP address, False otherwise. + """ + if six.PY3 and isinstance(hostname, bytes): + # IDN A-label bytes are ASCII compatible. + hostname = hostname.decode('ascii') + + families = [socket.AF_INET] + if hasattr(socket, 'AF_INET6'): + families.append(socket.AF_INET6) + + for af in families: + try: + inet_pton(af, hostname) + except (socket.error, ValueError, OSError): + pass + else: + return True + return False diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/timeout.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/timeout.py new file mode 100755 index 0000000..cec817e --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/timeout.py @@ -0,0 +1,242 @@ +from __future__ import absolute_import +# The default socket timeout, used by httplib to indicate that no timeout was +# specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: integer, float, or None + + :param connect: + The maximum amount of time to wait for a connection attempt to a server + to succeed. Omitting the parameter will default the connect timeout to + the system default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout for connection attempts. + + :type connect: integer, float, or None + + :param read: + The maximum amount of time to wait between consecutive + read operations for a response from the server. Omitting + the parameter will default the read timeout to the system + default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, 'connect') + self._read = self._validate_timeout(read, 'read') + self.total = self._validate_timeout(total, 'total') + self._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + raise ValueError("Timeout cannot be a boolean value. It must " + "be an int, float or None.") + try: + float(value) + except (TypeError, ValueError): + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + try: + if value <= 0: + raise ValueError("Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, + total=self.total) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError("Can't get connect duration for timer " + "that has not started.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if (self.total is not None and + self.total is not self.DEFAULT_TIMEOUT and + self._read is not None and + self._read is not self.DEFAULT_TIMEOUT): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), + self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/url.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/url.py new file mode 100755 index 0000000..6b6f996 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/url.py @@ -0,0 +1,230 @@ +from __future__ import absolute_import +from collections import namedtuple + +from ..exceptions import LocationParseError + + +url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] + +# We only want to normalize urls with an HTTP(S) scheme. +# urllib3 infers URLs without a scheme (None) to be http. +NORMALIZABLE_SCHEMES = ('http', 'https', None) + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. Both the scheme and host are normalized as they are + both case-insensitive according to RFC 3986. + """ + __slots__ = () + + def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, + query=None, fragment=None): + if path and not path.startswith('/'): + path = '/' + path + if scheme: + scheme = scheme.lower() + if host and scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx + 1:], min_delim + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. No whitespace, no plus or + # minus prefixes, no non-integer digits such as ^2 (superscript). + if not port.isdigit(): + raise LocationParseError(url) + try: + port = int(port) + except ValueError: + raise LocationParseError(url) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/wait.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/wait.py new file mode 100755 index 0000000..4db71ba --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/urllib3/util/wait.py @@ -0,0 +1,150 @@ +import errno +from functools import partial +import select +import sys +try: + from time import monotonic +except ImportError: + from time import time as monotonic + +__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] + + +class NoWayToWaitForSocketError(Exception): + pass + + +# How should we wait on sockets? +# +# There are two types of APIs you can use for waiting on sockets: the fancy +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like +# select/poll. The stateful APIs are more efficient when you have a lots of +# sockets to keep track of, because you can set them up once and then use them +# lots of times. But we only ever want to wait on a single socket at a time +# and don't want to keep track of state, so the stateless APIs are actually +# more efficient. So we want to use select() or poll(). +# +# Now, how do we choose between select() and poll()? On traditional Unixes, +# select() has a strange calling convention that makes it slow, or fail +# altogether, for high-numbered file descriptors. The point of poll() is to fix +# that, so on Unixes, we prefer poll(). +# +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper +# for it), but that's OK, because on Windows, select() doesn't have this +# strange calling convention; plain select() works fine. +# +# So: on Windows we use select(), and everywhere else we use poll(). We also +# fall back to select() in case poll() is somehow broken or missing. + +if sys.version_info >= (3, 5): + # Modern Python, that retries syscalls by default + def _retry_on_intr(fn, timeout): + return fn(timeout) +else: + # Old and broken Pythons. + def _retry_on_intr(fn, timeout): + if timeout is None: + deadline = float("inf") + else: + deadline = monotonic() + timeout + + while True: + try: + return fn(timeout) + # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 + except (OSError, select.error) as e: + # 'e.args[0]' incantation works for both OSError and select.error + if e.args[0] != errno.EINTR: + raise + else: + timeout = deadline - monotonic() + if timeout < 0: + timeout = 0 + if timeout == float("inf"): + timeout = None + continue + + +def select_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + rcheck = [] + wcheck = [] + if read: + rcheck.append(sock) + if write: + wcheck.append(sock) + # When doing a non-blocking connect, most systems signal success by + # marking the socket writable. Windows, though, signals success by marked + # it as "exceptional". We paper over the difference by checking the write + # sockets for both conditions. (The stdlib selectors module does the same + # thing.) + fn = partial(select.select, rcheck, wcheck, wcheck) + rready, wready, xready = _retry_on_intr(fn, timeout) + return bool(rready or wready or xready) + + +def poll_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + mask = 0 + if read: + mask |= select.POLLIN + if write: + mask |= select.POLLOUT + poll_obj = select.poll() + poll_obj.register(sock, mask) + + # For some reason, poll() takes timeout in milliseconds + def do_poll(t): + if t is not None: + t *= 1000 + return poll_obj.poll(t) + + return bool(_retry_on_intr(do_poll, timeout)) + + +def null_wait_for_socket(*args, **kwargs): + raise NoWayToWaitForSocketError("no select-equivalent available") + + +def _have_working_poll(): + # Apparently some systems have a select.poll that fails as soon as you try + # to use it, either due to strange configuration or broken monkeypatching + # from libraries like eventlet/greenlet. + try: + poll_obj = select.poll() + _retry_on_intr(poll_obj.poll, 0) + except (AttributeError, OSError): + return False + else: + return True + + +def wait_for_socket(*args, **kwargs): + # We delay choosing which implementation to use until the first time we're + # called. We could do it at import time, but then we might make the wrong + # decision if someone goes wild with monkeypatching select.poll after + # we're imported. + global wait_for_socket + if _have_working_poll(): + wait_for_socket = poll_wait_for_socket + elif hasattr(select, "select"): + wait_for_socket = select_wait_for_socket + else: # Platform-specific: Appengine. + wait_for_socket = null_wait_for_socket + return wait_for_socket(*args, **kwargs) + + +def wait_for_read(sock, timeout=None): + """ Waits for reading to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, read=True, timeout=timeout) + + +def wait_for_write(sock, timeout=None): + """ Waits for writing to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/__init__.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/__init__.py new file mode 100755 index 0000000..d21d697 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/__init__.py @@ -0,0 +1,342 @@ +# coding: utf-8 +""" + + webencodings + ~~~~~~~~~~~~ + + This is a Python implementation of the `WHATWG Encoding standard + <http://encoding.spec.whatwg.org/>`. See README for details. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + +from .labels import LABELS + + +VERSION = '0.5.1' + + +# Some names in Encoding are not valid Python aliases. Remap these. +PYTHON_NAMES = { + 'iso-8859-8-i': 'iso-8859-8', + 'x-mac-cyrillic': 'mac-cyrillic', + 'macintosh': 'mac-roman', + 'windows-874': 'cp874'} + +CACHE = {} + + +def ascii_lower(string): + r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. + + :param string: An Unicode string. + :returns: A new Unicode string. + + This is used for `ASCII case-insensitive + <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ + matching of encoding labels. + The same matching is also used, among other things, + for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. + + This is different from the :meth:`~py:str.lower` method of Unicode strings + which also affect non-ASCII characters, + sometimes mapping them into the ASCII range: + + >>> keyword = u'Bac\N{KELVIN SIGN}ground' + >>> assert keyword.lower() == u'background' + >>> assert ascii_lower(keyword) != keyword.lower() + >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' + + """ + # This turns out to be faster than unicode.translate() + return string.encode('utf8').lower().decode('utf8') + + +def lookup(label): + """ + Look for an encoding by its label. + This is the spec’s `get an encoding + <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. + Supported labels are listed there. + + :param label: A string. + :returns: + An :class:`Encoding` object, or :obj:`None` for an unknown label. + + """ + # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. + label = ascii_lower(label.strip('\t\n\f\r ')) + name = LABELS.get(label) + if name is None: + return None + encoding = CACHE.get(name) + if encoding is None: + if name == 'x-user-defined': + from .x_user_defined import codec_info + else: + python_name = PYTHON_NAMES.get(name, name) + # Any python_name value that gets to here should be valid. + codec_info = codecs.lookup(python_name) + encoding = Encoding(name, codec_info) + CACHE[name] = encoding + return encoding + + +def _get_encoding(encoding_or_label): + """ + Accept either an encoding object or label. + + :param encoding: An :class:`Encoding` object or a label string. + :returns: An :class:`Encoding` object. + :raises: :exc:`~exceptions.LookupError` for an unknown label. + + """ + if hasattr(encoding_or_label, 'codec_info'): + return encoding_or_label + + encoding = lookup(encoding_or_label) + if encoding is None: + raise LookupError('Unknown encoding label: %r' % encoding_or_label) + return encoding + + +class Encoding(object): + """Reresents a character encoding such as UTF-8, + that can be used for decoding or encoding. + + .. attribute:: name + + Canonical name of the encoding + + .. attribute:: codec_info + + The actual implementation of the encoding, + a stdlib :class:`~codecs.CodecInfo` object. + See :func:`codecs.register`. + + """ + def __init__(self, name, codec_info): + self.name = name + self.codec_info = codec_info + + def __repr__(self): + return '<Encoding %s>' % self.name + + +#: The UTF-8 encoding. Should be used for new content and formats. +UTF8 = lookup('utf-8') + +_UTF16LE = lookup('utf-16le') +_UTF16BE = lookup('utf-16be') + + +def decode(input, fallback_encoding, errors='replace'): + """ + Decode a single string. + + :param input: A byte string + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: + A ``(output, encoding)`` tuple of an Unicode string + and an :obj:`Encoding`. + + """ + # Fail early if `encoding` is an invalid label. + fallback_encoding = _get_encoding(fallback_encoding) + bom_encoding, input = _detect_bom(input) + encoding = bom_encoding or fallback_encoding + return encoding.codec_info.decode(input, errors)[0], encoding + + +def _detect_bom(input): + """Return (bom_encoding, input), with any BOM removed from the input.""" + if input.startswith(b'\xFF\xFE'): + return _UTF16LE, input[2:] + if input.startswith(b'\xFE\xFF'): + return _UTF16BE, input[2:] + if input.startswith(b'\xEF\xBB\xBF'): + return UTF8, input[3:] + return None, input + + +def encode(input, encoding=UTF8, errors='strict'): + """ + Encode a single string. + + :param input: An Unicode string. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: A byte string. + + """ + return _get_encoding(encoding).codec_info.encode(input, errors)[0] + + +def iter_decode(input, fallback_encoding, errors='replace'): + """ + "Pull"-based decoder. + + :param input: + An iterable of byte strings. + + The input is first consumed just enough to determine the encoding + based on the precense of a BOM, + then consumed on demand when the return value is. + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: + An ``(output, encoding)`` tuple. + :obj:`output` is an iterable of Unicode strings, + :obj:`encoding` is the :obj:`Encoding` that is being used. + + """ + + decoder = IncrementalDecoder(fallback_encoding, errors) + generator = _iter_decode_generator(input, decoder) + encoding = next(generator) + return generator, encoding + + +def _iter_decode_generator(input, decoder): + """Return a generator that first yields the :obj:`Encoding`, + then yields output chukns as Unicode strings. + + """ + decode = decoder.decode + input = iter(input) + for chunck in input: + output = decode(chunck) + if output: + assert decoder.encoding is not None + yield decoder.encoding + yield output + break + else: + # Input exhausted without determining the encoding + output = decode(b'', final=True) + assert decoder.encoding is not None + yield decoder.encoding + if output: + yield output + return + + for chunck in input: + output = decode(chunck) + if output: + yield output + output = decode(b'', final=True) + if output: + yield output + + +def iter_encode(input, encoding=UTF8, errors='strict'): + """ + “Pull”-based encoder. + + :param input: An iterable of Unicode strings. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: An iterable of byte strings. + + """ + # Fail early if `encoding` is an invalid label. + encode = IncrementalEncoder(encoding, errors).encode + return _iter_encode_generator(input, encode) + + +def _iter_encode_generator(input, encode): + for chunck in input: + output = encode(chunck) + if output: + yield output + output = encode('', final=True) + if output: + yield output + + +class IncrementalDecoder(object): + """ + “Push”-based decoder. + + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + """ + def __init__(self, fallback_encoding, errors='replace'): + # Fail early if `encoding` is an invalid label. + self._fallback_encoding = _get_encoding(fallback_encoding) + self._errors = errors + self._buffer = b'' + self._decoder = None + #: The actual :class:`Encoding` that is being used, + #: or :obj:`None` if that is not determined yet. + #: (Ie. if there is not enough input yet to determine + #: if there is a BOM.) + self.encoding = None # Not known yet. + + def decode(self, input, final=False): + """Decode one chunk of the input. + + :param input: A byte string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: An Unicode string. + + """ + decoder = self._decoder + if decoder is not None: + return decoder(input, final) + + input = self._buffer + input + encoding, input = _detect_bom(input) + if encoding is None: + if len(input) < 3 and not final: # Not enough data yet. + self._buffer = input + return '' + else: # No BOM + encoding = self._fallback_encoding + decoder = encoding.codec_info.incrementaldecoder(self._errors).decode + self._decoder = decoder + self.encoding = encoding + return decoder(input, final) + + +class IncrementalEncoder(object): + """ + “Push”-based encoder. + + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + .. method:: encode(input, final=False) + + :param input: An Unicode string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: A byte string. + + """ + def __init__(self, encoding=UTF8, errors='strict'): + encoding = _get_encoding(encoding) + self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/labels.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/labels.py new file mode 100755 index 0000000..29cbf91 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/labels.py @@ -0,0 +1,231 @@ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { + 'unicode-1-1-utf-8': 'utf-8', + 'utf-8': 'utf-8', + 'utf8': 'utf-8', + '866': 'ibm866', + 'cp866': 'ibm866', + 'csibm866': 'ibm866', + 'ibm866': 'ibm866', + 'csisolatin2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso8859-2': 'iso-8859-2', + 'iso88592': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso_8859-2:1987': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'csisolatin3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso8859-3': 'iso-8859-3', + 'iso88593': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso_8859-3:1988': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'csisolatin4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso8859-4': 'iso-8859-4', + 'iso88594': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso_8859-4:1988': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'csisolatincyrillic': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso8859-5': 'iso-8859-5', + 'iso88595': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso_8859-5:1988': 'iso-8859-5', + 'arabic': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'csiso88596e': 'iso-8859-6', + 'csiso88596i': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'iso-8859-6-e': 'iso-8859-6', + 'iso-8859-6-i': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso8859-6': 'iso-8859-6', + 'iso88596': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso_8859-6:1987': 'iso-8859-6', + 'csisolatingreek': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso8859-7': 'iso-8859-7', + 'iso88597': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso_8859-7:1987': 'iso-8859-7', + 'sun_eu_greek': 'iso-8859-7', + 'csiso88598e': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'iso-8859-8-e': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso8859-8': 'iso-8859-8', + 'iso88598': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso_8859-8:1988': 'iso-8859-8', + 'visual': 'iso-8859-8', + 'csiso88598i': 'iso-8859-8-i', + 'iso-8859-8-i': 'iso-8859-8-i', + 'logical': 'iso-8859-8-i', + 'csisolatin6': 'iso-8859-10', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'iso8859-10': 'iso-8859-10', + 'iso885910': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso8859-13': 'iso-8859-13', + 'iso885913': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso8859-14': 'iso-8859-14', + 'iso885914': 'iso-8859-14', + 'csisolatin9': 'iso-8859-15', + 'iso-8859-15': 'iso-8859-15', + 'iso8859-15': 'iso-8859-15', + 'iso885915': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'l9': 'iso-8859-15', + 'iso-8859-16': 'iso-8859-16', + 'cskoi8r': 'koi8-r', + 'koi': 'koi8-r', + 'koi8': 'koi8-r', + 'koi8-r': 'koi8-r', + 'koi8_r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'csmacintosh': 'macintosh', + 'mac': 'macintosh', + 'macintosh': 'macintosh', + 'x-mac-roman': 'macintosh', + 'dos-874': 'windows-874', + 'iso-8859-11': 'windows-874', + 'iso8859-11': 'windows-874', + 'iso885911': 'windows-874', + 'tis-620': 'windows-874', + 'windows-874': 'windows-874', + 'cp1250': 'windows-1250', + 'windows-1250': 'windows-1250', + 'x-cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'windows-1251': 'windows-1251', + 'x-cp1251': 'windows-1251', + 'ansi_x3.4-1968': 'windows-1252', + 'ascii': 'windows-1252', + 'cp1252': 'windows-1252', + 'cp819': 'windows-1252', + 'csisolatin1': 'windows-1252', + 'ibm819': 'windows-1252', + 'iso-8859-1': 'windows-1252', + 'iso-ir-100': 'windows-1252', + 'iso8859-1': 'windows-1252', + 'iso88591': 'windows-1252', + 'iso_8859-1': 'windows-1252', + 'iso_8859-1:1987': 'windows-1252', + 'l1': 'windows-1252', + 'latin1': 'windows-1252', + 'us-ascii': 'windows-1252', + 'windows-1252': 'windows-1252', + 'x-cp1252': 'windows-1252', + 'cp1253': 'windows-1253', + 'windows-1253': 'windows-1253', + 'x-cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'csisolatin5': 'windows-1254', + 'iso-8859-9': 'windows-1254', + 'iso-ir-148': 'windows-1254', + 'iso8859-9': 'windows-1254', + 'iso88599': 'windows-1254', + 'iso_8859-9': 'windows-1254', + 'iso_8859-9:1989': 'windows-1254', + 'l5': 'windows-1254', + 'latin5': 'windows-1254', + 'windows-1254': 'windows-1254', + 'x-cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'windows-1255': 'windows-1255', + 'x-cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'windows-1256': 'windows-1256', + 'x-cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'windows-1257': 'windows-1257', + 'x-cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'windows-1258': 'windows-1258', + 'x-cp1258': 'windows-1258', + 'x-mac-cyrillic': 'x-mac-cyrillic', + 'x-mac-ukrainian': 'x-mac-cyrillic', + 'chinese': 'gbk', + 'csgb2312': 'gbk', + 'csiso58gb231280': 'gbk', + 'gb2312': 'gbk', + 'gb_2312': 'gbk', + 'gb_2312-80': 'gbk', + 'gbk': 'gbk', + 'iso-ir-58': 'gbk', + 'x-gbk': 'gbk', + 'gb18030': 'gb18030', + 'hz-gb-2312': 'hz-gb-2312', + 'big5': 'big5', + 'big5-hkscs': 'big5', + 'cn-big5': 'big5', + 'csbig5': 'big5', + 'x-x-big5': 'big5', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'x-euc-jp': 'euc-jp', + 'csiso2022jp': 'iso-2022-jp', + 'iso-2022-jp': 'iso-2022-jp', + 'csshiftjis': 'shift_jis', + 'ms_kanji': 'shift_jis', + 'shift-jis': 'shift_jis', + 'shift_jis': 'shift_jis', + 'sjis': 'shift_jis', + 'windows-31j': 'shift_jis', + 'x-sjis': 'shift_jis', + 'cseuckr': 'euc-kr', + 'csksc56011987': 'euc-kr', + 'euc-kr': 'euc-kr', + 'iso-ir-149': 'euc-kr', + 'korean': 'euc-kr', + 'ks_c_5601-1987': 'euc-kr', + 'ks_c_5601-1989': 'euc-kr', + 'ksc5601': 'euc-kr', + 'ksc_5601': 'euc-kr', + 'windows-949': 'euc-kr', + 'csiso2022kr': 'iso-2022-kr', + 'iso-2022-kr': 'iso-2022-kr', + 'utf-16be': 'utf-16be', + 'utf-16': 'utf-16le', + 'utf-16le': 'utf-16le', + 'x-user-defined': 'x-user-defined', +} diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/mklabels.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/mklabels.py new file mode 100755 index 0000000..295dc92 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/mklabels.py @@ -0,0 +1,59 @@ +""" + + webencodings.mklabels + ~~~~~~~~~~~~~~~~~~~~~ + + Regenarate the webencodings.labels module. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +import json +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + + +def assert_lower(string): + assert string == string.lower() + return string + + +def generate(url): + parts = ['''\ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { +'''] + labels = [ + (repr(assert_lower(label)).lstrip('u'), + repr(encoding['name']).lstrip('u')) + for category in json.loads(urlopen(url).read().decode('ascii')) + for encoding in category['encodings'] + for label in encoding['labels']] + max_len = max(len(label) for label, name in labels) + parts.extend( + ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) + for label, name in labels) + parts.append('}') + return ''.join(parts) + + +if __name__ == '__main__': + print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/tests.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/tests.py new file mode 100755 index 0000000..e12c10d --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/tests.py @@ -0,0 +1,153 @@ +# coding: utf-8 +""" + + webencodings.tests + ~~~~~~~~~~~~~~~~~~ + + A basic test suite for Encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, + IncrementalDecoder, IncrementalEncoder, UTF8) + + +def assert_raises(exception, function, *args, **kwargs): + try: + function(*args, **kwargs) + except exception: + return + else: # pragma: no cover + raise AssertionError('Did not raise %s.' % exception) + + +def test_labels(): + assert lookup('utf-8').name == 'utf-8' + assert lookup('Utf-8').name == 'utf-8' + assert lookup('UTF-8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8 ').name == 'utf-8' + assert lookup(' \r\nutf8\t').name == 'utf-8' + assert lookup('u8') is None # Python label. + assert lookup('utf-8 ') is None # Non-ASCII white space. + + assert lookup('US-ASCII').name == 'windows-1252' + assert lookup('iso-8859-1').name == 'windows-1252' + assert lookup('latin1').name == 'windows-1252' + assert lookup('LATIN1').name == 'windows-1252' + assert lookup('latin-1') is None + assert lookup('LATİN1') is None # ASCII-only case insensitivity. + + +def test_all_labels(): + for label in LABELS: + assert decode(b'', label) == ('', lookup(label)) + assert encode('', label) == b'' + for repeat in [0, 1, 12]: + output, _ = iter_decode([b''] * repeat, label) + assert list(output) == [] + assert list(iter_encode([''] * repeat, label)) == [] + decoder = IncrementalDecoder(label) + assert decoder.decode(b'') == '' + assert decoder.decode(b'', final=True) == '' + encoder = IncrementalEncoder(label) + assert encoder.encode('') == b'' + assert encoder.encode('', final=True) == b'' + # All encoding names are valid labels too: + for name in set(LABELS.values()): + assert lookup(name).name == name + + +def test_invalid_label(): + assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') + assert_raises(LookupError, encode, 'é', 'invalid') + assert_raises(LookupError, iter_decode, [], 'invalid') + assert_raises(LookupError, iter_encode, [], 'invalid') + assert_raises(LookupError, IncrementalDecoder, 'invalid') + assert_raises(LookupError, IncrementalEncoder, 'invalid') + + +def test_decode(): + assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) + assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) + assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) + assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM + + assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM + assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM + assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) + assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) + + assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) + assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) + assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) + + assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) + assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) + assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) + + +def test_encode(): + assert encode('é', 'latin1') == b'\xe9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf-16') == b'\xe9\x00' + assert encode('é', 'utf-16le') == b'\xe9\x00' + assert encode('é', 'utf-16be') == b'\x00\xe9' + + +def test_iter_decode(): + def iter_decode_to_string(input, fallback_encoding): + output, _encoding = iter_decode(input, fallback_encoding) + return ''.join(output) + assert iter_decode_to_string([], 'latin1') == '' + assert iter_decode_to_string([b''], 'latin1') == '' + assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' + assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' + assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' + assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' + assert iter_decode_to_string([ + b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' + assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' + assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' + + +def test_iter_encode(): + assert b''.join(iter_encode([], 'latin1')) == b'' + assert b''.join(iter_encode([''], 'latin1')) == b'' + assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' + assert b''.join(iter_encode([ + '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' + + +def test_x_user_defined(): + encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' + decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' + encoded = b'aa' + decoded = 'aa' + assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) + assert encode(decoded, 'x-user-defined') == encoded diff --git a/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py new file mode 100755 index 0000000..d16e326 --- /dev/null +++ b/Lib/site-packages/pip-19.0.3-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py @@ -0,0 +1,325 @@ +# coding: utf-8 +""" + + webencodings.x_user_defined + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An implementation of the x-user-defined encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +### encodings module API + +codec_info = codecs.CodecInfo( + name='x-user-defined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, +) + + +### Decoding Table + +# Python 3: +# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) +decoding_table = ( + '\x00' + '\x01' + '\x02' + '\x03' + '\x04' + '\x05' + '\x06' + '\x07' + '\x08' + '\t' + '\n' + '\x0b' + '\x0c' + '\r' + '\x0e' + '\x0f' + '\x10' + '\x11' + '\x12' + '\x13' + '\x14' + '\x15' + '\x16' + '\x17' + '\x18' + '\x19' + '\x1a' + '\x1b' + '\x1c' + '\x1d' + '\x1e' + '\x1f' + ' ' + '!' + '"' + '#' + '$' + '%' + '&' + "'" + '(' + ')' + '*' + '+' + ',' + '-' + '.' + '/' + '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' + '[' + '\\' + ']' + '^' + '_' + '`' + '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' + '{' + '|' + '}' + '~' + '\x7f' + '\uf780' + '\uf781' + '\uf782' + '\uf783' + '\uf784' + '\uf785' + '\uf786' + '\uf787' + '\uf788' + '\uf789' + '\uf78a' + '\uf78b' + '\uf78c' + '\uf78d' + '\uf78e' + '\uf78f' + '\uf790' + '\uf791' + '\uf792' + '\uf793' + '\uf794' + '\uf795' + '\uf796' + '\uf797' + '\uf798' + '\uf799' + '\uf79a' + '\uf79b' + '\uf79c' + '\uf79d' + '\uf79e' + '\uf79f' + '\uf7a0' + '\uf7a1' + '\uf7a2' + '\uf7a3' + '\uf7a4' + '\uf7a5' + '\uf7a6' + '\uf7a7' + '\uf7a8' + '\uf7a9' + '\uf7aa' + '\uf7ab' + '\uf7ac' + '\uf7ad' + '\uf7ae' + '\uf7af' + '\uf7b0' + '\uf7b1' + '\uf7b2' + '\uf7b3' + '\uf7b4' + '\uf7b5' + '\uf7b6' + '\uf7b7' + '\uf7b8' + '\uf7b9' + '\uf7ba' + '\uf7bb' + '\uf7bc' + '\uf7bd' + '\uf7be' + '\uf7bf' + '\uf7c0' + '\uf7c1' + '\uf7c2' + '\uf7c3' + '\uf7c4' + '\uf7c5' + '\uf7c6' + '\uf7c7' + '\uf7c8' + '\uf7c9' + '\uf7ca' + '\uf7cb' + '\uf7cc' + '\uf7cd' + '\uf7ce' + '\uf7cf' + '\uf7d0' + '\uf7d1' + '\uf7d2' + '\uf7d3' + '\uf7d4' + '\uf7d5' + '\uf7d6' + '\uf7d7' + '\uf7d8' + '\uf7d9' + '\uf7da' + '\uf7db' + '\uf7dc' + '\uf7dd' + '\uf7de' + '\uf7df' + '\uf7e0' + '\uf7e1' + '\uf7e2' + '\uf7e3' + '\uf7e4' + '\uf7e5' + '\uf7e6' + '\uf7e7' + '\uf7e8' + '\uf7e9' + '\uf7ea' + '\uf7eb' + '\uf7ec' + '\uf7ed' + '\uf7ee' + '\uf7ef' + '\uf7f0' + '\uf7f1' + '\uf7f2' + '\uf7f3' + '\uf7f4' + '\uf7f5' + '\uf7f6' + '\uf7f7' + '\uf7f8' + '\uf7f9' + '\uf7fa' + '\uf7fb' + '\uf7fc' + '\uf7fd' + '\uf7fe' + '\uf7ff' +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/Lib/site-packages/setuptools-40.8.0-py3.7.egg b/Lib/site-packages/setuptools-40.8.0-py3.7.egg new file mode 100755 index 0000000000000000000000000000000000000000..60b654cf15ed69e294b193d3c3cdba5aa7276b7b GIT binary patch literal 571910 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⪚r4#7<B<L=5yk3rELbP5 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%0AaCsRM0n%G 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 D1y_(T literal 0 HcmV?d00001 diff --git a/Lib/site-packages/setuptools.pth b/Lib/site-packages/setuptools.pth new file mode 100755 index 0000000..666aec5 --- /dev/null +++ b/Lib/site-packages/setuptools.pth @@ -0,0 +1 @@ +./setuptools-40.8.0-py3.7.egg diff --git a/Scripts/Activate.ps1 b/Scripts/Activate.ps1 new file mode 100755 index 0000000..4515994 --- /dev/null +++ b/Scripts/Activate.ps1 @@ -0,0 +1,51 @@ +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + if (Test-Path function:_OLD_VIRTUAL_PROMPT) { + copy-item function:_OLD_VIRTUAL_PROMPT function:prompt + remove-item function:_OLD_VIRTUAL_PROMPT + } + + if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { + copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME + remove-item env:_OLD_VIRTUAL_PYTHONHOME + } + + if (Test-Path env:_OLD_VIRTUAL_PATH) { + copy-item env:_OLD_VIRTUAL_PATH env:PATH + remove-item env:_OLD_VIRTUAL_PATH + } + + if (Test-Path env:VIRTUAL_ENV) { + remove-item env:VIRTUAL_ENV + } + + if (!$NonDestructive) { + # Self destruct! + remove-item function:deactivate + } +} + +deactivate -nondestructive + +$env:VIRTUAL_ENV="C:\Users\amer1\Desktop\python" + +if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT {""} + copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green '(python) ' + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path env:PYTHONHOME) { + copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME + remove-item env:PYTHONHOME +} + +# Add the venv to the PATH +copy-item env:PATH env:_OLD_VIRTUAL_PATH +$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH" diff --git a/Scripts/activate b/Scripts/activate new file mode 100755 index 0000000..09bd0f5 --- /dev/null +++ b/Scripts/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="C:\Users\amer1\Desktop\python" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$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(python) " != x ] ; then + PS1="(python) ${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/Scripts/activate.bat b/Scripts/activate.bat new file mode 100755 index 0000000..33dda61 --- /dev/null +++ b/Scripts/activate.bat @@ -0,0 +1,45 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:" %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set "_OLD_CODEPAGE=%%a" +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set "VIRTUAL_ENV=C:\Users\amer1\Desktop\python" + +if not defined PROMPT ( + set "PROMPT=$P$G" +) + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" +) + +set "_OLD_VIRTUAL_PROMPT=%PROMPT%" +set "PROMPT=(python) %PROMPT%" + +if defined PYTHONHOME ( + set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" + set PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) else ( + set "_OLD_VIRTUAL_PATH=%PATH%" +) + +set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%" + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set "_OLD_CODEPAGE=" +) diff --git a/Scripts/deactivate.bat b/Scripts/deactivate.bat new file mode 100755 index 0000000..313c079 --- /dev/null +++ b/Scripts/deactivate.bat @@ -0,0 +1,21 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= + +:END diff --git a/Scripts/easy_install-3.7-script.py b/Scripts/easy_install-3.7-script.py new file mode 100755 index 0000000..8d7e305 --- /dev/null +++ b/Scripts/easy_install-3.7-script.py @@ -0,0 +1,12 @@ +#!C:\Users\amer1\Desktop\python\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install-3.7' +__requires__ = 'setuptools==40.8.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install-3.7')() + ) diff --git a/Scripts/easy_install-3.7.exe b/Scripts/easy_install-3.7.exe new file mode 100755 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/Scripts/easy_install-3.7.exe.manifest b/Scripts/easy_install-3.7.exe.manifest new file mode 100755 index 0000000..62463b3 --- /dev/null +++ b/Scripts/easy_install-3.7.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="easy_install-3.7" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Scripts/easy_install-script.py b/Scripts/easy_install-script.py new file mode 100755 index 0000000..f007e07 --- /dev/null +++ b/Scripts/easy_install-script.py @@ -0,0 +1,12 @@ +#!C:\Users\amer1\Desktop\python\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install' +__requires__ = 'setuptools==40.8.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install')() + ) diff --git a/Scripts/easy_install.exe b/Scripts/easy_install.exe new file mode 100755 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/Scripts/easy_install.exe.manifest b/Scripts/easy_install.exe.manifest new file mode 100755 index 0000000..b3c85a1 --- /dev/null +++ b/Scripts/easy_install.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="easy_install" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Scripts/pip-script.py b/Scripts/pip-script.py new file mode 100755 index 0000000..e942f75 --- /dev/null +++ b/Scripts/pip-script.py @@ -0,0 +1,12 @@ +#!C:\Users\amer1\Desktop\python\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip' +__requires__ = 'pip==19.0.3' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==19.0.3', 'console_scripts', 'pip')() + ) diff --git a/Scripts/pip.exe b/Scripts/pip.exe new file mode 100755 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/Scripts/pip.exe.manifest b/Scripts/pip.exe.manifest new file mode 100755 index 0000000..604470d --- /dev/null +++ b/Scripts/pip.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="pip" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Scripts/pip3-script.py b/Scripts/pip3-script.py new file mode 100755 index 0000000..a321e4f --- /dev/null +++ b/Scripts/pip3-script.py @@ -0,0 +1,12 @@ +#!C:\Users\amer1\Desktop\python\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3' +__requires__ = 'pip==19.0.3' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==19.0.3', 'console_scripts', 'pip3')() + ) diff --git a/Scripts/pip3.7-script.py b/Scripts/pip3.7-script.py new file mode 100755 index 0000000..0fa9502 --- /dev/null +++ b/Scripts/pip3.7-script.py @@ -0,0 +1,12 @@ +#!C:\Users\amer1\Desktop\python\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3.7' +__requires__ = 'pip==19.0.3' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==19.0.3', 'console_scripts', 'pip3.7')() + ) diff --git a/Scripts/pip3.7.exe b/Scripts/pip3.7.exe new file mode 100755 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/Scripts/pip3.7.exe.manifest b/Scripts/pip3.7.exe.manifest new file mode 100755 index 0000000..cd60728 --- /dev/null +++ b/Scripts/pip3.7.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="pip3.7" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Scripts/pip3.exe b/Scripts/pip3.exe new file mode 100755 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/Scripts/pip3.exe.manifest b/Scripts/pip3.exe.manifest new file mode 100755 index 0000000..da3c385 --- /dev/null +++ b/Scripts/pip3.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="pip3" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Scripts/python.exe b/Scripts/python.exe new file mode 100755 index 0000000000000000000000000000000000000000..a996c22e9f9980aa335c6bd40eb5727fa50ffdcd GIT binary patch literal 415248 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ℑqo{(!Ok=jpS%P< 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�yDMrqx1i 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 literal 0 HcmV?d00001 diff --git a/Scripts/pythonw.exe b/Scripts/pythonw.exe new file mode 100755 index 0000000000000000000000000000000000000000..ab1b78274f8896e2c574684f08dedfdf21bca07c GIT binary patch literal 414736 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%0AA3zpKyQ+cBoi+yk- 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%0AFAfRN{=5 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Ν{xd}Y4(7OqC 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℞7R(I@`vXu2 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 Korweg3i=PsU>79- literal 0 HcmV?d00001 diff --git a/example1.py b/example1.py new file mode 100755 index 0000000..ca01c65 --- /dev/null +++ b/example1.py @@ -0,0 +1,29 @@ +#import csv +#with open('test1.txt','r') as f: +# # Printing Specific Part of CSV_file +# # Printing last line of second column +# lines = list(csv.reader(f, delimiter = ',', skipinitialspace = True)) +# #print(lines[1][4]) +# # For printing a range of rows except 10 last rows of second column +# for i in range(len(lines)-3): +# print(lines[i][4]) + +import numpy as np + +AoA_point_3 = -90 +a = np.array([]) + + +def get_data(filename): + import csv + with open(filename,'r') as f: + lines = list(csv.reader(f, delimiter = ',', skipinitialspace = True)) # Printing Specific Part of CSV_file + #print(lines[0][4]) # Printing last line of second column + for i in range(len(lines)-5): # For printing a range of rows except 10 last rows of second column + #print(lines[i][4]) # Print the 4th column of every row except last 3 rows + C = int(lines[i][4]) + if C != AoA_point_3: + Angle_diff = C - AoA_point_3 + print(Angle_diff) + +get_data('test2.txt') diff --git a/example2.py b/example2.py new file mode 100755 index 0000000..709ef29 --- /dev/null +++ b/example2.py @@ -0,0 +1,9 @@ +import numpy as np + +a = np.array([5, 10, 15, 20, 25]) # Create a rank 1 array +b = a / 5 + +print("with numpy: a = {} b = {} \n".format(a,b)) + +import sys +sys.exit() diff --git a/example_test.py b/example_test.py new file mode 100755 index 0000000..fc0bbc7 --- /dev/null +++ b/example_test.py @@ -0,0 +1,14 @@ +AOA_Point_3 = -90 + +def get_data(filename): + import csv + with open(filename,'r') as f: + lines = list(csv.reader(f, delimiter = ',', skipinitialspace = True)) # Printing Specific Part of CSV_file + #print(lines[0][4]) # Printing last line of second column + for i in range(len(lines)-5): # For printing a range of rows except 10 last rows of second column + C = int(lines[i][4]) + Angle_diff = C - AOA_Point_3 + print(Angle_diff) + #return + +get_data('test2.txt') diff --git a/new 1.py b/new 1.py new file mode 100755 index 0000000..63554f0 --- /dev/null +++ b/new 1.py @@ -0,0 +1,14 @@ +x = 3 +print(type(x)) # Prints "<class 'int'>" +print(x) # Prints "3" +print(x + 1) # Addition; prints "4" +print(x - 1) # Subtraction; prints "2" +print(x * 2) # Multiplication; prints "6" +print(x ** 2) # Exponentiation; prints "9" +x += 1 +print(x) # Prints "4" +x *= 2 +print(x) # Prints "8" +y = 2.5 +print(type(y)) # Prints "<class 'float'>" +print(y, y + 1, y * 2, y ** 2) # Prints "2.5 3.5 5.0 6.25" \ No newline at end of file diff --git a/pyvenv.cfg b/pyvenv.cfg new file mode 100755 index 0000000..ded0f0b --- /dev/null +++ b/pyvenv.cfg @@ -0,0 +1,3 @@ +home = C:\Users\amer1\AppData\Local\Programs\Python\Python37-32 +include-system-site-packages = false +version = 3.7.3 diff --git a/test2.txt b/test2.txt new file mode 100755 index 0000000..7554f1d --- /dev/null +++ b/test2.txt @@ -0,0 +1,531 @@ +$ORIEN,54:6C:0E:A0:42:58,0,2668,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2669,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2670,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2671,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2672,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2673,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2674,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2675,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2676,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2677,-88,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2678,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2679,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2680,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2681,-87,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2682,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2683,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2684,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2685,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2686,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2687,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2688,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2689,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2690,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2691,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2692,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2693,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2694,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2695,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2696,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2697,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2698,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2699,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2700,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2701,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2702,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2703,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2704,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2705,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2706,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2707,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2708,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2709,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2710,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2711,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2712,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2713,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2714,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2715,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2716,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2717,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2718,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2719,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2720,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2721,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2722,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2723,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2724,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2725,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2726,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2727,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2728,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2729,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2730,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2731,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2732,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2733,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2734,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2735,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2736,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2737,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2738,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2739,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2740,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2741,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2742,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2743,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2744,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2745,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2746,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2747,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2748,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2749,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2750,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2751,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2752,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2753,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2754,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2755,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2756,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2757,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2758,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2759,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2760,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2761,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2762,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2763,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2764,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2765,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2766,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2767,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2768,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2769,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2770,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2771,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2772,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2773,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2774,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2775,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2776,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2777,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2778,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2779,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2780,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2781,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2782,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2783,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2784,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2785,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2786,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2787,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2788,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2789,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2790,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2791,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2792,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2793,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2794,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2795,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2796,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2797,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2798,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2799,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2800,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2801,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2802,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2803,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2804,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2805,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2806,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2807,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2808,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2809,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2810,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2811,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2812,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2813,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2814,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2815,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2816,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2817,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2818,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2819,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2820,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2821,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2822,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2823,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2824,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2825,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2826,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2827,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2828,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2829,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2830,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2831,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2832,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2833,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2834,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2835,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2836,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2837,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2838,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2839,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2840,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2841,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2842,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2843,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2844,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2845,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2846,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2847,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2848,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2849,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2850,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2851,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2852,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2853,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2854,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2855,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2856,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2857,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2858,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2859,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2860,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2861,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2862,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2863,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2864,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2865,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2866,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2867,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2868,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2869,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2870,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2871,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2872,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2873,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2874,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2875,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2876,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2877,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2878,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2879,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2880,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2881,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2882,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2883,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2884,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2885,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2886,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2887,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2888,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2889,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2890,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2891,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2892,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2893,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2894,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2895,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2896,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2897,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2898,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2899,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2900,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2901,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2902,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2903,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2904,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2905,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2906,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2907,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2908,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2909,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2910,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2911,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2912,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2913,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2914,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2915,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2916,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2917,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2918,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2919,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2920,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2921,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2922,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2923,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2924,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2925,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2926,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2927,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2928,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2929,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2930,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2931,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2932,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2933,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2934,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2935,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2936,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2937,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2938,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2939,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2940,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2941,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2942,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2943,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2944,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2945,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2946,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2947,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2948,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2949,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2950,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2951,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2952,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2953,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2954,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2955,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2956,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2957,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2958,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2959,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2960,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2961,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2962,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2963,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2964,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2965,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2966,-88,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2967,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2968,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2969,-88,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2970,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2971,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2972,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2973,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2974,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2975,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2976,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2977,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2978,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2979,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2980,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2981,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2982,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2983,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2984,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2985,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2986,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2987,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2988,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2989,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2990,-91,-62,0,0,0,0,0 +$ORIEN,54:6B:8E:A0:42:58,0,2991,-90,-61,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2992,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2993,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2994,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2995,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2996,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2997,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,2998,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,2999,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3000,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3001,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3002,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3003,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3004,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3005,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3006,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3007,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3008,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3009,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3010,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3011,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3012,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3013,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3014,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3015,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3016,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3017,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3018,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3019,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3020,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3021,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3022,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3023,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3024,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3025,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3026,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3027,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3028,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3029,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3030,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3031,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3032,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3033,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3034,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3035,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3036,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3037,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3038,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3039,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3040,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3041,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3042,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3043,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3044,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3045,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3046,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3047,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3048,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3049,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3050,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3051,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3052,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3053,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3054,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3055,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3056,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3057,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3058,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3059,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3060,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3061,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3062,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3063,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3064,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3065,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3066,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3067,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3068,-88,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3069,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3070,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3071,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3072,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3073,-88,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3074,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3075,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3076,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3077,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3078,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3079,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3080,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3081,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3082,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3083,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3084,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3085,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3086,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3087,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3088,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3089,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3090,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3091,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3092,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3093,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3094,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3095,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3096,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3097,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3098,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3099,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3100,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3101,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3102,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3103,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3104,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3105,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3106,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3107,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3108,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3109,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3110,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3111,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3112,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3113,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3114,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3115,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3116,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3117,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3118,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3119,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3120,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3121,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3122,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3123,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3124,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3125,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3126,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3127,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3128,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3129,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3130,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3131,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3132,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3133,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3134,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3135,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3136,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3137,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3138,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3139,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3140,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3141,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3142,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3143,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3144,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3145,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3146,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3147,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3148,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3149,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3150,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3151,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3152,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3153,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3154,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3155,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3156,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3157,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3158,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3159,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3160,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3161,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3162,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3163,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3164,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3165,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3166,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3167,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3168,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3169,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3170,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3171,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3172,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3173,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3174,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3175,-89,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3176,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3177,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3178,-89,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3179,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3180,-90,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3181,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3182,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3183,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3184,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3185,-90,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3186,-91,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3187,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3188,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3189,-91,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3190,-92,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3191,-92,-62,0,0,0,0,0 +$ORIEN,54:6C:0E:A0:42:58,0,3192,-93,-62,0,0,0,0,1 +$ORIEN,54:6C:0E:A0:42:58,0,3193,-93,-62,0,0,0,0,0 + +AoA Scan Stopped +Toggle AoA Scan -> + +