diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index c7eca478..00000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!Pipfile* diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 554b1b0f..c513af07 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,9 +34,21 @@ jobs: - run: echo "PYTHONPATH=${GITHUB_WORKSPACE}" >> $GITHUB_ENV - run: make prereqs - run: make version - - run: make install - - run: make lint - run: make test + lint: + runs-on: ubuntu-latest + name: Lint + steps: + - uses: actions/checkout@v2 + - run: git fetch --prune --unshallow + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - run: echo "PYTHONPATH=${GITHUB_WORKSPACE}" >> $GITHUB_ENV + - run: make prereqs + - run: make version + - run: make yarn + - run: make lint selenium: runs-on: ubuntu-latest steps: @@ -52,6 +64,11 @@ jobs: - run: make -C selenium test-env-up - run: make -C selenium jupyter-up - run: make -C selenium test + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: selenium-logs + path: '**/*.log' distributions: needs: test runs-on: ubuntu-latest @@ -63,18 +80,14 @@ jobs: python-version: 3.8.x - run: echo "PYTHONPATH=${GITHUB_WORKSPACE}" >> $GITHUB_ENV - run: make prereqs - - run: pipenv clean - - run: pipenv install --skip-lock --dev - - run: pipenv run pip install -U 'SecretStorage>=3' - - run: git reset --hard HEAD - run: make dist id: create_dist - uses: actions/upload-artifact@v2 with: name: distributions path: dist/ - - run: pipenv run pip install -vvv ${{ steps.create_dist.outputs.whl }} - - run: pipenv run python -c 'import rsconnect_jupyter;print(rsconnect_jupyter.__version__)' + - run: pip install -vvv ${{ steps.create_dist.outputs.whl }} + - run: python -c 'import rsconnect_jupyter;print(rsconnect_jupyter.__version__)' - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') id: create_release uses: actions/create-release@v1 diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml index 7858dd1a..8e178245 100644 --- a/.github/workflows/snyk.yml +++ b/.github/workflows/snyk.yml @@ -16,18 +16,11 @@ jobs: with: fetch-depth: 0 - - name: Install pipenv - run: | - python -m pip install --upgrade pipenv - - - name: Install Pipfile dependencies (as required by Snyk) - run: pipenv install - - name: Run Snyk uses: snyk/actions/python@master with: command: monitor - args: --file=Pipfile --project-name=python --org=${{ env.SNYK_ORG }} + args: --file=requirements-dev.txt --project-name=python --org=${{ env.SNYK_ORG }} ui: runs-on: ubuntu-latest steps: diff --git a/Dockerfile b/Dockerfile index 0cf96ffd..1d05ef9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,14 +22,11 @@ RUN useradd --password password \ chown ${NB_UID}:${NB_GID} /rsconnect_jupyter USER ${NB_UID}:${NB_GID} -WORKDIR /rsconnect_jupyter ENV WORKON_HOME=/home/builder \ - PIPENV_DONT_LOAD_ENV=1 \ - PIPENV_SHELL=/bin/bash \ PATH=/home/builder/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ PYTHONPATH=/rsconnect_jupyter -COPY Pipfile Pipfile -COPY Pipfile.lock Pipfile.lock -RUN python -m pip install -I -U pip pipenv && \ - pipenv install --dev --python=/usr/local/bin/python && \ - rm -vf Pipfile* +COPY requirements.txt . +COPY requirements-dev.txt . +RUN /usr/local/bin/python -m pip install -I -U pip && \ + /usr/local/bin/python -m pip install -r requirements-dev.txt +WORKDIR /rsconnect_jupyter diff --git a/Makefile b/Makefile index c0fcc67c..b8d2df0f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ IMAGE := rstudio/rsconnect-jupyter-py NOTEBOOKS_DIR := /notebooks PORT := $(shell printenv PORT || echo 9999) S3_PREFIX := s3://rstudio-connect-downloads/connect/rsconnect-jupyter -VERSION := $(shell pipenv run python setup.py --version 2>/dev/null || echo 'NOTSET') +VERSION := $(shell python setup.py --version 2>/dev/null || echo 'NOTSET') BDIST_WHEEL := dist/rsconnect_jupyter-$(VERSION)-py2.py3-none-any.whl JUPYTER_LOG_LEVEL ?= INFO @@ -17,16 +17,14 @@ export SOURCE_DATE_EPOCH PYTHONPATH ?= $(CURDIR) export PYTHONPATH - .PHONY: prereqs prereqs: pip install -U pip - pip install -U pipenv - + pip install -r requirements-dev.txt .PHONY: install-latest-rsconnect-python install-latest-rsconnect-python: - pipenv run pip install -U https://cdn.rstudio.com/connect/rsconnect-python/latest/rsconnect_python-latest-py2.py3-none-any.whl + pip install -U https://cdn.rstudio.com/connect/rsconnect-python/latest/rsconnect_python-latest-py2.py3-none-any.whl .PHONY: clean clean: @@ -45,12 +43,8 @@ image%: --build-arg PY_VERSION=$* \ . -.PHONY: all-tests -all-tests: test3.7 test3.8 test3.9 test3.10 test3.11 - -.PHONY: test test: version-frontend - pipenv run pytest -vv --cov=rsconnect_jupyter tests/ + pytest -vv --cov=rsconnect_jupyter tests/ .PHONY: test-selenium test-selenium: @@ -64,36 +58,29 @@ test-selenium: # exported as a point of reference instead. .PHONY: dist dist: version-frontend - pipenv run python setup.py bdist_wheel - pipenv run twine check $(BDIST_WHEEL) + rm -vf dist/*.whl + python setup.py bdist_wheel + twine check $(BDIST_WHEEL) rm -vf dist/*.egg @echo "::set-output name=whl::$(BDIST_WHEEL)" @echo "::set-output name=whl_basename::$(notdir $(BDIST_WHEEL))" -.PHONY: run run: install - mkdir -p $(NOTEBOOKS_DIR) - pipenv run jupyter notebook \ + jupyter notebook \ -y \ --log-level=$(JUPYTER_LOG_LEVEL) \ - --notebook-dir=$(NOTEBOOKS_DIR) \ + --notebook-dir=./notebooks3 \ --ip='0.0.0.0' \ --port=9999 \ --no-browser \ --NotebookApp.token='' -.PHONY: run-local -run-local: NOTEBOOKS_DIR := $(CURDIR)/notebooks3.8 -run-local: run - .PHONY: install -install: yarn - pipenv install --dev - $(MAKE) install-latest-rsconnect-python - $(MAKE) version-frontend - pipenv run jupyter nbextension install --symlink --user --py rsconnect_jupyter - pipenv run jupyter nbextension enable --py rsconnect_jupyter - pipenv run jupyter serverextension enable --py rsconnect_jupyter +install: version-frontend + jupyter nbextension uninstall rsconnect_jupyter || true + jupyter nbextension install --symlink --user --py rsconnect_jupyter + jupyter nbextension enable --py rsconnect_jupyter + jupyter serverextension enable --py rsconnect_jupyter build/mock-connect/bin/flask: bash -c '\ @@ -121,12 +108,12 @@ lint-js: .PHONY: lint-py lint-py: - pipenv run black --check --diff ./rsconnect_jupyter - pipenv run flake8 ./rsconnect_jupyter + black --check --diff ./rsconnect_jupyter + flake8 ./rsconnect_jupyter .PHONY: fmt fmt: - pipenv run black ./rsconnect_jupyter + black ./rsconnect_jupyter ## Specify that Docker runs with the calling user's uid/gid to avoid file ## permission issues on Linux dev hosts. diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 4e006dd2..00000000 --- a/Pipfile +++ /dev/null @@ -1,35 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] -black = {version = "22.1.0", markers = "python_version >= '3.6'"} -coverage = "*" -flake8 = "*" -importlib-metadata = "*" -ipython = "*" -pytest = "*" -pytest-cov = "*" -setuptools_scm = "*" -toml = "*" -twine = "*" -wheel = "*" -# https://github.com/rstudio/rsconnect-jupyter/issues/316 -traitlets = ">=5.1.1" - -[packages] -nbconvert = ">=5.0" -nbformat = "*" -notebook = ">=6.1.5, <7.0.0" -rsconnect-python = ">=1.7.1" -six = "*" -# Dependabot fixes -py = ">=1.10.0" -Pygments = ">=2.7.4" -jinja2 = ">=2.11.3" -bleach = ">=3.3.0" -cryptography = ">=3.2" - -[pipenv] -allow_prereleases = true diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index fcdd05a9..00000000 --- a/Pipfile.lock +++ /dev/null @@ -1,1474 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "2c02d8de66ca693b68453941de77c57abeaae88a222b73c9650f3e608e96b6d9" - }, - "pipfile-spec": 6, - "requires": {}, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "argon2-cffi": { - "hashes": [ - "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80", - "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3.0" - }, - "argon2-cffi-bindings": { - "hashes": [ - "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670", - "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f", - "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583", - "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194", - "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", - "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a", - "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", - "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5", - "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", - "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7", - "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", - "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", - "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", - "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", - "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", - "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", - "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d", - "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", - "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb", - "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", - "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351" - ], - "markers": "python_version >= '3.6'", - "version": "==21.2.0" - }, - "asttokens": { - "hashes": [ - "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c", - "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5" - ], - "version": "==2.0.5" - }, - "attrs": { - "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" - }, - "backcall": { - "hashes": [ - "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", - "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" - ], - "version": "==0.2.0" - }, - "black": { - "hashes": [ - "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2", - "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71", - "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6", - "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5", - "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912", - "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866", - "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d", - "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0", - "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321", - "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8", - "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd", - "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3", - "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba", - "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0", - "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5", - "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a", - "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28", - "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c", - "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1", - "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab", - "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f", - "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61", - "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==22.1.0" - }, - "bleach": { - "hashes": [ - "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", - "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" - ], - "index": "pypi", - "version": "==4.1.0" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" - }, - "click": { - "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" - ], - "markers": "python_version >= '3.6'", - "version": "==8.0.3" - }, - "cryptography": { - "hashes": [ - "sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3", - "sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31", - "sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac", - "sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf", - "sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316", - "sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca", - "sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638", - "sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94", - "sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12", - "sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173", - "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b", - "sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a", - "sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f", - "sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2", - "sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9", - "sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46", - "sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903", - "sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3", - "sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1", - "sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee" - ], - "index": "pypi", - "version": "==36.0.1" - }, - "debugpy": { - "hashes": [ - "sha256:01e98c594b3e66d529e40edf314f849cd1a21f7a013298df58cd8e263bf8e184", - "sha256:16db27b4b91991442f91d73604d32080b30de655aca9ba821b1972ea8171021b", - "sha256:17a25ce9d7714f92fc97ef00cc06269d7c2b163094990ada30156ed31d9a5030", - "sha256:194f95dd3e84568b5489aab5689a3a2c044e8fdc06f1890b8b4f70b6b89f2778", - "sha256:1ec3a086e14bba6c472632025b8fe5bdfbaef2afa1ebd5c6615ce6ed8d89bc67", - "sha256:23df67fc56d59e386c342428a7953c2c06cc226d8525b11319153e96afb65b0c", - "sha256:26fbe53cca45a608679094791ce587b6e2798acd1d4777a8b303b07622e85182", - "sha256:2b073ad5e8d8c488fbb6a116986858bab0c9c4558f28deb8832c7a5a27405bd6", - "sha256:318f81f37341e4e054b4267d39896b73cddb3612ca13b39d7eea45af65165e1d", - "sha256:3a457ad9c0059a21a6c7d563c1f18e924f5cf90278c722bd50ede6f56b77c7fe", - "sha256:4404a62fb5332ea5c8c9132290eef50b3a0ba38cecacad5529e969a783bcbdd7", - "sha256:5d76a4fd028d8009c3faf1185b4b78ceb2273dd2499447664b03939e0368bb90", - "sha256:70b422c63a833630c33e3f9cdbd9b6971f8c5afd452697e464339a21bbe862ba", - "sha256:82f5f9ce93af6861a0713f804e62ab390bb12a17f113153e47fea8bbb1dfbe36", - "sha256:a2aa64f6d2ca7ded8a7e8a4e7cae3bc71866b09876b7b05cecad231779cb9156", - "sha256:b2df2c373e85871086bd55271c929670cd4e1dba63e94a08d442db830646203b", - "sha256:b5b3157372e0e0a1297a8b6b5280bcf1d35a40f436c7973771c972726d1e32d5", - "sha256:d2b09e91fbd1efa4f4fda121d49af89501beda50c18ed7499712c71a4bf3452e", - "sha256:d876db8c312eeb02d85611e0f696abe66a2c1515e6405943609e725d5ff36f2a", - "sha256:f3a3dca9104aa14fd4210edcce6d9ce2b65bd9618c0b222135a40b9d6e2a9eeb", - "sha256:f73988422b17f071ad3c4383551ace1ba5ed810cbab5f9c362783d22d40a08dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.5.1" - }, - "decorator": { - "hashes": [ - "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", - "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" - ], - "markers": "python_version >= '3.5'", - "version": "==5.1.1" - }, - "defusedxml": { - "hashes": [ - "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", - "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.7.1" - }, - "entrypoints": { - "hashes": [ - "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4", - "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f" - ], - "markers": "python_version >= '3.6'", - "version": "==0.4" - }, - "executing": { - "hashes": [ - "sha256:32fc6077b103bd19e6494a72682d66d5763cf20a106d5aa7c5ccbea4e47b0df7", - "sha256:c23bf42e9a7b9b212f185b1b2c3c91feb895963378887bb10e64a2e612ec0023" - ], - "version": "==0.8.2" - }, - "importlib-resources": { - "hashes": [ - "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", - "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" - ], - "markers": "python_version < '3.9'", - "version": "==5.4.0" - }, - "ipykernel": { - "hashes": [ - "sha256:4fae9df6e192837552b2406a6052d707046dd2e153860be73c68484bacba18ed", - "sha256:f95070a2dfd3147f8ab19f18ee46733310813758593745e07ec18fb08b409f1d" - ], - "markers": "python_version >= '3.7'", - "version": "==6.9.1" - }, - "ipython": { - "hashes": [ - "sha256:ab564d4521ea8ceaac26c3a2c6e5ddbca15c8848fd5a5cc325f960da88d42974", - "sha256:c503a0dd6ccac9c8c260b211f2dd4479c042b49636b097cc9a0d55fe62dff64c" - ], - "markers": "python_version >= '3.8'", - "version": "==8.0.1" - }, - "ipython-genutils": { - "hashes": [ - "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", - "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" - ], - "version": "==0.2.0" - }, - "jedi": { - "hashes": [ - "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d", - "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab" - ], - "markers": "python_version >= '3.6'", - "version": "==0.18.1" - }, - "jinja2": { - "hashes": [ - "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", - "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" - ], - "index": "pypi", - "version": "==3.0.3" - }, - "jsonschema": { - "hashes": [ - "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83", - "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823" - ], - "markers": "python_version >= '3.7'", - "version": "==4.4.0" - }, - "jupyter-client": { - "hashes": [ - "sha256:4ea61033726c8e579edb55626d8ee2e6bf0a83158ddf3751b8dd46b2c5cd1e96", - "sha256:d56f1c57bef42ff31e61b1185d3348a5b2bcde7c9a05523ae4dbe5ee0871797c" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==7.1.2" - }, - "jupyter-core": { - "hashes": [ - "sha256:d69baeb9ffb128b8cd2657fcf2703f89c769d1673c851812119e3a2a0e93ad9a", - "sha256:f875e4d27e202590311d468fa55f90c575f201490bd0c18acabe4e318db4a46d" - ], - "markers": "python_version >= '3.6'", - "version": "==4.9.2" - }, - "jupyterlab-pygments": { - "hashes": [ - "sha256:abfb880fd1561987efaefcb2d2ac75145d2a5d0139b1876d5be806e32f630008", - "sha256:cfcda0873626150932f438eccf0f8bf22bfa92345b814890ab360d666b254146" - ], - "version": "==0.1.2" - }, - "markupsafe": { - "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", - "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", - "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", - "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", - "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", - "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", - "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", - "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", - "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", - "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", - "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", - "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", - "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", - "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", - "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", - "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", - "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", - "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", - "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "matplotlib-inline": { - "hashes": [ - "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee", - "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c" - ], - "markers": "python_version >= '3.5'", - "version": "==0.1.3" - }, - "mistune": { - "hashes": [ - "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", - "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" - ], - "version": "==0.8.4" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "nbclient": { - "hashes": [ - "sha256:03e857bea3012377289daa1e1c1651f4fc0295bcd109ccd36a337efcdbebaed7", - "sha256:751516992f34b58172bad54eef1e4bf7e4f4460d58e255ca1a4e5c9649476007" - ], - "markers": "python_version >= '3.7'", - "version": "==0.5.11" - }, - "nbconvert": { - "hashes": [ - "sha256:7b006ae9979af56200e7fa3db39d9d12c99e811e8843b05dbe518e5b754bcb2e", - "sha256:eb2803db18f6facce6bf3b01b684fe47907994bd156d15eaccdf011e3d7f8164" - ], - "index": "pypi", - "version": "==6.4.2" - }, - "nbformat": { - "hashes": [ - "sha256:b516788ad70771c6250977c1374fcca6edebe6126fd2adb5a69aa5c2356fd1c8", - "sha256:eb8447edd7127d043361bc17f2f5a807626bc8e878c7709a1c647abda28a9171" - ], - "index": "pypi", - "version": "==5.1.3" - }, - "nest-asyncio": { - "hashes": [ - "sha256:3fdd0d6061a2bb16f21fe8a9c6a7945be83521d81a0d15cff52e9edee50101d6", - "sha256:f969f6013a16fadb4adcf09d11a68a4f617c6049d7af7ac2c676110169a63abd" - ], - "markers": "python_version >= '3.5'", - "version": "==1.5.4" - }, - "notebook": { - "hashes": [ - "sha256:1e985c9dc6f678bdfffb9dc657306b5469bfa62d73e03f74e8defbf76d284312", - "sha256:3e702fcc54b8ae597533c3864793b7a1e971dec9e112f67235828d8a798fd654" - ], - "index": "pypi", - "version": "==6.4.8" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pandocfilters": { - "hashes": [ - "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38", - "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.0" - }, - "parso": { - "hashes": [ - "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", - "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" - ], - "markers": "python_version >= '3.6'", - "version": "==0.8.3" - }, - "pathspec": { - "hashes": [ - "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" - ], - "version": "==0.9.0" - }, - "pexpect": { - "hashes": [ - "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", - "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" - ], - "markers": "sys_platform != 'win32'", - "version": "==4.8.0" - }, - "pickleshare": { - "hashes": [ - "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", - "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" - ], - "version": "==0.7.5" - }, - "pip": { - "hashes": [ - "sha256:c146f331f0805c77017c6bb9740cec4a49a0d4582d0c3cc8244b057f83eca359", - "sha256:f29d589df8c8ab99c060e68ad294c4a9ed896624f6368c5349d70aa581b333d0" - ], - "markers": "python_version >= '3.7'", - "version": "==22.0.3" - }, - "platformdirs": { - "hashes": [ - "sha256:30671902352e97b1eafd74ade8e4a694782bd3471685e78c32d0fdfd3aa7e7bb", - "sha256:8ec11dfba28ecc0715eb5fb0147a87b1bf325f349f3da9aab2cd6b50b96b692b" - ], - "markers": "python_version >= '3.7'", - "version": "==2.5.0" - }, - "prometheus-client": { - "hashes": [ - "sha256:357a447fd2359b0a1d2e9b311a0c5778c330cfbe186d880ad5a6b39884652316", - "sha256:ada41b891b79fca5638bd5cfe149efa86512eaa55987893becd2c6d8d0a5dfc5" - ], - "markers": "python_version >= '3.6'", - "version": "==0.13.1" - }, - "prompt-toolkit": { - "hashes": [ - "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c", - "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.28" - }, - "ptyprocess": { - "hashes": [ - "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", - "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" - ], - "markers": "os_name != 'nt'", - "version": "==0.7.0" - }, - "pure-eval": { - "hashes": [ - "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", - "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" - ], - "version": "==0.2.2" - }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "index": "pypi", - "version": "==1.11.0" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.21" - }, - "pygments": { - "hashes": [ - "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65", - "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a" - ], - "index": "pypi", - "version": "==2.11.2" - }, - "pyparsing": { - "hashes": [ - "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea", - "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.7" - }, - "pyrsistent": { - "hashes": [ - "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", - "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc", - "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e", - "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26", - "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec", - "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286", - "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045", - "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec", - "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8", - "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c", - "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca", - "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22", - "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a", - "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96", - "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc", - "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1", - "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07", - "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6", - "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b", - "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5", - "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6" - ], - "markers": "python_version >= '3.7'", - "version": "==0.18.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" - }, - "pyzmq": { - "hashes": [ - "sha256:08c4e315a76ef26eb833511ebf3fa87d182152adf43dedee8d79f998a2162a0b", - "sha256:0ca6cd58f62a2751728016d40082008d3b3412a7f28ddfb4a2f0d3c130f69e74", - "sha256:1621e7a2af72cced1f6ec8ca8ca91d0f76ac236ab2e8828ac8fe909512d566cb", - "sha256:18cd854b423fce44951c3a4d3e686bac8f1243d954f579e120a1714096637cc0", - "sha256:2841997a0d85b998cbafecb4183caf51fd19c4357075dfd33eb7efea57e4c149", - "sha256:2b97502c16a5ec611cd52410bdfaab264997c627a46b0f98d3f666227fd1ea2d", - "sha256:3a4c9886d61d386b2b493377d980f502186cd71d501fffdba52bd2a0880cef4f", - "sha256:3c1895c95be92600233e476fe283f042e71cf8f0b938aabf21b7aafa62a8dac9", - "sha256:42abddebe2c6a35180ca549fadc7228d23c1e1f76167c5ebc8a936b5804ea2df", - "sha256:468bd59a588e276961a918a3060948ae68f6ff5a7fa10bb2f9160c18fe341067", - "sha256:480b9931bfb08bf8b094edd4836271d4d6b44150da051547d8c7113bf947a8b0", - "sha256:53f4fd13976789ffafedd4d46f954c7bb01146121812b72b4ddca286034df966", - "sha256:62bcade20813796c426409a3e7423862d50ff0639f5a2a95be4b85b09a618666", - "sha256:67db33bea0a29d03e6eeec55a8190e033318cee3cbc732ba8fd939617cbf762d", - "sha256:6b217b8f9dfb6628f74b94bdaf9f7408708cb02167d644edca33f38746ca12dd", - "sha256:7661fc1d5cb73481cf710a1418a4e1e301ed7d5d924f91c67ba84b2a1b89defd", - "sha256:76c532fd68b93998aab92356be280deec5de8f8fe59cd28763d2cc8a58747b7f", - "sha256:79244b9e97948eaf38695f4b8e6fc63b14b78cc37f403c6642ba555517ac1268", - "sha256:7c58f598d9fcc52772b89a92d72bf8829c12d09746a6d2c724c5b30076c1f11d", - "sha256:7dc09198e4073e6015d9a8ea093fc348d4e59de49382476940c3dd9ae156fba8", - "sha256:80e043a89c6cadefd3a0712f8a1322038e819ebe9dbac7eca3bce1721bcb63bf", - "sha256:851977788b9caa8ed011f5f643d3ee8653af02c5fc723fa350db5125abf2be7b", - "sha256:8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c", - "sha256:902319cfe23366595d3fa769b5b751e6ee6750a0a64c5d9f757d624b2ac3519e", - "sha256:954e73c9cd4d6ae319f1c936ad159072b6d356a92dcbbabfd6e6204b9a79d356", - "sha256:ab888624ed68930442a3f3b0b921ad7439c51ba122dbc8c386e6487a658e4a4e", - "sha256:acebba1a23fb9d72b42471c3771b6f2f18dcd46df77482612054bd45c07dfa36", - "sha256:b4ebed0977f92320f6686c96e9e8dd29eed199eb8d066936bac991afc37cbb70", - "sha256:badb868fff14cfd0e200eaa845887b1011146a7d26d579aaa7f966c203736b92", - "sha256:be4e0f229cf3a71f9ecd633566bd6f80d9fa6afaaff5489492be63fe459ef98c", - "sha256:c0f84360dcca3481e8674393bdf931f9f10470988f87311b19d23cda869bb6b7", - "sha256:c1e41b32d6f7f9c26bc731a8b529ff592f31fc8b6ef2be9fa74abd05c8a342d7", - "sha256:c88fa7410e9fc471e0858638f403739ee869924dd8e4ae26748496466e27ac59", - "sha256:cf98fd7a6c8aaa08dbc699ffae33fd71175696d78028281bc7b832b26f00ca57", - "sha256:d072f7dfbdb184f0786d63bda26e8a0882041b1e393fbe98940395f7fab4c5e2", - "sha256:d1b5d457acbadcf8b27561deeaa386b0217f47626b29672fa7bd31deb6e91e1b", - "sha256:d3dcb5548ead4f1123851a5ced467791f6986d68c656bc63bfff1bf9e36671e2", - "sha256:d6157793719de168b199194f6b6173f0ccd3bf3499e6870fac17086072e39115", - "sha256:d728b08448e5ac3e4d886b165385a262883c34b84a7fe1166277fe675e1c197a", - "sha256:de8df0684398bd74ad160afdc2a118ca28384ac6f5e234eb0508858d8d2d9364", - "sha256:e6a02cf7271ee94674a44f4e62aa061d2d049001c844657740e156596298b70b", - "sha256:ea12133df25e3a6918718fbb9a510c6ee5d3fdd5a346320421aac3882f4feeea", - "sha256:ea5a79e808baef98c48c884effce05c31a0698c1057de8fc1c688891043c1ce1", - "sha256:f43b4a2e6218371dd4f41e547bd919ceeb6ebf4abf31a7a0669cd11cd91ea973", - "sha256:f762442bab706fd874064ca218b33a1d8e40d4938e96c24dafd9b12e28017f45", - "sha256:f89468059ebc519a7acde1ee50b779019535db8dcf9b8c162ef669257fef7a93", - "sha256:f907c7359ce8bf7f7e63c82f75ad0223384105f5126f313400b7e8004d9b33c3" - ], - "markers": "python_version >= '3.6'", - "version": "==22.3.0" - }, - "rsconnect-python": { - "hashes": [ - "sha256:3fe3c7b7fc73fc243ae257192901764bcdef4e8b0205350069701c28c4bc8d71" - ], - "index": "pypi", - "version": "==1.7.1" - }, - "semver": { - "hashes": [ - "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4", - "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.13.0" - }, - "send2trash": { - "hashes": [ - "sha256:56215329f48b4b147d93719fe901d7de84cae0048cad6e6c31e6d593d9f2dcbb", - "sha256:9c9f667f7211232dda8add62116e835304c8015210cbd8612847aaf19875a487" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.8.1b0" - }, - "setuptools": { - "hashes": [ - "sha256:80743e57120665fa65665286369a0734bce0e7a629ad36507fb7a4b65e7d2e3b", - "sha256:93b1a3037230bf9aa07327b9fc58f527d5f4e22d36705b55d55ba3ece8606ca6" - ], - "markers": "python_version >= '3.7'", - "version": "==60.9.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "index": "pypi", - "version": "==1.16.0" - }, - "stack-data": { - "hashes": [ - "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12", - "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e" - ], - "version": "==0.2.0" - }, - "terminado": { - "hashes": [ - "sha256:5b82b5c6e991f0705a76f961f43262a7fb1e55b093c16dca83f16384a7f39b7b", - "sha256:f446b522b50a7aa68b5def0a02893978fb48cb82298b0ebdae13003c6ee6f198" - ], - "markers": "python_version >= '3.7'", - "version": "==0.13.1" - }, - "testpath": { - "hashes": [ - "sha256:1acf7a0bcd3004ae8357409fc33751e16d37ccc650921da1094a86581ad1e417", - "sha256:8044f9a0bab6567fc644a3593164e872543bb44225b0e24846e2c89237937589" - ], - "markers": "python_version >= '3.5'", - "version": "==0.5.0" - }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.1" - }, - "tornado": { - "hashes": [ - "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb", - "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c", - "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288", - "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95", - "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558", - "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe", - "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791", - "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d", - "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326", - "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b", - "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4", - "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c", - "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910", - "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5", - "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c", - "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0", - "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675", - "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd", - "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f", - "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c", - "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea", - "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6", - "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05", - "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd", - "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575", - "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a", - "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37", - "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795", - "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f", - "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32", - "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c", - "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01", - "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4", - "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2", - "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921", - "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085", - "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df", - "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102", - "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5", - "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68", - "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5" - ], - "markers": "python_version >= '3.5'", - "version": "==6.1" - }, - "traitlets": { - "hashes": [ - "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7", - "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033" - ], - "markers": "python_version >= '3.7'", - "version": "==5.1.1" - }, - "typing-extensions": { - "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" - ], - "markers": "python_version < '3.10'", - "version": "==4.1.1" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, - "zipp": { - "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" - ], - "markers": "python_version < '3.10'", - "version": "==3.7.0" - } - }, - "develop": { - "asttokens": { - "hashes": [ - "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c", - "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5" - ], - "version": "==2.0.5" - }, - "attrs": { - "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" - }, - "backcall": { - "hashes": [ - "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", - "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" - ], - "version": "==0.2.0" - }, - "black": { - "hashes": [ - "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2", - "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71", - "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6", - "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5", - "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912", - "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866", - "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d", - "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0", - "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321", - "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8", - "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd", - "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3", - "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba", - "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0", - "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5", - "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a", - "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28", - "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c", - "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1", - "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab", - "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f", - "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61", - "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==22.1.0" - }, - "bleach": { - "hashes": [ - "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", - "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" - ], - "index": "pypi", - "version": "==4.1.0" - }, - "certifi": { - "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" - ], - "version": "==2021.10.8" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" - ], - "markers": "python_version >= '3'", - "version": "==2.0.12" - }, - "click": { - "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" - ], - "markers": "python_version >= '3.6'", - "version": "==8.0.3" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.4.4" - }, - "coverage": { - "hashes": [ - "sha256:1245ab82e8554fa88c4b2ab1e098ae051faac5af829efdcf2ce6b34dccd5567c", - "sha256:1bc6d709939ff262fd1432f03f080c5042dc6508b6e0d3d20e61dd045456a1a0", - "sha256:25e73d4c81efa8ea3785274a2f7f3bfbbeccb6fcba2a0bdd3be9223371c37554", - "sha256:276b13cc085474e482566c477c25ed66a097b44c6e77132f3304ac0b039f83eb", - "sha256:2aed4761809640f02e44e16b8b32c1a5dee5e80ea30a0ff0912158bde9c501f2", - "sha256:2dd70a167843b4b4b2630c0c56f1b586fe965b4f8ac5da05b6690344fd065c6b", - "sha256:352c68e233409c31048a3725c446a9e48bbff36e39db92774d4f2380d630d8f8", - "sha256:3f2b05757c92ad96b33dbf8e8ec8d4ccb9af6ae3c9e9bd141c7cc44d20c6bcba", - "sha256:448d7bde7ceb6c69e08474c2ddbc5b4cd13c9e4aa4a717467f716b5fc938a734", - "sha256:463e52616ea687fd323888e86bf25e864a3cc6335a043fad6bbb037dbf49bbe2", - "sha256:482fb42eea6164894ff82abbcf33d526362de5d1a7ed25af7ecbdddd28fc124f", - "sha256:56c4a409381ddd7bbff134e9756077860d4e8a583d310a6f38a2315b9ce301d0", - "sha256:56d296cbc8254a7dffdd7bcc2eb70be5a233aae7c01856d2d936f5ac4e8ac1f1", - "sha256:5e15d424b8153756b7c903bde6d4610be0c3daca3986173c18dd5c1a1625e4cd", - "sha256:618eeba986cea7f621d8607ee378ecc8c2504b98b3fdc4952b30fe3578304687", - "sha256:61d47a897c1e91f33f177c21de897267b38fbb45f2cd8e22a710bcef1df09ac1", - "sha256:621f6ea7260ea2ffdaec64fe5cb521669984f567b66f62f81445221d4754df4c", - "sha256:6a5cdc3adb4f8bb8d8f5e64c2e9e282bc12980ef055ec6da59db562ee9bdfefa", - "sha256:6c3f6158b02ac403868eea390930ae64e9a9a2a5bbfafefbb920d29258d9f2f8", - "sha256:704f89b87c4f4737da2860695a18c852b78ec7279b24eedacab10b29067d3a38", - "sha256:72128176fea72012063200b7b395ed8a57849282b207321124d7ff14e26988e8", - "sha256:78fbb2be068a13a5d99dce9e1e7d168db880870f7bc73f876152130575bd6167", - "sha256:7bff3a98f63b47464480de1b5bdd80c8fade0ba2832c9381253c9b74c4153c27", - "sha256:84f2436d6742c01136dd940ee158bfc7cf5ced3da7e4c949662b8703b5cd8145", - "sha256:9976fb0a5709988778ac9bc44f3d50fccd989987876dfd7716dee28beed0a9fa", - "sha256:9ad0a117b8dc2061ce9461ea4c1b4799e55edceb236522c5b8f958ce9ed8fa9a", - "sha256:9e3dd806f34de38d4c01416344e98eab2437ac450b3ae39c62a0ede2f8b5e4ed", - "sha256:9eb494070aa060ceba6e4bbf44c1bc5fa97bfb883a0d9b0c9049415f9e944793", - "sha256:9fde6b90889522c220dd56a670102ceef24955d994ff7af2cb786b4ba8fe11e4", - "sha256:9fff3ff052922cb99f9e52f63f985d4f7a54f6b94287463bc66b7cdf3eb41217", - "sha256:a06c358f4aed05fa1099c39decc8022261bb07dfadc127c08cfbd1391b09689e", - "sha256:a4f923b9ab265136e57cc14794a15b9dcea07a9c578609cd5dbbfff28a0d15e6", - "sha256:c5b81fb37db76ebea79aa963b76d96ff854e7662921ce742293463635a87a78d", - "sha256:d5ed164af5c9078596cfc40b078c3b337911190d3faeac830c3f1274f26b8320", - "sha256:d651fde74a4d3122e5562705824507e2f5b2d3d57557f1916c4b27635f8fbe3f", - "sha256:de73fca6fb403dd72d4da517cfc49fcf791f74eee697d3219f6be29adf5af6ce", - "sha256:e647a0be741edbb529a72644e999acb09f2ad60465f80757da183528941ff975", - "sha256:e92c7a5f7d62edff50f60a045dc9542bf939758c95b2fcd686175dd10ce0ed10", - "sha256:eeffd96882d8c06d31b65dddcf51db7c612547babc1c4c5db6a011abe9798525", - "sha256:f5a4551dfd09c3bd12fca8144d47fe7745275adf3229b7223c2f9e29a975ebda", - "sha256:fac0bcc5b7e8169bffa87f0dcc24435446d329cbc2b5486d155c2e0f3b493ae1" - ], - "index": "pypi", - "version": "==6.3.1" - }, - "cryptography": { - "hashes": [ - "sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3", - "sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31", - "sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac", - "sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf", - "sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316", - "sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca", - "sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638", - "sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94", - "sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12", - "sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173", - "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b", - "sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a", - "sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f", - "sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2", - "sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9", - "sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46", - "sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903", - "sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3", - "sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1", - "sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee" - ], - "index": "pypi", - "version": "==36.0.1" - }, - "decorator": { - "hashes": [ - "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", - "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" - ], - "markers": "python_version >= '3.5'", - "version": "==5.1.1" - }, - "docutils": { - "hashes": [ - "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c", - "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.18.1" - }, - "executing": { - "hashes": [ - "sha256:32fc6077b103bd19e6494a72682d66d5763cf20a106d5aa7c5ccbea4e47b0df7", - "sha256:c23bf42e9a7b9b212f185b1b2c3c91feb895963378887bb10e64a2e612ec0023" - ], - "version": "==0.8.2" - }, - "flake8": { - "hashes": [ - "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d", - "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "idna": { - "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" - ], - "markers": "python_version >= '3'", - "version": "==3.3" - }, - "importlib-metadata": { - "hashes": [ - "sha256:175f4ee440a0317f6e8d81b7f8d4869f93316170a65ad2b007d2929186c8052c", - "sha256:e0bc84ff355328a4adfc5240c4f211e0ab386f80aa640d1b11f0618a1d282094" - ], - "index": "pypi", - "version": "==4.11.1" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "ipython": { - "hashes": [ - "sha256:ab564d4521ea8ceaac26c3a2c6e5ddbca15c8848fd5a5cc325f960da88d42974", - "sha256:c503a0dd6ccac9c8c260b211f2dd4479c042b49636b097cc9a0d55fe62dff64c" - ], - "markers": "python_version >= '3.8'", - "version": "==8.0.1" - }, - "jedi": { - "hashes": [ - "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d", - "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab" - ], - "markers": "python_version >= '3.6'", - "version": "==0.18.1" - }, - "jeepney": { - "hashes": [ - "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac", - "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f" - ], - "markers": "sys_platform == 'linux'", - "version": "==0.7.1" - }, - "keyring": { - "hashes": [ - "sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9", - "sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261" - ], - "markers": "python_version >= '3.7'", - "version": "==23.5.0" - }, - "matplotlib-inline": { - "hashes": [ - "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee", - "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c" - ], - "markers": "python_version >= '3.5'", - "version": "==0.1.3" - }, - "mccabe": { - "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" - ], - "version": "==0.6.1" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "parso": { - "hashes": [ - "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", - "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" - ], - "markers": "python_version >= '3.6'", - "version": "==0.8.3" - }, - "pathspec": { - "hashes": [ - "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" - ], - "version": "==0.9.0" - }, - "pexpect": { - "hashes": [ - "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", - "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" - ], - "markers": "sys_platform != 'win32'", - "version": "==4.8.0" - }, - "pickleshare": { - "hashes": [ - "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", - "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" - ], - "version": "==0.7.5" - }, - "pkginfo": { - "hashes": [ - "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff", - "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc" - ], - "version": "==1.8.2" - }, - "platformdirs": { - "hashes": [ - "sha256:30671902352e97b1eafd74ade8e4a694782bd3471685e78c32d0fdfd3aa7e7bb", - "sha256:8ec11dfba28ecc0715eb5fb0147a87b1bf325f349f3da9aab2cd6b50b96b692b" - ], - "markers": "python_version >= '3.7'", - "version": "==2.5.0" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "prompt-toolkit": { - "hashes": [ - "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c", - "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.28" - }, - "ptyprocess": { - "hashes": [ - "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", - "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" - ], - "markers": "os_name != 'nt'", - "version": "==0.7.0" - }, - "pure-eval": { - "hashes": [ - "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", - "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" - ], - "version": "==0.2.2" - }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "index": "pypi", - "version": "==1.11.0" - }, - "pycodestyle": { - "hashes": [ - "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", - "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.8.0" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.21" - }, - "pyflakes": { - "hashes": [ - "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c", - "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.0" - }, - "pygments": { - "hashes": [ - "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65", - "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a" - ], - "index": "pypi", - "version": "==2.11.2" - }, - "pyparsing": { - "hashes": [ - "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea", - "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.7" - }, - "pytest": { - "hashes": [ - "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db", - "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171" - ], - "index": "pypi", - "version": "==7.0.1" - }, - "pytest-cov": { - "hashes": [ - "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6", - "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470" - ], - "index": "pypi", - "version": "==3.0.0" - }, - "readme-renderer": { - "hashes": [ - "sha256:a50a0f2123a4c1145ac6f420e1a348aafefcc9211c846e3d51df05fe3d865b7d", - "sha256:b512beafa6798260c7d5af3e1b1f097e58bfcd9a575da7c4ddd5e037490a5b85" - ], - "markers": "python_version >= '3.6'", - "version": "==32.0" - }, - "requests": { - "hashes": [ - "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", - "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.27.1" - }, - "requests-toolbelt": { - "hashes": [ - "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", - "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0" - ], - "version": "==0.9.1" - }, - "rfc3986": { - "hashes": [ - "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", - "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "secretstorage": { - "hashes": [ - "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f", - "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195" - ], - "markers": "sys_platform == 'linux'", - "version": "==3.3.1" - }, - "setuptools": { - "hashes": [ - "sha256:80743e57120665fa65665286369a0734bce0e7a629ad36507fb7a4b65e7d2e3b", - "sha256:93b1a3037230bf9aa07327b9fc58f527d5f4e22d36705b55d55ba3ece8606ca6" - ], - "markers": "python_version >= '3.7'", - "version": "==60.9.2" - }, - "setuptools-scm": { - "hashes": [ - "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30", - "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4" - ], - "index": "pypi", - "version": "==6.4.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "index": "pypi", - "version": "==1.16.0" - }, - "stack-data": { - "hashes": [ - "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12", - "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e" - ], - "version": "==0.2.0" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "index": "pypi", - "version": "==0.10.2" - }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.1" - }, - "tqdm": { - "hashes": [ - "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", - "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.62.3" - }, - "traitlets": { - "hashes": [ - "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7", - "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033" - ], - "markers": "python_version >= '3.7'", - "version": "==5.1.1" - }, - "twine": { - "hashes": [ - "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19", - "sha256:d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8" - ], - "index": "pypi", - "version": "==3.8.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" - ], - "markers": "python_version < '3.10'", - "version": "==4.1.1" - }, - "urllib3": { - "hashes": [ - "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed", - "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.8" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, - "wheel": { - "hashes": [ - "sha256:4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a", - "sha256:e9a504e793efbca1b8e0e9cb979a249cf4a0a7b5b8c9e8b65a5e39d49529c1c4" - ], - "index": "pypi", - "version": "==0.37.1" - }, - "zipp": { - "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" - ], - "markers": "python_version < '3.10'", - "version": "==3.7.0" - } - } -} diff --git a/docs/docs/images/rsconnect-jupyter-usage.png b/docs/docs/images/rsconnect-jupyter-usage.png index 1f583547..20ad1c5d 100644 Binary files a/docs/docs/images/rsconnect-jupyter-usage.png and b/docs/docs/images/rsconnect-jupyter-usage.png differ diff --git a/docs/docs/usage.md b/docs/docs/usage.md index 69edaa75..b0bc64c4 100644 --- a/docs/docs/usage.md +++ b/docs/docs/usage.md @@ -39,13 +39,18 @@ You have multiple options in this case, depending on your needs: ## Publishing options -There are two different publication modes: +There are three different publication modes: -- If you select **Publish document with source code**, the notebook file and a list of the Python -packages installed in your environment will be sent to Posit Connect. This enables Posit +- If you select **Publish document with source code**, the notebook file and a list of the Python +packages installed in your environment will be sent to Posit Connect. This enables Posit Connect to recreate the environment and re-run the notebook at a later time. -- Selecting **Publish finished document only** will -publish an HTML snapshot of the notebook to Posit Connect. HTML snapshots are static and +- If you select **Publish interactive Voila document with source code**, your notebook will +be published using the [Voila](https://voila.readthedocs.io/en/stable/) package. When +visitors view your published notebook, Connect will present it as an interactive +application. Voila creates a Jupyter kernel for each visitor so they can interact +with any `ipywidgets` that you have included in your notebook. +- Selecting **Publish finished document only** will +publish an HTML snapshot of the notebook to Posit Connect. HTML snapshots are static and cannot be scheduled or re-run on the Posit Connect server. publish dialog @@ -74,7 +79,7 @@ Once enabled, tag each cell where you would like to hide the input code. The tag ### Additional Files -If your notebook needs some external file to render, add the file using the +If your notebook needs some external file to render, add the file using the **Select Files...** button. You can select any file within the notebook folder. However, these files may not be made available to users after render. @@ -117,7 +122,7 @@ informing you of this fact. If you need to regenerate the files, delete them in Dialog titled -For more information on git publishing, see the +For more information on git publishing, see the [Posit Connect User Guide](https://docs.rstudio.com/connect/user/git-backed#git-backed-publishing). ## Handling conflicts @@ -129,13 +134,13 @@ may choose to overwrite the existing content or create new content. - Choosing **New location** creates a new document in Posit Connect. - You can choose either publication mode: - - an HTML snapshot *or* + - an HTML snapshot *or* - a document with source code Updating an existing document will not change its publication mode. Upon successful publishing of the document, a notification will be -shown in the toolbar. +shown in the toolbar. Clicking the notification will open the published document in the Posit Connect server you selected in the previous diff --git a/mock_connect.py b/mock_connect.py index d95b2f1c..585d958e 100644 --- a/mock_connect.py +++ b/mock_connect.py @@ -258,6 +258,7 @@ def read_html(tarball): app_modes = { "static": 4, "jupyter-static": 7, + "jupyter-voila": 16, } diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..4a689397 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,16 @@ +-r requirements.txt +asyncmock +black==22.3.0 +click>=7.0.0 +coverage +flake8 +importlib-metadata +ipython +pytest +pytest-cov +setuptools_scm +toml +twine +wheel +# https://github.com/rstudio/rsconnect-jupyter/issues/316 +traitlets>=5.1.1 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..987c251a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +nbconvert>=5.0 +nbformat +notebook>=6.1.5, <7.0.0 +six +py>=1.10.0 +Pygments>=2.7.4 +jinja2>=2.11.3 +bleach>=3.3.0 +cryptography>=3.2 +rsconnect-python>=1.15.0b1 diff --git a/rsconnect_jupyter/__init__.py b/rsconnect_jupyter/__init__.py index b90d8848..45826afd 100644 --- a/rsconnect_jupyter/__init__.py +++ b/rsconnect_jupyter/__init__.py @@ -22,6 +22,7 @@ from rsconnect.bundle import ( make_notebook_html_bundle, make_notebook_source_bundle, + make_voila_bundle, write_manifest, ) from rsconnect.environment import Environment @@ -196,6 +197,24 @@ async def post(self, action): except Exception as exc: self.log.exception("Bundle creation failed") raise web.HTTPError(500, "Bundle creation failed: %s" % exc) + elif app_mode == "jupyter-voila": + # workaround current dir issue with rsconnect-python's voila deployments + os.chdir(dirname(os_path)) + if not environment_dict: + raise web.HTTPError(400, "environment is required for jupyter-voila app_mode") + + try: + bundle = make_voila_bundle( + os_path, + None, + extra_files, + [], # excludes + False, # force_generate + Environment(**environment_dict), + ) + except Exception as exc: + self.log.exception("Bundle creation failed") + raise web.HTTPError(500, "Bundle creation failed: %s" % exc) else: raise web.HTTPError( 400, diff --git a/rsconnect_jupyter/static/connect.js b/rsconnect_jupyter/static/connect.js index 7a871f3a..4a726d77 100644 --- a/rsconnect_jupyter/static/connect.js +++ b/rsconnect_jupyter/static/connect.js @@ -818,7 +818,7 @@ define([ * @param userEditedTitle {String} title as edited by user * @param selectedDeployLocation {DeploymentLocation.Canceled|DeploymentLocation.New|String} whether this is a new * deployment, a canceled deployment, or has an app id - * @param selectedAppMode {'jupyter-static'|'static'|null} App mode + * @param selectedAppMode {'jupyter-static'|'static'|'jupyter-voila'|null} App mode * @param environmentOptions {null|"use-existing-conda"|"use-existing-pip"|"generate-new-pip"|"generate-new-conda"} * Selected environment option */ @@ -1014,7 +1014,7 @@ define([ } function updateCheckboxStates() { - var publishingWithSource = (appMode === 'jupyter-static'); + var publishingWithSource = (appMode === 'jupyter-static' || appMode === 'jupyter-voila'); var serverSelected = !!selectedEntryId; var $filesBox = $('#include-files'); var includingFiles = $filesBox.prop('checked'); @@ -1033,6 +1033,11 @@ define([ $subdirsBox.prop('checked', false); } $subdirsBox.parent().toggleClass('rsc-text-light', !canIncludeSubdirs); + + // Disable hide code cells options in Voila mode, since Voila always hides them. + var isVoila = (appMode === 'jupyter-voila'); + $('#hide_all_input').prop('disabled', isVoila); + $('#hide_tagged_input').prop('disabled', isVoila); } var publishModal = Dialog.modal({ @@ -1064,6 +1069,13 @@ define([ ' Publish document with source code
', ' Choose this option if you want to create a scheduled report or rebuild your document on the server', ' ', + ' ', + ' ', + ' Publish interactive Voila document with source code
', + ' Choose this option if you want to publish an interactive notebook with widgets', + '
', ' ', ' ' + '
' ); var divider = $('

Or update:

'); diff --git a/rsconnect_jupyter/static/images/publishDocVoila.png b/rsconnect_jupyter/static/images/publishDocVoila.png new file mode 100644 index 00000000..2ee87ad0 Binary files /dev/null and b/rsconnect_jupyter/static/images/publishDocVoila.png differ diff --git a/rsconnect_jupyter/static/images/publishDocVoila_2x.png b/rsconnect_jupyter/static/images/publishDocVoila_2x.png new file mode 100644 index 00000000..705668b2 Binary files /dev/null and b/rsconnect_jupyter/static/images/publishDocVoila_2x.png differ diff --git a/rsconnect_jupyter/static/rsconnect.js b/rsconnect_jupyter/static/rsconnect.js index e8f149f4..3b3f8054 100644 --- a/rsconnect_jupyter/static/rsconnect.js +++ b/rsconnect_jupyter/static/rsconnect.js @@ -347,7 +347,7 @@ define([ * @param serverId {string} the server identifier * @param appId {number} the numeric app ID * @param notebookTitle {string} Title of the notebook to be passed as name/title - * @param appMode {'static'|'jupyter-static'} App mode to deploy. 'static' is not rendered. + * @param appMode {'static'|'jupyter-static'|'jupyter-voila'} App mode to deploy. 'static' is not rendered. * @param files {Array} paths to files to deploy. * @param condaMode {boolean} whether or not to use conda to build an `environment.yml`. * @param forceGenerate {boolean} whether to force `requirements.txt` to be generated even if one exists. @@ -477,7 +477,7 @@ define([ return xhr; } - if (appMode === 'jupyter-static') { + if (appMode === 'jupyter-static' || appMode === 'jupyter-voila') { return this.inspectEnvironment(condaMode, forceGenerate).then(deploy); } else { return deploy(null); diff --git a/selenium/Makefile b/selenium/Makefile index 4fe47dc4..91ad8a1e 100644 --- a/selenium/Makefile +++ b/selenium/Makefile @@ -37,7 +37,7 @@ TMP_PIPE=tmp.pipe TRE_IMAGE?=rstudio/checkrs-tew:0.4.0 NOTEBOOKS_DIR_MOUNT := /notebooks -NOTEBOOKS_DIR := $(CURDIR)/../notebooks$(PY_VERSION) +NOTEBOOKS_DIR := $(CURDIR)/../notebooks3 # Allocate a tty and keep stdin open when running locally # Jenkins nodes don't have input tty, so we set this to "" @@ -121,14 +121,14 @@ prepare-logging: tee ${PYTESTLOG} < ${TMP_PIPE} & run: $(NOTEBOOKS_DIR) - @${DOCKER_RUN_COMMAND} ${COMMAND} + ${DOCKER_RUN_COMMAND} ${COMMAND} test-env-up: grid-up connect-up test-env-down: network-down wait-for-systems-up: - @docker run --rm \ + docker run --rm \ --name=systemstat \ --network=$(NETWORK) \ --volume=${CURDIR}/..:${RSCONNECT_DIR} \ @@ -140,7 +140,8 @@ wait-for-systems-up: -n $$(( ${SCALE_FIREFOX} + ${SCALE_CHROME} )) \ -l ${LOGS_DIR} \ -j '${JUPYTER_SCHEME}://${JUPYTER_HOST}:${JUPYTER_PORT}' \ - -c '${CONNECT_SCHEME}://${CONNECT_HOST}:${CONNECT_PORT}' + -c '${CONNECT_SCHEME}://${CONNECT_HOST}:${CONNECT_PORT}' \ + || (echo "Jupyter log: "; cat ${JUPYTER_LOG}) grid-up: network-up NETWORK=${NETWORK} \ @@ -162,14 +163,14 @@ grid-restart: network-up: $(eval NETWORK_EXISTS=$(shell docker network inspect ${NETWORK} > /dev/null 2>&1 && echo 0 || echo 1)) - @if [ "${NETWORK_EXISTS}" = "1" ] ; then \ + if [ "${NETWORK_EXISTS}" = "1" ] ; then \ echo "Creating network: ${NETWORK}"; \ docker network create --driver bridge ${NETWORK} ; \ fi network-down: connect-down grid-down $(eval NETWORK_EXISTS=$(shell docker network inspect ${NETWORK} > /dev/null 2>&1 && echo 0 || echo 1)) - @if [ "${NETWORK_EXISTS}" = "0" ] ; then \ + if [ "${NETWORK_EXISTS}" = "0" ] ; then \ for i in `docker network inspect -f '{{range .Containers}}{{.Name}} {{end}}' ${NETWORK}`; do \ echo "Removing container \"$${i}\" from network \"${NETWORK}\""; \ docker network disconnect -f ${NETWORK} $${i}; \ @@ -179,8 +180,8 @@ network-down: connect-down grid-down fi jupyter-up: $(NOTEBOOKS_DIR) - @echo "Creating ${JUPYTER_HOST} ..." - @docker run --rm -d --init \ + echo "Creating ${JUPYTER_HOST} ..." + docker run --rm -d --init \ ${DOCKER_TTY_FLAGS} \ --name=${JUPYTER_HOST} \ --network=${NETWORK} \ @@ -197,20 +198,20 @@ jupyter-up: $(NOTEBOOKS_DIR) $(JUPYTER_IMAGE) \ make -C ${RSCONNECT_DIR} run JUPYTER_LOG_LEVEL=$(JUPYTER_LOG_LEVEL) \ 1>/dev/null - @docker logs -f ${JUPYTER_HOST} > ${JUPYTER_LOG} & - @echo " done" + docker logs -f ${JUPYTER_HOST} > ${JUPYTER_LOG} & + echo " done" jupyter-down: $(eval JUPYTER_EXISTS=$(shell docker container inspect ${JUPYTER_HOST} > /dev/null 2>&1 && echo 0 || echo 1)) - @if [ "${JUPYTER_EXISTS}" = "0" ] ; then \ + if [ "${JUPYTER_EXISTS}" = "0" ] ; then \ echo "Stopping ${JUPYTER_HOST} ..."; \ docker stop ${JUPYTER_HOST} 1>/dev/null; \ echo " done"; \ fi connect-up: - @echo "Creating ${CONNECT_HOST} ..." - @docker run --rm -d --init \ + echo "Creating ${CONNECT_HOST} ..." + docker run --rm -d --init \ ${DOCKER_TTY_FLAGS} \ --name=${CONNECT_HOST} \ --network=${NETWORK} \ @@ -222,12 +223,12 @@ connect-up: $(CONNECT_IMAGE) \ flask run --host=0.0.0.0 --port=${CONNECT_PORT} \ 1>/dev/null - @docker logs -f ${CONNECT_HOST} > ${CONNECT_LOG} & - @echo " done" + docker logs -f ${CONNECT_HOST} > ${CONNECT_LOG} & + echo " done" connect-down: $(eval CONNECT_EXISTS=$(shell docker container inspect ${CONNECT_HOST} > /dev/null 2>&1 && echo 0 || echo 1)) - @if [ "${CONNECT_EXISTS}" = "0" ] ; then \ + if [ "${CONNECT_EXISTS}" = "0" ] ; then \ echo "Stopping ${CONNECT_HOST} ..."; \ docker stop ${CONNECT_HOST} 1>/dev/null; \ echo " done"; \ diff --git a/selenium/tools/systemstat/sutstat.py b/selenium/tools/systemstat/sutstat.py index db325bce..3ae6fd1b 100644 --- a/selenium/tools/systemstat/sutstat.py +++ b/selenium/tools/systemstat/sutstat.py @@ -4,7 +4,7 @@ class SutStat(systemstat.SystemStat): - def __init__(self, url="http://localhost:6969", sleep=5.0, wait=60, **kwargs): + def __init__(self, url="http://localhost:6969", sleep=5.0, wait=120, **kwargs): super(SutStat, self).__init__(sleep=sleep, wait=wait, **kwargs) self._url = url diff --git a/setup.cfg b/setup.cfg index 6f8e37da..7a11e16d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,7 +16,7 @@ project_urls = [options] install_requires = - rsconnect-python>=1.7.1 + rsconnect-python>=1.15.0b1 notebook>=6.1.5,<7.0.0 nbformat nbconvert>=5.6.1 diff --git a/tests/test_managers.py b/tests/test_managers.py index 78883349..5f5a22c8 100644 --- a/tests/test_managers.py +++ b/tests/test_managers.py @@ -1,5 +1,5 @@ from unittest import TestCase -from unittest.mock import Mock, MagicMock, AsyncMock +from asyncmock import Mock, MagicMock, AsyncMock from rsconnect_jupyter.managers import ContentsManager, get_model, isawaitable