Repository: dynobo/normcap (language: python)

Issue:
ValueError: A distribution name is required.
Hi,

for me, `normcap` fails with error message 
```
ValueError: A distribution name is required.
```

It was installed using `pip install --user normcap`. 

This is on a fully-updated **Ubuntu 20.04.4 LTS**, using the default Debian package `python3` at version `3.8.2-0ubuntu2`.

```
mona@mona1:~$ normcap 
14:26:39 - ERROR   - normcap.utils          - L:104 - Uncaught exception! Quitting NormCap!
Traceback (most recent call last):
  File "/home/mona/.local/bin/normcap", line 8, in <module>
    sys.exit(main())
  File "/home/mona/.local/lib/python3.8/site-packages/normcap/app.py", line 56, in main
    logger.debug("System info:\n%s", system_info.to_string())
  File "/home/mona/.local/lib/python3.8/site-packages/normcap/system_info.py", line 190, in to_string
    is_briefcase_package=is_briefcase_package(),
  File "/home/mona/.local/lib/python3.8/site-packages/normcap/system_info.py", line 161, in is_briefcase_package
    metadata = importlib_metadata.metadata(app_module)
  File "/home/mona/.local/lib/python3.8/site-packages/importlib_metadata/__init__.py", line 1005, in metadata
    return Distribution.from_name(distribution_name).metadata
  File "/home/mona/.local/lib/python3.8/site-packages/importlib_metadata/__init__.py", line 562, in from_name
    raise ValueError("A distribution name is required.")
ValueError: A distribution name is required.
14:26:39 - ERROR   - normcap.utils          - L:107 - Please open an issue with the output above on https://github.com/dynobo/normcap/issues
```

Auxiliary information:

Pip installation completed without error:
```
mona@mona1:~$ pip install --user normcap
Collecting normcap
  Using cached normcap-0.2.10-py3-none-any.whl (402 kB)
Collecting PySide2<6.0.0,>=5.15.2
  Using cached PySide2-5.15.2.1-5.15.2-cp35.cp36.cp37.cp38.cp39.cp310-abi3-manylinux1_x86_64.whl (164.3 MB)
Collecting jeepney<0.8.0,>=0.7.1
  Using cached jeepney-0.7.1-py3-none-any.whl (54 kB)
Collecting tesserocr<3.0.0,>=2.4.0; sys_platform == "linux"
  Using cached tesserocr-2.5.2.tar.gz (57 kB)
Collecting importlib-metadata<5.0.0,>=4.10.0
  Using cached importlib_metadata-4.12.0-py3-none-any.whl (21 kB)
Collecting packaging<22.0,>=21.3
  Using cached packaging-21.3-py3-none-any.whl (40 kB)
Collecting importlib-resources<6.0.0,>=5.4.0
  Using cached importlib_resources-5.8.0-py3-none-any.whl (28 kB)
Collecting shiboken2==5.15.2.1
  Using cached shiboken2-5.15.2.1-5.15.2-cp35.cp36.cp37.cp38.cp39.cp310-abi3-manylinux1_x86_64.whl (975 kB)
Collecting zipp>=0.5
  Using cached zipp-3.8.1-py3-none-any.whl (5.6 kB)
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/lib/python3/dist-packages (from packaging<22.0,>=21.3->normcap) (2.4.6)
Building wheels for collected packages: tesserocr
  Building wheel for tesserocr (setup.py) ... done
  Created wheel for tesserocr: filename=tesserocr-2.5.2-cp38-cp38-linux_x86_64.whl size=892733 sha256=2d790e47f44401aca331a66cfddd14508bcacdbe3a2104ed1a496c40ddc3e62d
  Stored in directory: /home/mona/.cache/pip/wheels/37/dc/0b/36772b98dae0f858676602cb16ed393eb3353a4abe7d4bb146
Successfully built tesserocr
Installing collected packages: shiboken2, PySide2, jeepney, tesserocr, zipp, importlib-metadata, packaging, importlib-resources, normcap
Successfully installed PySide2-5.15.2.1 importlib-metadata-4.12.0 importlib-resources-5.8.0 jeepney-0.7.1 normcap-0.2.10 packaging-21.3 shiboken2-5.15.2.1 tesserocr-2.5.2 zipp-3.8.1
mona@mona1:~$ 
```

```
mona@mona1:~$ lsb_release -ds
Ubuntu 20.04.4 LTS
```

```
mona@mona1:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

On a side note, please add package `g++` (or the less specific `build-essential`) to the list of requirements on Ubuntu / Debian.

Thanks!


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml
index 53fa4592..d6727a01 100644
--- a/.github/workflows/python.yaml
+++ b/.github/workflows/python.yaml
@@ -4,6 +4,10 @@
 name: Build
 on: [pull_request, push]
 
+concurrency:
+  group: cicd-${{ github.ref }}
+  cancel-in-progress: true
+
 jobs:
   # Run tests on all pull requests or when triggered via [test] tag
   test:
@@ -13,23 +17,20 @@ jobs:
       github.event_name == 'pull_request'
       || contains(github.event.head_commit.message, '[test]')
       || startsWith(github.ref, 'refs/tags/v')
-      || startsWith(github.ref, 'refs/heads/dev')
     strategy:
       fail-fast: false
       matrix:
-        os: [macos-10.15, windows-2019, ubuntu-20.04]
+        os: [macos-11, windows-2019, ubuntu-22.04]
     steps:
       # SETUP ENVIRONMENT
       - uses: actions/checkout@v2
       - uses: actions/setup-python@v2
         with:
-          python-version: 3.9
+          python-version: "3.10"
       - uses: abatilo/actions-poetry@v2.1.4
-        with:
-          poetry-version: 1.1.12
 
       - name: Prepare Linux
-        if: ${{ matrix.os  == 'ubuntu-20.04' }}
+        if: ${{ matrix.os  == 'ubuntu-22.04' }}
         run: |
           sudo apt-get update
           sudo apt-get install \
@@ -46,15 +47,16 @@ jobs:
             libxcb-render-util0 \
             libxcb-xinerama0 \
             libxcb-xfixes0 \
+            libxcb-shape0 \
             libegl1 \
             libegl1-mesa
           ls -la
-          echo "XDG_SESSION_TYPE=gnome" >> $env:GITHUB_ENV
+          echo "XDG_SESSION_TYPE=gnome" >> $GITHUB_ENV
 
       - name: Prepare MacOS
-        if: ${{ matrix.os  == 'macos-10.15' }}
+        if: ${{ matrix.os  == 'macos-11' }}
         run: |
-          brew install pkg-config tesseract
+          brew install pkg-config tesseract dylibbundler
           brew info tesseract
           "/Library/Application Support/VMware Tools/vmware-resolutionSet" 1920 1080
           ls -R /usr/local/Cellar/tesseract/
@@ -79,7 +81,8 @@ jobs:
           tesseract --list-langs
 
       - name: Poetry install
-        run: poetry install
+        run: |
+          poetry install
 
       # PERFORM TESTS
       - name: Pylint
@@ -106,11 +109,10 @@ jobs:
         run: poetry run bandit --quiet --severity-level medium -r src/normcap
       - name: Pytest
         run: |
-          poetry run pytest -m "not skip_on_gh" --log-cli-level=10 --cov --cov-report=xml
-
+          poetry run pytest -vv -m "not skip_on_gh" --cov --cov-report=xml
       - name: Coveralls
         if:
-          ${{ matrix.os  == 'ubuntu-20.04' && github.repository ==
+          ${{ matrix.os  == 'ubuntu-22.04' && github.repository ==
           'dynobo/normcap' }}
         run: poetry run coveralls
         env:
@@ -118,23 +120,29 @@ jobs:
 
       - name: SonarCloud
         if:
-          ${{ matrix.os  == 'ubuntu-20.04' && github.repository
+          ${{ matrix.os  == 'ubuntu-22.04' && github.repository
           =='dynobo/normcap' }}
         uses: SonarSource/sonarcloud-github-action@master
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
 
-      # Build test package
-      - name: Install briefcase and run build
+      # Build test packages
+      - name: Build test package briefcase
         shell: bash -l {0}
-        run: |
-          poetry run python build.py dev
+        run: poetry run python package/build.py --framework=briefcase --dev
+      - name: Build test package nuitka
+        continue-on-error: true
+        shell: bash -l {0}
+        run: poetry run python package/build.py --framework=nuitka --dev
+      - name: List files
+        shell: bash -l {0}
+        run: ls -la ./package
 
+      # Release test package
       - name: Set current date as env variable
+        shell: bash -l {0}
         run: echo "NOW=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_ENV
-
-      # Release test package
       - name: Draft internal release
         uses: ncipollo/release-action@v1
         if: ${{ github.repository == 'dynobo/normcap' }}
@@ -142,7 +150,7 @@ jobs:
           name: Internal
           body:
             "Only for internal tests. Should not be published. [${{ env.NOW }}]"
-          artifacts: "*/*.+(dmg|AppImage|msi)"
+          artifacts: "*/*.+(dmg|AppImage|msi|zip)"
           artifactErrorsFailBuild: false
           allowUpdates: true
           draft: true
@@ -154,15 +162,13 @@ jobs:
     name: Build and release new Python package
     needs: test
     if: ${{ startsWith(github.ref, 'refs/tags/v') }}
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-python@v2
         with:
-          python-version: 3.9
+          python-version: "3.10"
       - uses: abatilo/actions-poetry@v2.1.4
-        with:
-          poetry-version: 1.1.12
       - name: Poetry publish
         run: |
           poetry publish --build --username __token__ --password ${{ secrets.PYPI_TOKEN }}
@@ -175,25 +181,27 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-20.04, macos-10.15, windows-2019]
+        os: [ubuntu-22.04, macos-11, windows-2019]
     steps:
       - uses: actions/checkout@v2
         with:
           fetch-depth: 0
       - uses: actions/setup-python@v2
         with:
-          python-version: 3.9
+          python-version: "3.10"
       - uses: abatilo/actions-poetry@v2.1.4
-        with:
-          poetry-version: 1.1.12
       - name: Extract version from tag
         id: extract_version
         uses: damienaicheh/extract-version-from-tag-action@v1.0.0
-      - name: Install briefcase and run build
+      - name: Install dependencies
         shell: bash -l {0}
         run: |
           poetry install
-          poetry run python build.py
+      - name: Build package briefcase
+        shell: bash -l {0}
+        run: |
+          poetry run python package/build.py --framework=briefcase
+          ls -la ./package
       - name: Draft release
         uses: ncipollo/release-action@v1
         with:
@@ -201,7 +209,7 @@ jobs:
             See
             [CHANGELOG](https://github.com/dynobo/normcap/blob/main/CHANGELOG.md)
             for details.
-          artifacts: "*/*.+(dmg|AppImage|msi)"
+          artifacts: "*/*.+(dmg|AppImage|msi|zip)"
           artifactErrorsFailBuild: false
           allowUpdates: true
           draft: true
@@ -212,7 +220,7 @@ jobs:
     name: Deploy github pages
     needs: build-packages
     if: ${{ startsWith(github.ref, 'refs/tags/v') }}
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v2
       - name: Deploy pages
diff --git a/.gitignore b/.gitignore
index d39aeb4e..19c2ade3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,23 +6,28 @@ dependency_graph.png
 result.json
 .temp
 .venv/
-linux/
-macOS/
-windows/
-Windows/
-shortcut-properties.nsh
 .vscode/
 cov.xml
 coverage
 .coverage
 .coveralls.yml
 *.spec
-normcap/resources/icon
-normcap/resources/screencast
-src/normcap/resources/tesseract/
+src/normcap/resources/tesseract/*
+!src/normcap/resources/tesseract/.keep
 normcap/src/normcap.dist-info
 .DS_Store
 *.traineddata
+app.build/
+app.dist/
+app.onefile-build/
+*.app
+tesseract.zip
+wix/
+*.wixpdb
+*.msi
+*.AppImage
+*.zip
+linux/
 
 ### Python ###
 # Byte-compiled / optimized / DLL files
@@ -35,7 +40,6 @@ __pycache__/
 
 # Distribution / packaging
 .Python
-build/
 develop-eggs/
 dist/
 downloads/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8ebdf38a..6c6cbc6e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -21,21 +21,21 @@ repos:
         name: isort
         stages: [commit]
         language: system
-        entry: poetry run isort --jobs=0 src/normcap src/tests/
+        entry: poetry run isort --jobs=0 src/normcap src/tests/ package/
         types: [python]
 
       - id: black
         name: black
         stages: [commit]
         language: system
-        entry: poetry run black src/normcap src/tests/
+        entry: poetry run black src/normcap src/tests/ package/
         types: [python]
 
       - id: pydocstyle
         name: pydocstyle
         stages: [commit]
         language: system
-        entry: poetry run pydocstyle src/normcap src/tests/
+        entry: poetry run pydocstyle src/normcap src/tests/ package/
         types: [python]
         pass_filenames: false
 
@@ -59,7 +59,7 @@ repos:
         name: pylint
         stages: [commit]
         language: system
-        entry: poetry run pylint src/normcap src/tests
+        entry: poetry run pylint src/normcap src/tests package/
         types: [python]
         pass_filenames: false
 
@@ -76,8 +76,8 @@ repos:
         stages: [commit]
         language: system
         entry:
-          poetry run pytest --log-cli-level=10 src/tests/ --cov normcap
-          --cov-report xml:cov.xml --cov-report html
+          poetry run pytest src/tests/ -vv --cov --cov-report xml:cov.xml
+          --cov-report html
         types: [python]
         pass_filenames: false
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6756d26a..dd4fc33b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,17 @@
 # Changelog
 
+## v0.3.5 (2022-07-27)
+
+- All: Reduce the file size of prebuild packages.
+- Windows: Fix bug causing a 5 seconds delay during recognition
+  [#218](https://github.com/dynobo/normcap/issues/218).
+- Docu: Add Python version required for installing package from PyPi
+  [#221](https://github.com/dynobo/normcap/issues/221).
+
 ## v0.3.4 (2022-03-31)
 
 - All: Various speed improvements.
-- All: Smaller size by updating to Pyside 6.3 without addons.
+- All: Smaller size by updating to PySide 6.3 without add-ons.
 - Linux: Avoid crash on denied screenshot on Wayland.
 - Docu: In README, complement dependencies for installing pip package. Thx,
   [@thecoder-001](https://github.com/thecoder-001) &
diff --git a/README.md b/README.md
index 480966b2..7b431f35 100644
--- a/README.md
+++ b/README.md
@@ -45,13 +45,13 @@ If you experience issues please look at the
 ## Python package
 
 As an _alternative_ to a pre-build package you can install the
-[NormCap Python package](https://pypi.org/project/normcap/):
+[NormCap Python package](https://pypi.org/project/normcap/) for **Python >=3.9**:
 
 #### On Linux
 
 ```sh
 # Install dependencies (Ubuntu/Debian)
-sudo apt install tesseract-ocr tesseract-ocr-eng libtesseract-dev libleptonica-dev
+sudo apt install build-essential tesseract-ocr tesseract-ocr-eng libtesseract-dev libleptonica-dev
 
 ## Install dependencies (Arch)
 sudo pacman -S tesseract tesseract-data-eng
@@ -127,8 +127,8 @@ See [XKCD](https://xkcd.com):
 
 ## Development
 
-Prerequisites for setting up a development environment are: **Python >=3.9**, **Poetry**
-and **Tesseract** (incl. **language data**).
+Prerequisites for setting up a development environment are: **Python >=3.9**,
+**Poetry>=1.2.0b2** and **Tesseract** (incl. **language data**).
 
 ```sh
 # Clone repository
@@ -159,6 +159,8 @@ Packaging is done with:
 
 - [briefcase](https://pypi.org/project/briefcase/) _- converting Python projects into_
   _standalone apps_
+- [nuitka](https://pypi.org/project/Nuitka/) _- compiling Python projects into_
+  _standalone apps_
 
 And it depends on external software
 
@@ -168,7 +170,7 @@ Thanks to the maintainers of those nice libraries!
 
 ## Similar open source tools
 
-Try those to see which one suits your needs:
+If NormCap doesn't fit your needs, try those alternatives (no particular order):
 
 - [TextSnatcher](https://github.com/RajSolai/TextSnatcher)
 - [GreenShot](https://getgreenshot.org/)
@@ -176,6 +178,7 @@ Try those to see which one suits your needs:
 - [gImageReader](https://github.com/manisandro/gImageReader)
 - [Capture2Text](https://sourceforge.net/projects/capture2text)
 - [Frog](https://github.com/TenderOwl/Frog)
+- [Textinator](https://github.com/RhetTbull/textinator)
 
 ## Certification
 
diff --git a/build.py b/build.py
deleted file mode 100644
index 8b0f7254..00000000
--- a/build.py
+++ /dev/null
@@ -1,451 +0,0 @@
-"""Adjustments executed while packaging with briefcase during CI/CD."""
-
-import fileinput
-import hashlib
-import inspect
-import os
-import shutil
-import subprocess
-import sys
-import urllib.request
-import xml.etree.ElementTree as ET
-import zipfile
-from pathlib import Path
-
-import briefcase  # type: ignore
-import toml
-
-platform_str = sys.platform.lower()
-
-
-EXCLUDE_FROM_PySide6 = [
-    "3danimation",
-    "3dcore",
-    "3dextras",
-    "3drender",
-    "assistant",
-    "audio",
-    "bluetooth",
-    "canbus",
-    "charts",
-    "datavisualization",
-    "designer",
-    "examples",
-    "gamepad",
-    "geoservices",
-    "help",
-    "icudtl",
-    "labs",
-    "libexec",
-    "linguist",
-    "location",
-    "lupdate",
-    "mediaservice",
-    "multimedia",
-    "nfc",
-    "openglfunct",
-    "pdf",
-    "purchasing",
-    "qt63d",
-    "qt6quick",
-    "qt6shadertools",
-    "qtopengl",
-    "qtquick",
-    "rcc",
-    "remoteobjects",
-    "scene",
-    "sensor",
-    "serialport",
-    "sql",
-    "test",
-    "texttospeech",
-    "uic",
-    "uitools",
-    "virtualkeyboard",
-    "webchannel",
-    "webengine",
-    "websockets",
-    "webview",
-]
-# Excluding this breaks application:
-# "printsupport",
-
-EXCLUDE_FROM_APP_PACKAGES = [
-    "/tests/",
-    "docs",
-]
-
-EXCLUDE_FROM_LIB = ["qt6qml"]
-
-
-def get_version() -> str:
-    """Get versions string from pyproject.toml."""
-    with open("pyproject.toml", encoding="utf8") as toml_file:
-        pyproject_toml = toml.load(toml_file)
-    return pyproject_toml["tool"]["poetry"]["version"]
-
-
-def get_system_requires(platform) -> list[str]:
-    """Get versions string from pyproject.toml."""
-    with open("pyproject.toml", encoding="utf8") as toml_file:
-        pyproject_toml = toml.load(toml_file)
-    return pyproject_toml["tool"]["briefcase"]["app"]["normcap"][platform][
-        "system_requires"
-    ]
-
-
-def cmd(cmd_str: str):
-    """Run command in subprocess.run()."""
-    completed_proc = subprocess.run(  # pylint: disable=subprocess-run-check
-        cmd_str, shell=True
-    )
-    if completed_proc.returncode != 0:
-        raise subprocess.CalledProcessError(
-            returncode=completed_proc.returncode,
-            cmd=cmd_str,
-            output=completed_proc.stdout,
-            stderr=completed_proc.stderr,
-        )
-
-
-def patch_windows_installer():
-    """Customize wix-installer.
-
-    Currently only branding is added.
-    """
-    print("Preparing installer...")
-
-    wxs_file = Path.cwd() / "windows" / "msi" / "NormCap" / "normcap.wxs"
-
-    # Cache header for inserting later
-    with open(wxs_file, encoding="utf-8") as f:
-        header_lines = f.readlines()[:3]
-
-    ns = "{http://schemas.microsoft.com/wix/2006/wi}"
-    ET.register_namespace("", ns[1:-1])
-
-    tree = ET.parse(wxs_file)
-    root = tree.getroot()
-    product = root.find(f"{ns}Product")
-
-    # Copy installer images
-    left = "normcap_install_bg.bmp"
-    top = "normcap_install_top.bmp"
-    for image in [left, top]:
-        original = Path.cwd() / "src" / "normcap" / "resources" / image
-        target = Path.cwd() / "windows" / "msi" / "NormCap" / image
-        shutil.copy(original, target)
-
-    # Set installer images
-    ET.SubElement(product, "WixVariable", {"Id": "WixUIDialogBmp", "Value": f"{left}"})
-    ET.SubElement(product, "WixVariable", {"Id": "WixUIBannerBmp", "Value": f"{top}"})
-
-    # Allow upgrades
-    major_upgrade = ET.SubElement(product, "MajorUpgrade")
-    major_upgrade.set("DowngradeErrorMessage", "Can't downgrade. Uninstall first.")
-
-    sequence = product.find(f"{ns}InstallExecuteSequence")
-    product.remove(sequence)
-
-    upgrade = product.find(f"{ns}Upgrade")
-    product.remove(upgrade)
-
-    # Write & fix header
-    tree.write(wxs_file, encoding="utf-8", xml_declaration=False)
-    with open(wxs_file, "r+", encoding="utf-8") as f:
-        lines = f.readlines()
-        f.seek(0)
-        f.writelines(header_lines + lines)
-
-    print("Installer prepared.")
-
-
-def download_openssl():
-    """Download openssl needed for QNetwork https connections."""
-    target_path = Path.cwd() / "src" / "normcap" / "resources" / "openssl"
-    target_path.mkdir(exist_ok=True)
-    zip_path = Path.cwd() / "openssl.zip"
-    urllib.request.urlretrieve(
-        "http://wiki.overbyte.eu/arch/openssl-1.1.1m-win64.zip", zip_path
-    )
-    with zipfile.ZipFile(zip_path, "r") as zip_ref:
-        zip_ref.extractall(target_path)
-    print("Openssl extracted")
-
-
-def download_tessdata():
-    """Download trained data for tesseract.
-
-    Necessary to include it in the packages.
-    """
-    target_path = Path.cwd() / "src" / "normcap" / "resources" / "tessdata"
-    url_prefix = "https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/4.1.0"
-    files = [
-        "ara.traineddata",
-        "chi_sim.traineddata",
-        "deu.traineddata",
-        "rus.traineddata",
-        "spa.traineddata",
-        "eng.traineddata",
-    ]
-
-    if len(list(target_path.glob("*.traineddata"))) >= len(files):
-        print("Language data already present. Skipping download.")
-        return
-
-    print("Downloading language data...")
-    for file_name in files:
-        urllib.request.urlretrieve(f"{url_prefix}/{file_name}", target_path / file_name)
-        print(
-            f"Downloaded {url_prefix}/{file_name} to {(target_path / file_name).absolute()}"
-        )
-
-    print("Download done.")
-
-
-def download_tesseract_windows_build():
-    # Link to download artifact might change
-    # https://ci.appveyor.com/project/zdenop/tesseract/build/artifacts
-
-    resources_path = Path.cwd() / "src" / "normcap" / "resources"
-    tesseract_path = resources_path / "tesseract"
-
-    cmd(
-        "curl -L -o tesseract.zip "
-        + "https://ci.appveyor.com/api/projects/zdenop/tesseract/artifacts/tesseract.zip"
-    )
-    zip_file = Path("tesseract.zip")
-    with zipfile.ZipFile(zip_file) as artifact_zip:
-        members = [
-            m
-            for m in artifact_zip.namelist()
-            if ".test." not in m and ".training." not in m
-        ]
-        subdir = members[0].split("/")[0]
-        artifact_zip.extractall(path=resources_path, members=members)
-    print("Tesseract binaries downloaded")
-
-    shutil.rmtree(tesseract_path, ignore_errors=True)
-
-    os.rename(
-        resources_path / subdir,
-        tesseract_path,
-    )
-    os.rename(
-        tesseract_path / "google.tesseract.tesseract-master.exe",
-        tesseract_path / "tesseract.exe",
-    )
-
-    print("Tesseract.exe renamed.")
-
-
-def bundle_pytesseract_dylibs():
-    print("Bundling tesseract libs...")
-    app_pkg_path = "macOS/app/NormCap/NormCap.app/Contents/Resources/app_packages"
-    tesseract_source = "/usr/local/bin/tesseract"
-    tesseract_target = app_pkg_path + "/tesseract"
-    install_path = "@executable_path/"
-    cmd(
-        "dylibbundler "
-        + f"--fix-file {tesseract_source} "
-        + f"--dest-dir {app_pkg_path} "
-        + f"--install-path {install_path} "
-        + "--bundle-deps "
-        + "--overwrite-files"
-    )
-    shutil.copy(tesseract_source, tesseract_target)
-
-
-def rm_recursive(directory, exclude):
-    """Remove excluded files from package."""
-    for package_path in directory.glob(r"**/*"):
-        path_str = str(package_path.absolute()).lower()
-        if any(e in path_str for e in exclude):
-            if not package_path.exists():
-                continue
-            print(f"Removing: {package_path.absolute()}")
-            if package_path.is_dir():
-                shutil.rmtree(package_path)
-            if package_path.is_file():
-                os.remove(package_path)
-
-
-def patch_briefcase_appimage_to_prune_deps():
-    """Insert code into briefcase appimage code to remove unnecessary libs."""
-    def_rm_recursive = inspect.getsource(rm_recursive)
-
-    file_path = Path(briefcase.__file__).parent / "platforms" / "linux" / "appimage.py"
-    patch = f"""
-import shutil, os
-{def_rm_recursive}
-app_dir = self.appdir_path(app) / "usr" / "app_packages"
-rm_recursive(directory=app_dir, exclude={EXCLUDE_FROM_APP_PACKAGES})
-rm_recursive(directory=app_dir / "PySide6", exclude={EXCLUDE_FROM_PySide6})
-
-lib_dir = self.appdir_path(app) / "usr" / "lib"
-rm_recursive(directory=lib_dir / "PySide6", exclude={EXCLUDE_FROM_PySide6})
-"""
-    insert_after = 'self.logger.info(f"[{app.app_name}] Building AppImage...")'
-    patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
-
-
-def patch_info_plist_for_proper_fullscreen():
-    """Set attribute to keep dock and menubar hidden in fullscreen.
-
-    See details:
-    https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/20001431-113616
-    """
-    file_path = Path("macOS/app/NormCap/NormCap.app/Contents") / "Info.plist"
-    patch = """
-    <key>LSUIPresentationMode</key>
-    <integer>3</integer>
-"""
-    insert_after = "<string>normcap</string>"
-    patch_file(
-        file_path=file_path, insert_after=insert_after, patch=patch, mark_patched=False
-    )
-
-
-def patch_briefcase_appimage_to_include_tesseract():
-    """Insert code into briefcase appimage code to remove unnecessary libs."""
-    file_path = Path(briefcase.__file__).parent / "platforms" / "linux" / "appimage.py"
-    insert_after = '"-o", "appimage",'
-    # TODO: Try running with linuxdeploy-plugin-qt. Has to be installed first.
-    patch = """
-"--executable",
-"/usr/bin/tesseract",
-"""
-    patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
-
-
-def patch_file(
-    file_path: Path, insert_after: str, patch: str, mark_patched: bool = True
-):
-    """Insert lines in file, if not already done.
-
-    Indents the patch like the line after which it is inserted.
-    """
-    patch_applied = False
-    patch_hash = hashlib.md5(patch.encode()).hexdigest()
-
-    with open(file_path, "r", encoding="utf8") as f:
-        if f.read().find(patch_hash) > -1:
-            print("Skipping patch. Already applied.")
-            return
-
-    print(f"Patching file {file_path.resolve()}")
-    if mark_patched:
-        patch = (
-            f"# dynobo: {patch_hash} >>>>>>>>>>>>>>"
-            + patch
-            + f"# dynobo: {patch_hash} <<<<<<<<<<<<<<\n"
-        )
-    for line in fileinput.FileInput(file_path, inplace=True):
-        if insert_after in line:
-            pad = len(line) - len(line.lstrip(" "))
-            patch = patch.replace("\n", f"\n{pad * ' '}")
-            line = line.replace(line, line + pad * " " + patch + "\n")
-            patch_applied = True
-        print(line, end="")
-
-    if not patch_applied:
-        raise RuntimeError(
-            f"Couldn't apply patch to file {file_path}! "
-            + f"Line '{insert_after}' not found!"
-        )
-
-
-def patch_briefcase_create_to_adjust_dockerfile():
-    """Add code to add tesseract ppa to Dockerfile."""
-    file_path = Path(briefcase.__file__).parent / "commands" / "create.py"
-    insert_after = "self.install_app_support_package(app=app)"
-    patch = """
-if "linux" in str(bundle_path):
-    print()
-    print("Patching Dockerfile on Linux")
-    import fileinput
-    patch = "\\nRUN apt-add-repository ppa:alex-p/tesseract-ocr-devel"
-    for line in fileinput.FileInput(bundle_path / "Dockerfile", inplace=1):
-        if "RUN apt-add-repository ppa:deadsnakes/ppa" in line:
-            line = line.replace(line, line + patch)
-        print(line, end="")
-"""
-    patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
-
-
-def add_metainfo_to_appimage():
-    """Copy metainfo file with info for appimage hub."""
-    metainfo = Path.cwd() / "src" / "normcap" / "resources" / "metainfo"
-    target_path = (
-        Path.cwd()
-        / "linux"
-        / "appimage"
-        / "NormCap"
-        / "NormCap.AppDir"
-        / "usr"
-        / "share"
-    )
-    shutil.copy(metainfo, target_path / "metainfo")
-
-
-if __name__ == "__main__":
-    if platform_str.lower().startswith("win"):
-        app_dir = Path.cwd() / "windows" / "msi" / "NormCap" / "src" / "app_packages"
-        download_tesseract_windows_build()
-        download_tessdata()
-        download_openssl()
-        cmd("briefcase create")
-        rm_recursive(directory=app_dir, exclude=EXCLUDE_FROM_APP_PACKAGES)
-        rm_recursive(directory=app_dir / "PySide6", exclude=EXCLUDE_FROM_PySide6)
-        cmd("briefcase build")
-        patch_windows_installer()
-        cmd("briefcase package")
-        if "dev" in sys.argv:
-            cmd("mv windows/*.msi windows/NormCap-unstable-Windows.msi")
-        else:
-            cmd(f"mv windows/*.msi windows/NormCap-{get_version()}-Windows.msi")
-
-    elif platform_str.lower().startswith("darwin"):
-        app_dir = (
-            Path.cwd()
-            / "macOS"
-            / "app"
-            / "NormCap"
-            / "NormCap.app"
-            / "Contents"
-            / "Resources"
-            / "app_packages"
-        )
-        download_tessdata()
-        cmd("brew install tesseract")
-        cmd("brew install dylibbundler")
-        cmd("briefcase create")
-        bundle_pytesseract_dylibs()
-        rm_recursive(directory=app_dir, exclude=EXCLUDE_FROM_APP_PACKAGES)
-        rm_recursive(directory=app_dir / "PySide6", exclude=EXCLUDE_FROM_PySide6)
-        cmd("briefcase build")
-        # TODO: Re-enable if we have a solution for unfocusing on MacOS
-        # patch_info_plist_for_proper_fullscreen()
-        cmd("briefcase package macos app --no-sign")
-        if "dev" in sys.argv:
-            cmd("mv macOS/*.dmg macOS/NormCap-unstable-MacOS.dmg")
-        else:
-            cmd(f"mv macOS/*.dmg macOS/NormCap-{get_version()}-MacOS.dmg")
-
-    elif platform_str.lower().startswith("linux"):
-        if system_requires := get_system_requires("linux"):
-            github_actions_uid = 1001
-            if os.getuid() == github_actions_uid:  # type: ignore
-                cmd("sudo apt update")
-                cmd(f"sudo apt install {' '.join(system_requires)}")
-        download_tessdata()
-        patch_briefcase_appimage_to_prune_deps()
-        patch_briefcase_appimage_to_include_tesseract()
-        patch_briefcase_create_to_adjust_dockerfile()
-        cmd("briefcase create")
-        cmd("briefcase build")
-        cmd("briefcase package")
-        if "dev" in sys.argv:
-            cmd("mv linux/*.AppImage linux/NormCap-unstable-x86_64.AppImage")
-    else:
-        raise ValueError("Unknown operating system.")
diff --git a/docs/index.html b/docs/index.html
index d7e73479..08f34bac 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,589 +1,527 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <title>NormCap</title>
-    <meta charset="utf-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1" />
-    <meta
-      name="description"
-      content="OCR-powered screenshot tool to capture text instead of images."
-    />
 
-    <link rel="canonical" href="https://dynobo.github.io/normcap/" />
-    <link rel="stylesheet" href="pico-bootstrap-grid.min.css" />
-    <link rel="stylesheet" href="style.css" />
+<head>
+  <title>NormCap</title>
+  <meta charset="utf-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <meta name="description" content="OCR-powered screenshot tool to capture text instead of images." />
 
-    <link rel="icon" href="favicon.ico" type="image/x-icon" />
-    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
-    <link
-      rel="icon"
-      type="image/png"
-      sizes="192x192"
-      href="favicon-192x192.png"
-    />
-    <link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png" />
-    <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" />
-    <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" />
-  </head>
+  <link rel="canonical" href="https://dynobo.github.io/normcap/" />
+  <link rel="stylesheet" href="pico-bootstrap-grid.min.css" />
+  <link rel="stylesheet" href="style.css" />
 
-  <body>
-    <nav class="container-fluid">
-      <ul>
-        <li id="logo">
-          <img src="img/normcap.svg" alt="logo" /><strong class="contrast"
-            >NormCap</strong
-          >
+  <link rel="icon" href="favicon.ico" type="image/x-icon" />
+  <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+  <link rel="icon" type="image/png" sizes="192x192" href="favicon-192x192.png" />
+  <link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png" />
+  <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" />
+  <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" />
+</head>
+
+<body>
+  <nav class="container-fluid">
+    <ul>
+      <li id="logo">
+        <img src="img/normcap.svg" alt="logo" /><strong class="contrast">NormCap</strong>
+      </li>
+    </ul>
+    <ul>
+      <li><a href="#features" class="contrast">Features</a></li>
+      <li><a href="#usage" class="contrast">Usage</a></li>
+      <li><a href="#support" class="contrast">Support</a></li>
+      <li><a href="#faqs" class="contrast">FAQs</a></li>
+      <li>
+        <a href="#python-package" class="contrast">Python&nbsp;package</a>
+      </li>
+      <li class="switch-light">
+        <a href="#" class="contrast" data-theme-switcher="light">🌣</a>
+      </li>
+      <li class="switch-dark">
+        <a href="#" class="contrast" data-theme-switcher="dark">⏾</a>
+      </li>
+    </ul>
+  </nav>
+
+  <main class="container">
+    <article id="download" class="grid">
+      <a id="link-to-source" href="https://github.com/dynobo/normcap" target="_blank"></a>
+      <div>
+        <div class="hgroup">
+          <h1>NormCap v0.3.4</h1>
+          <h2>
+            <a href="https://en.wikipedia.org/wiki/Optical_character_recognition" target="_blank">OCR</a>
+            -powered screenshot tool to capture text instead of images.
+          </h2>
+        </div>
+        <p>
+          Packages with the
+          <a href="https://github.com/dynobo/normcap/blob/main/CHANGELOG.md" target="_blank">latest changes</a>
+          for your system:
+        </p>
+        <ul>
+          <li>
+            <a
+              href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-Windows.msi">NormCap-<strong>Windows</strong>.exe</a>
+            <small>~85 MB</small>
+            <span data-tooltip="Run installer and start through start menu">🛈</span>
+          </li>
+          <li>
+            <a
+              href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-x86_64.AppImage">NormCap-<strong>Linux</strong>.AppImage</a>
+            <small>~85 MB</small>
+            <span data-tooltip="Make the file executable and run it">🛈</span>
+          </li>
+          <li>
+            <a
+              href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-MacOS.dmg">NormCap-<strong>MacOS</strong>.dmg</a>
+            <small>~75 MB</small>
+            <span class="wide-tooltip"
+              data-tooltip="Unsigned application! You have to grant permissions on first start:&#10;'System Preferences' → 'Security & Privacy' → 'General' → 'Open anyway'.&#10;(You might have to grant permissions to take screenshots, too.)">🛈</span>
+          </li>
+        </ul>
+        <p class="align-right">
+          <small>... or
+            <a href="#python-package">install the Python package</a>
+            instead.</small>
+        </p>
+      </div>
+      <div></div>
+    </article>
+
+    <article id="features">
+      <div class="hgroup">
+        <h2>Features</h2>
+        <h3>
+          Characteristics and functionalities that make NormCap interesting.
+        </h3>
+      </div>
+      <div class="row features">
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-1">
+            <strong>Free & Open Source</strong>
+          </div>
+        </div>
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-3">
+            <strong>Cross-platform</strong>
+          </div>
+        </div>
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-2">
+            <strong>Multi monitor</strong>
+          </div>
+        </div>
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-4">
+            <strong>Many languages</strong>
+          </div>
+        </div>
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-6">
+            <strong>System tray</strong>
+          </div>
+        </div>
+        <div class="col-md-6 col-lg-6 col-xl-4">
+          <div class="feature feature-5">
+            <strong>Heuristic parsing</strong>
+          </div>
+        </div>
+      </div>
+    </article>
+
+    <article id="usage">
+      <div class="hgroup">
+        <h2>Usage</h2>
+        <h3>
+          A short guide for using NormCap and its most important features.
+        </h3>
+      </div>
+      <h4>Quickstart</h4>
+      <ol>
+        <li>Start NormCap and wait until a pink border appears.</li>
+        <li>Select a region on screen with your mouse.</li>
+        <li>
+          Paste the recognized text from the clipboard anywhere you like.
         </li>
-      </ul>
+      </ol>
+      <h4>User Interface</h4>
       <ul>
-        <li><a href="#features" class="contrast">Features</a></li>
-        <li><a href="#usage" class="contrast">Usage</a></li>
-        <li><a href="#support" class="contrast">Support</a></li>
-        <li><a href="#faqs" class="contrast">FAQs</a></li>
         <li>
-          <a href="#python-package" class="contrast">Python&nbsp;package</a>
+          The settings can be accessed via the
+          <span class="primary">⚙</span>-icon in the top right.
+        </li>
+        <li>
+          In the settings you can adjust the language(s) you are trying to
+          recognize, which is important for a good accuracy.
         </li>
-        <li class="switch-light">
-          <a href="#" class="contrast" data-theme-switcher="light">🌣</a>
+        <li>
+          The icons <span class="primary">★</span> or
+          <span class="primary">☰</span> next to the selection-rectangle
+          indicate the active "capture mode" (see below).
         </li>
-        <li class="switch-dark">
-          <a href="#" class="contrast" data-theme-switcher="dark">⏾</a>
+        <li>
+          To abort a capture or quit NormCap press <code>&lt;esc&gt;</code>
         </li>
       </ul>
-    </nav>
 
-    <main class="container">
-      <article id="download" class="grid">
-        <a
-          id="link-to-source"
-          href="https://github.com/dynobo/normcap"
-          target="_blank"
-        ></a>
-        <div>
-          <div class="hgroup">
-            <h1>NormCap v0.3.4</h1>
-            <h2>
-              <a
-                href="https://en.wikipedia.org/wiki/Optical_character_recognition"
-                target="_blank"
-                >OCR</a
-              >
-              -powered screenshot tool to capture text instead of images.
-            </h2>
-          </div>
+      <h4>Capture Modes</h4>
+      <p>
+        The settings menu <span class="primary">⚙</span> allows switching
+        between the two capture modes: "parse" and "raw":
+      </p>
+      <ul>
+        <li>
+          <p><strong>"Raw"-Mode </strong></p>
           <p>
-            Packages with the
-            <a
-              href="https://github.com/dynobo/normcap/blob/main/CHANGELOG.md"
-              target="_blank"
-              >latest changes</a
-            >
-            for your system:
+            Marked by the <span class="primary">☰</span> symbol, it outputs
+            the detected text just as detected by the OCR software. Keeps the
+            text as recognized, e.g. doesn't remove line-breaks.
           </p>
-          <ul>
-            <li>
-              <a
-                href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-Windows.msi"
-                >NormCap-<strong>Windows</strong>.exe</a
-              >
-              <small>~90 MB</small>
-              <span data-tooltip="Run installer and start through start menu"
-                >🛈</span
-              >
-            </li>
-            <li>
-              <a
-                href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-x86_64.AppImage"
-                >NormCap-<strong>Linux</strong>.AppImage</a
-              >
-              <small>~110 MB</small>
-              <span data-tooltip="Make the file executable and run it">🛈</span>
-            </li>
-            <li>
-              <a
-                href="https://github.com/dynobo/normcap/releases/download/v0.3.4/NormCap-0.3.4-MacOS.dmg"
-                >NormCap-<strong>MacOS</strong>.dmg</a
-              >
-              <small>~80 MB</small>
-              <span
-                class="wide-tooltip"
-                data-tooltip="Unsigned application! You have to grant permissions on first start:&#10;'System Preferences' → 'Security & Privacy' → 'General' → 'Open anyway'.&#10;(You might have to grant permissions to take screenshots, too.)"
-                >🛈</span
-              >
-            </li>
-          </ul>
-          <p class="align-right">
-            <small
-              >... or
-              <a href="#python-package">install the Python package</a>
-              instead.</small
-            >
+        </li>
+        <li>
+          <p><strong>"Parse"-Mode</strong> <small>(default)</small></p>
+          <p>
+            Indicated by the <span class="primary">★</span> symbol, it
+            performs some formatting of the output based on certain
+            implemented rules, which can take additional information like text
+            position into account. In a first step, every rule calculates a
+            "score" to determine the likelihood of being responsible for this
+            type of text. In a second step, the rule which achieved the
+            highest "score" takes the necessary actions to "transform" the
+            input text according to its type. Those rules are currently
+            implemented:
           </p>
-        </div>
-        <div></div>
-      </article>
+          <table>
+            <caption>
+              Heuristics performed in parse-mode.
+            </caption>
+            <thead>
+              <tr>
+                <th scope="col">
+                  <strong>Rule&NonBreakingSpace;name</strong>
+                </th>
+                <th scope="col"><strong>Score heuristics</strong></th>
+                <th scope="col"><strong>Transform</strong></th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <td><strong>Single line</strong></td>
+                <td>Only single line is detected</td>
+                <td>Trim unnecessary whitespace</td>
+              </tr>
+              <tr>
+                <td><strong>Multi line</strong></td>
+                <td>Multiple lines, but single paragraph</td>
+                <td>
+                  Separate using line breaks and trim unnecessary whitespace
+                  in each line
+                </td>
+              </tr>
+              <tr>
+                <td><strong>Paragraph</strong></td>
+                <td>Multiple blocks of lines or multiple paragraphs</td>
+                <td>
+                  Join every paragraph into a single line, separate different
+                  paragraphs by empty line
+                </td>
+              </tr>
+              <tr>
+                <td><strong>E-Mail</strong></td>
+                <td>Number of chars in email addresses vs. overall chars</td>
+                <td>
+                  Transform to a comma-separated list of email addresses
+                </td>
+              </tr>
+              <tr>
+                <td><strong>URL</strong></td>
+                <td>Number of chars in URLs vs. overall chars</td>
+                <td>Transform to line-break separated URLs</td>
+              </tr>
+            </tbody>
+          </table>
+        </li>
+      </ul>
+    </article>
 
-      <article id="features">
-        <div class="hgroup">
-          <h2>Features</h2>
-          <h3>
-            Characteristics and functionalities that make NormCap interesting.
-          </h3>
-        </div>
-        <div class="row features">
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-1">
-              <strong>Free & Open Source</strong>
-            </div>
-          </div>
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-3">
-              <strong>Cross platform</strong>
-            </div>
-          </div>
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-2">
-              <strong>Multi monitor</strong>
-            </div>
-          </div>
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-4">
-              <strong>Many languages</strong>
-            </div>
-          </div>
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-6">
-              <strong>System tray</strong>
-            </div>
-          </div>
-          <div class="col-md-6 col-lg-6 col-xl-4">
-            <div class="feature feature-5">
-              <strong>Heuristic parsing</strong>
-            </div>
-          </div>
-        </div>
-      </article>
+    <article id="support">
+      <div class="hgroup">
+        <h2>Support</h2>
+        <h3>When things did not go as expected.</h3>
+      </div>
+      <h5>You need support with NormCap?</h5>
+      <ul>
+        <li>
+          For general questions use the
+          <a href="https://github.com/dynobo/normcap/discussions/categories/q-a">discussions</a>
+          board.
+        </li>
+        <li>
+          If you have found a bug, open an
+          <a href="https://github.com/dynobo/normcap/issues">issue</a>.
+        </li>
+        <li>
+          Take a look at the
+          <a href="#faqs">frequently asked questions</a> below.
+        </li>
+      </ul>
+      <h5>You want to support NormCap?</h5>
+      <ul>
+        <li>Tell your friends about NormCap.</li>
+        <li>
+          Provide
+          <a href="https://github.com/dynobo/normcap/discussions/categories/feedback">feedback</a>
+          and
+          <a href="https://github.com/dynobo/normcap/discussions/categories/ideas">ideas</a>.
+        </li>
+        <li>
+          If you know Python, support on
+          <a href="https://github.com/dynobo/normcap/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22">open
+            issues</a>.
+        </li>
+      </ul>
+      <h5>Not at all satisfied with NormCap?</h5>
+      <p>
+        Try an <a href="#faqs-alternatives">alternative applications</a> and
+        see if they work better for you.
+      </p>
+    </article>
 
-      <article id="usage">
-        <div class="hgroup">
-          <h2>Usage</h2>
-          <h3>
-            A short guide for using NormCap and its most important features.
-          </h3>
-        </div>
-        <h4>Quickstart</h4>
-        <ol>
-          <li>Start NormCap and wait until a pink border appears.</li>
-          <li>Select a region on screen with your mouse.</li>
+    <article id="faqs">
+      <div class="hgroup">
+        <h2>Frequently Asked Questions</h2>
+        <h3>
+          A knowledge base for common issues and additional information.
+        </h3>
+      </div>
+      <h4>General</h4>
+      <details id="faqs-languages">
+        <summary>How can I add additional languages to NormCap?</summary>
+        <p>
+          The <strong>prebuild packages</strong> are shipped with the
+          following languages English, Arabic, Chinese, German, Spanish and
+          Russian. If you miss a language, click the settings icon and "open
+          data folder..." (in the "Languages" section), then follow the
+          instructions in the file
+          <a href="https://github.com/dynobo/normcap/blob/main/src/normcap/resources/tessdata/add_more_languages.txt"
+            target="_blank">add_more_languages.txt</a>.
+        </p>
+        <p>
+          If you installed NormCap as <strong>Python package</strong>, refer
+          to the online documentation on how to install additional language
+          for Tesseract on your system.
+        </p>
+      </details>
+      <details id="faqs-improve-detection">
+        <summary>How can I improve the detection accuracy?</summary>
+        <p>
+          The most import thing is to specify the correct language(s) (via
+          settings menu or the <code>--language</code> command line argument).
+          Keep in mind: selecting multiple languages at once slows down the
+          recognition a bit.
+        </p>
+        <p>
+          Sometimes Tesseract struggles with recognizing text with just very
+          few characters, like a single word. In this case try selecting a
+          larger portion of text.
+        </p>
+        <p>
+          The pre-build NormCap packages are shipped with the
+          <a href="https://github.com/tesseract-ocr/tessdata_fast" target="_blank">tessdata-fast</a>
+          models, which offer a very good accuracy to speed compromise. But
+          you can also try to add the models from
+          <a href="https://github.com/tesseract-ocr/tessdata" target="_blank">tessdata</a>
+          or
+          <a href="https://github.com/tesseract-ocr/tessdata_best" target="_blank">tessdata-best</a>
+          instead as <a href="#faqs-languages">described above</a>.
+        </p>
+        <p>
+          If the results are still bad, please submit a screenshot of the text
+          you are trying to recognize
+          <a href="https://github.com/dynobo/normcap/issues">as an issue</a>.
+        </p>
+      </details>
+      <details id="faqs-cloud">
+        <summary>Is my image/text analyzed in "the cloud"?</summary>
+        <p>
+          No. The text recognition is performed offline using the OCR
+          framework
+          <a href="https://github.com/tesseract-ocr/tesseract" target="_blank">Tesseract</a>.
+        </p>
+      </details>
+      <details id="faqs-data-sent">
+        <summary>Is any other data send to the internet?</summary>
+        <p>
+          No telemetry data is collected and by default also no other data is
+          sent anywhere.
+        </p>
+        <p>
+          However, some (optional) features require accessing resources on the
+          web and therefore expose minimal information (like IP address) to
+          the accessed server:
+        </p>
+        <ul>
           <li>
-            Paste the recognized text from the clipboard anywhere you like.
+            If you enable the check for updates on start, the application
+            checks NormCap's releases page on github.com.
           </li>
-        </ol>
-        <h4>User Interface</h4>
-        <ul>
           <li>
-            The settings can be accessed via the
-            <span class="primary">⚙</span>-icon in the top right.
+            If you download additional languages, they are being fetched from
+            github.com, too.
           </li>
+        </ul>
+      </details>
+      <details id="faqs-shortcuts">
+        <summary>Can I start NormCap via a keyboard shortcut?</summary>
+        <p>
+          Yes, but you'll have to configure it on your own using your
+          operating system's tools:
+        </p>
+        <ul>
           <li>
-            In the settings you can adjust the language(s) you are trying to
-            recognize, which is important for a good accuracy.
+            Linux:
+            <ul>
+              <li>
+                Ubuntu/Gnome:
+                <a href="https://help.ubuntu.com/stable/ubuntu-help/keyboard-shortcuts-set.html">Set Keyboard
+                  Shortcuts</a>
+              </li>
+              <li>
+                Manjaro/XFCE, Plasma:
+                <a href="https://wiki.manjaro.org/index.php?title=Keyboard_Shortcuts">Keyboard Shortcuts</a>
+              </li>
+            </ul>
           </li>
           <li>
-            The icons <span class="primary">★</span> or
-            <span class="primary">☰</span> next to the selection-rectangle
-            indicate the active "capture mode" (see below).
+            MacOS:
+            <a href="https://www.wikihow.com/Set-a-Keyboard-Shortcut-to-Open-Mac-Apps">Set a keyboard shortcut to open
+              Mac apps</a>
           </li>
           <li>
-            To abort a capture or quit NormCap press <code>&lt;esc&gt;</code>
+            Windows 10:
+            <a href="https://www.cnet.com/tech/computing/open-programs-with-keyboard-shortcuts-in-windows-10/">Open
+              programs with keyboard shortcuts in Windows 10</a>
           </li>
         </ul>
-
-        <h4>Capture Modes</h4>
         <p>
-          The settings menu <span class="primary">⚙</span> allows switching
-          between the two capture modes: "parse" and "raw":
+          Ask your preferred search engine for support or different ways to do
+          this.
+        </p>
+      </details>
+      <details id="faqs-alternatives">
+        <summary>Are there alternatives to NormCap?</summary>
+        <p>
+          Some applications offer similar features like NormCap and might be a
+          good or even better alternative for you: It completely depends on
+          your use case and requirements. Some similar open-source Projects
+          are:
         </p>
         <ul>
           <li>
-            <p><strong>"Raw"-Mode </strong></p>
-            <p>
-              Marked by the <span class="primary">☰</span> symbol, it outputs
-              the detected text just as detected by the OCR software. Keeps the
-              text as recognized, e.g. doesn't remove line-breaks.
-            </p>
+            <a href="https://github.com/RajSolai/TextSnatcher" target="_blank">TextSnatcher</a>
           </li>
           <li>
-            <p><strong>"Parse"-Mode</strong> <small>(default)</small></p>
-            <p>
-              Indicated by the <span class="primary">★</span> symbol, it
-              performs some formatting of the output based on certain
-              implemented rules, which can take additional information like text
-              position into account. In a first step, every rule calculates a
-              "score" to determine the likelihood of being responsible for this
-              type of text. In a second step, the rule which achieved the
-              highest "score" takes the necessary actions to "transform" the
-              input text according to its type. Those rules are currently
-              implemented:
-            </p>
-            <table>
-              <caption>
-                Heuristics performed in parse-mode.
-              </caption>
-              <thead>
-                <tr>
-                  <th scope="col">
-                    <strong>Rule&NonBreakingSpace;name</strong>
-                  </th>
-                  <th scope="col"><strong>Score heuristics</strong></th>
-                  <th scope="col"><strong>Transform</strong></th>
-                </tr>
-              </thead>
-              <tbody>
-                <tr>
-                  <td><strong>Single line</strong></td>
-                  <td>Only single line is detected</td>
-                  <td>Trim unnecessary whitespace</td>
-                </tr>
-                <tr>
-                  <td><strong>Multi line</strong></td>
-                  <td>Multiple lines, but single paragraph</td>
-                  <td>
-                    Separate using line breaks and trim unnecessary whitespace
-                    in each line
-                  </td>
-                </tr>
-                <tr>
-                  <td><strong>Paragraph</strong></td>
-                  <td>Multiple blocks of lines or multiple paragraphs</td>
-                  <td>
-                    Join every paragraph into a single line, separate different
-                    paragraphs by empty line
-                  </td>
-                </tr>
-                <tr>
-                  <td><strong>E-Mail</strong></td>
-                  <td>Number of chars in email addresses vs. overall chars</td>
-                  <td>
-                    Transform to a comma-separated list of email addresses
-                  </td>
-                </tr>
-                <tr>
-                  <td><strong>URL</strong></td>
-                  <td>Number of chars in URLs vs. overall chars</td>
-                  <td>Transform to line-break separated URLs</td>
-                </tr>
-              </tbody>
-            </table>
+            <a href="https://getgreenshot.org" target="_blank">GreenShot</a>
           </li>
-        </ul>
-      </article>
-
-      <article id="support">
-        <div class="hgroup">
-          <h2>Support</h2>
-          <h3>When things did not went as expected.</h3>
-        </div>
-        <h5>You need support with NormCap?</h5>
-        <ul>
           <li>
-            For general questions use the
-            <a
-              href="https://github.com/dynobo/normcap/discussions/categories/q-a"
-              >discussions</a
-            >
-            forum.
+            <a href="https://github.com/ianzhao05/textshot" target="_blank">TextShot</a>
           </li>
           <li>
-            If you have found a bug, open an
-            <a href="https://github.com/dynobo/normcap/issues">issue</a>.
+            <a href="https://github.com/manisandro/gImageReader" target="_blank">gImageReader</a>
           </li>
           <li>
-            Take a look at the
-            <a href="#faqs">frequently asked questions</a> below.
+            <a href="https://sourceforge.net/projects/capture2text" target="_blank">Capture2Text</a>
           </li>
-        </ul>
-        <h5>You want to support NormCap?</h5>
-        <ul>
-          <li>Tell your friends about NormCap.</li>
           <li>
-            Provide
-            <a
-              href="https://github.com/dynobo/normcap/discussions/categories/feedback"
-              >feedback</a
-            >
-            and
-            <a
-              href="https://github.com/dynobo/normcap/discussions/categories/ideas"
-              >ideas</a
-            >.
+            <a href="https://github.com/TenderOwl/Frog" target="_blank">Frog</a>
           </li>
           <li>
-            If you know Python, support on
-            <a
-              href="https://github.com/dynobo/normcap/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22"
-              >open issues</a
-            >.
+            <a href="https://github.com/RhetTbull/textinator" target="_blank">Textinator</a>
           </li>
         </ul>
-        <h5>Not at all satisfied with NormCap?</h5>
+      </details>
+      <details id="faqs-windows-cli">
+        <summary>
+          [Windows] How can I start NormCap with a command line argument?
+        </summary>
         <p>
-          Try an <a href="#faqs-alternatives">alternative applications</a> and
-          see if they work better for you.
+          To run NormCap with an argument <em>once</em>, run it in the
+          "Terminal":
         </p>
-      </article>
-
-      <article id="faqs">
-        <div class="hgroup">
-          <h2>Frequently Asked Questions</h2>
-          <h3>
-            A knowledge base for common issues and additional information.
-          </h3>
-        </div>
-        <h4>General</h4>
-        <details id="faqs-languages">
-          <summary>How can I add additional languages to NormCap?</summary>
-          <p>
-            The <strong>prebuild packages</strong> are shipped with the
-            following languages English, Arabic, Chinese, German, Spanish and
-            Russian. If you miss a language, click the settings icon and "open
-            data folder..." (in the "Languages" section), then follow the
-            instructions in the file
-            <a
-              href="https://github.com/dynobo/normcap/blob/main/src/normcap/resources/tessdata/add_more_languages.txt"
-              target="_blank"
-              >add_more_languages.txt</a
-            >.
-          </p>
-          <p>
-            If you installed NormCap as <strong>Python package</strong>, refer
-            to the online documentation on how to install additional language
-            for Tesseract on your system.
-          </p>
-        </details>
-        <details id="faqs-improve-detection">
-          <summary>How can I improve the detection accuracy?</summary>
-          <p>
-            The most import thing is to specify the correct language(s) (via
-            settings menu or the <code>--language</code> command line argument).
-            Keep in mind: selecting multiple languages at once slows down the
-            recognition a bit.
-          </p>
-          <p>
-            Sometimes Tesseract struggles with recognizing text with just very
-            few characters, like a single word. In this case try selecting a
-            larger portion of text.
-          </p>
-          <p>
-            The pre-build NormCap packages are shipped with the
-            <a
-              href="https://github.com/tesseract-ocr/tessdata_fast"
-              target="_blank"
-              >tessdata-fast</a
-            >
-            models, which offer a very good accuracy to speed compromise. But
-            you can also try to add the models from
-            <a href="https://github.com/tesseract-ocr/tessdata" target="_blank"
-              >tessdata</a
-            >
-            or
-            <a
-              href="https://github.com/tesseract-ocr/tessdata_best"
-              target="_blank"
-              >tessdata-best</a
-            >
-            instead as <a href="#faqs-languages">described above</a>.
-          </p>
-          <p>
-            If the results are still bad, please submit a screenshot of the text
-            your are trying to recognize
-            <a href="https://github.com/dynobo/normcap/issues">as an issue</a>.
-          </p>
-        </details>
-        <details id="faqs-cloud">
-          <summary>Is my image/text analyzed in "the cloud"?</summary>
-          <p>
-            No. The text recognition is performed offline using the OCR
-            framework
-            <a href="https://github.com/tesseract-ocr/tesseract" target="_blank"
-              >Tesseract</a
-            >.
-          </p>
-        </details>
-        <details id="faqs-data-sent">
-          <summary>Is any other data send to the internet?</summary>
-          <p>
-            No telemetry data is collected and by default also no other data is
-            send anywhere.
-          </p>
-          <p>
-            However, some (optional) features require accessing resources on the
-            web and therefore expose minimal information (like IP address) to
-            the accessed server:
-          </p>
-          <ul>
-            <li>
-              If you enable the check for updates on start, the application
-              checks NormCap's releases page on github.com.
-            </li>
-            <li>
-              If you download additional languages, they are being fetched from
-              github.com, too.
-            </li>
-          </ul>
-        </details>
-        <details id="faqs-shortcuts">
-          <summary>Can I start NormCap via a keyboard shortcut?</summary>
-          <p>
-            Yes, but you'll have to configure it on your own using your
-            operating system's tools:
-          </p>
-          <ul>
-            <li>
-              Linux:
-              <ul>
-                <li>
-                  Ubuntu/Gnome:
-                  <a
-                    href="https://help.ubuntu.com/stable/ubuntu-help/keyboard-shortcuts-set.html"
-                    >Set Keyboard Shortcuts</a
-                  >
-                </li>
-                <li>
-                  Manjaro/XFCE, Plasma:
-                  <a
-                    href="https://wiki.manjaro.org/index.php?title=Keyboard_Shortcuts"
-                    >Keyboard Shortcuts</a
-                  >
-                </li>
-              </ul>
-            </li>
-            <li>
-              MacOS:
-              <a
-                href="https://www.wikihow.com/Set-a-Keyboard-Shortcut-to-Open-Mac-Apps"
-                >Set a keyboard shortcut to open Mac apps</a
-              >
-            </li>
-            <li>
-              Windows 10:
-              <a
-                href="https://www.cnet.com/tech/computing/open-programs-with-keyboard-shortcuts-in-windows-10/"
-                >Open programs with keyboard shortcuts in Windows 10</a
-              >
-            </li>
-          </ul>
-          <p>
-            Ask your preferred search engine for support or different ways to do
-            this.
-          </p>
-        </details>
-        <details id="faqs-alternatives">
-          <summary>Are there alternatives to NormCap?</summary>
-          <p>
-            Some applications offer similar features like NormCap and might be a
-            good or even better alternative for you: It completely depends on
-            your use case and requirements. Some similar OpenSource Projects
-            are:
-          </p>
-          <ul>
-            <li>
-              <a href="https://github.com/RajSolai/TextSnatcher" target="_blank"
-                >TextSnatcher</a
-              >
-            </li>
-            <li>
-              <a href="https://getgreenshot.org" target="_blank">GreenShot</a>
-            </li>
-            <li>
-              <a href="https://github.com/ianzhao05/textshot" target="_blank"
-                >TextShot</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://github.com/manisandro/gImageReader"
-                target="_blank"
-                >gImageReader</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://sourceforge.net/projects/capture2text"
-                target="_blank"
-                >Capture2Text</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://github.com/TenderOwl/Frog"
-                target="_blank"
-                >Frog</a
-              >
-            </li>
-          </ul>
-        </details>
-        <details id="faqs-windows-cli">
-          <summary>
-            [Windows] How can I start NormCap with a command line argument?
-          </summary>
-          <p>
-            To run NormCap with an argument <em>once</em>, run it in the
-            "Terminal":
-          </p>
-          <pre><code>C:\Users\&lt;USER-NAME&gt;\AppData\Local\Programs\NormCap\python\python.exe -m normcap --help</code></pre>
-        </details>
-        <details id="faqs-macos-cli">
-          <summary>
-            [MacOS] How can I start NormCap with a command line argument?
-          </summary>
-          <p>
-            To run NormCap with an argument <em>once</em>, run it in the
-            "Terminal":
-          </p>
-          <pre><code>$ /Applications/NormCap.app/Contents/MacOS/NormCap --help</code></pre>
-          <p>
-            To <em>create a launcher</em> with command line arguments, launch
-            the "Script Editor" and make a new script with the desired command
-            line arguments, e.g.:
-          </p>
-          <pre><code>do shell script "exec /Applications/NormCap.app/Contents/MacOS/NormCap --tray"s</code></pre>
-          <p>
-            Save the script as type "Application" in the folder
-            "/Applications"<br />
-            <small>
-              (When this new Application is started, an additional Icon will
-              show up in the Dock. If you know a way to avoid this, please
-              <a href="https://github.com/dynobo/normcap/issues"
-                >open an issue</a
-              >)
-            </small>
-          </p>
-        </details>
+        <pre><code>C:\Users\&lt;USER-NAME&gt;\AppData\Local\Programs\NormCap\NormCap.exe --help</code></pre>
+        <p>
+          Due to the way NormCap is packaged, you will see no output in the terminal. Instead, the output is
+          written to a file in the same folder:
+        </p>
+        <pre><code>C:\Users\&lt;USER-NAME&gt;\AppData\Local\Programs\NormCap\NormCap.exe.log</code></pre>
+      </details>
+      <details id="faqs-windows-log">
+        <summary>
+          [Windows] How can I write a log-file with debugging information?
+        </summary>
+        <p>
+          Run NormCap with from the "Terminal" with the following argument:
+        </p>
+        <pre><code>C:\Users\&lt;USER-NAME&gt;\AppData\Local\Programs\NormCap\NormCap.exe -v debug</code></pre>
+        <p>
+          After NormCap exits, you can find the debug and error output in the file:
+        </p>
+        <pre><code>C:\Users\&lt;USER-NAME&gt;\AppData\Local\Programs\NormCap\NormCap.exe.log</code></pre>
+        <p>
+          In case of problems, <a href="https://github.com/dynobo/normcap/issues">create a new issue on GitHub</a> and
+          include the information in the log file.
+        </p>
+      </details>
+      <details id="faqs-macos-cli">
+        <summary>
+          [MacOS] How can I start NormCap with a command line argument?
+        </summary>
+        <p>
+          To run NormCap with an argument <em>once</em>, run it in the
+          "Terminal":
+        </p>
+        <pre><code>$ /Applications/NormCap.app/Contents/MacOS/NormCap --help</code></pre>
+        <p>
+          To <em>create a launcher</em> with command line arguments, launch
+          the "Script Editor" and make a new script with the desired command
+          line arguments, e.g.:
+        </p>
+        <pre><code>do shell script "exec /Applications/NormCap.app/Contents/MacOS/NormCap --tray"s</code></pre>
+        <p>
+          Save the script as type "Application" in the folder
+          "/Applications"<br />
+          <small>
+            (When this new Application is started, an additional Icon will
+            show up in the Dock. If you know a way to avoid this, please
+            <a href="https://github.com/dynobo/normcap/issues">open an issue</a>)
+          </small>
+        </p>
+      </details>
 
-        <h4>Troubleshooting</h4>
-        <details id="faqs-is-not-starting">
-          <summary>NormCap is not starting</summary>
-          <p>
-            Please try to start again with the <code>-v debug</code> option. This should reveal more
-            information useful for problem solving.
-          </p>
-        </details>
-        <details id="faqs-couldnt-load-xcb">
-          <summary>[Linux] Could not load the Qt platform plugin xcb</summary>
-          <p>In case you get the following output...</p>
-          <pre><code>$ normcap -v debug
+      <h4>Troubleshooting</h4>
+      <details id="faqs-is-not-starting">
+        <summary>NormCap is not starting</summary>
+        <p>
+          Please try to start again with the <code>-v debug</code> option. This should reveal more
+          information useful for problem-solving.
+        </p>
+      </details>
+      <details id="faqs-couldnt-load-xcb">
+        <summary>[Linux] Could not load the Qt platform plugin xcb</summary>
+        <p>In case you get the following output...</p>
+        <pre><code>$ normcap -v debug
 12:06:34 - INFO    - normcap.app            - L:32  - Starting Normcap v0.2.0
 12:06:34 - DEBUG   - normcap.utils          - L:199 - [QT] L:0, func: None, file: None
 12:06:34 - DEBUG   - normcap.utils          - L:200 - [QT] QtInfoMsg - Could not load the Qt platform plugin "xcb" in "" even though it was found.
 12:06:34 - DEBUG   - normcap.utils          - L:199 - [QT] L:0, func: None, file: None
 12:06:34 - DEBUG   - normcap.utils          - L:200 - [QT] QtFatalMsg - This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
 Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.</code></pre>
-          <p>
-            ... the chances are, some system requirements are outdated. You can
-            check this with <code>apt list "libxcb-util*"</code>:
-          </p>
-          <pre><code>$ apt list "libxcb-util*"
+        <p>
+          ... the chances are, some system requirements are outdated. You can
+          check this with <code>apt list "libxcb-util*"</code>:
+        </p>
+        <pre><code>$ apt list "libxcb-util*"
 Listing... Done
 libxcb-util-dev/hirsute 0.4.0-1 amd64
 libxcb-util-dev/hirsute 0.4.0-1 i386
@@ -591,179 +529,188 @@ <h4>Troubleshooting</h4>
 libxcb-util0-dev/hirsute 0.4.0-1 i386
 libxcb-util1/hirsute,now 0.4.0-1 amd64 [installed,automatic]
 libxcb-util1/hirsute 0.4.0-1 i386</code></pre>
-          <p>
-            Is only <code>libxcb-util0</code> shown but
-            <code>libxcb-util1</code> is missing? Then you can try to create a
-            symlink for the missing version:
-          </p>
-          <pre><code>sudo ln -s /lib/x86_64-linux-gnu/libxcb-util.so.0 /lib/x86_64-linux-gnu/libxcb-util.so.1</code></pre>
-        </details>
-        <details id="faqs-doesnt-show-system-tray">
-          <summary>[Linux] Normcap does not show up in system tray</summary>
-          <p>
-            Is your display environment Gnome Shell? Then you probably need to
-            install a
-            <a href="https://extensions.gnome.org/" target="_blank"
-              >Gnome Shell extension</a
-            >
-            to support showing applications in the top bar, e.g.:
-          </p>
-          <ul>
-            <li>
-              <a
-                href="https://extensions.gnome.org/extension/615/appindicator-support/"
-                target="_blank"
-                >AppIndicator Support</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://extensions.gnome.org/extension/1301/ubuntu-appindicators/"
-                target="_blank"
-                >Ubuntu AppIndicators</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://extensions.gnome.org/extension/1503/tray-icons/"
-                target="_blank"
-                >Tray Icons</a
-              >
-            </li>
-            <li>
-              <a
-                href="https://extensions.gnome.org/extension/2890/tray-icons-reloaded/"
-                target="_blank"
-                >Tray Icons: Reloaded</a
-              >
-            </li>
-          </ul>
-        </details>
-        <details id="faqs-doesnt-show-notification">
-          <summary>
-            [Linux] Normcap doesn't show a notification after capture
-          </summary>
-          <p>
-            NormCap's notifcations depend on the system tray functionality. Try
-            running normcap with the <code>--tray</code> flag, and if nothing is
-            shown in the system tray, proceed like in the question above.
-          </p>
-        </details>
+        <p>
+          Is only <code>libxcb-util0</code> shown but
+          <code>libxcb-util1</code> is missing? Then you can try to create a
+          symlink for the missing version:
+        </p>
+        <pre><code>sudo ln -s /lib/x86_64-linux-gnu/libxcb-util.so.0 /lib/x86_64-linux-gnu/libxcb-util.so.1</code></pre>
+      </details>
+      <details id="faqs-doesnt-show-system-tray">
+        <summary>[Linux] Normcap does not show up in system tray</summary>
+        <p>
+          Is your display environment Gnome Shell? Then you probably need to
+          install a
+          <a href="https://extensions.gnome.org/" target="_blank">Gnome Shell extension</a>
+          to support showing applications in the top bar, e.g.:
+        </p>
+        <ul>
+          <li>
+            <a href="https://extensions.gnome.org/extension/615/appindicator-support/" target="_blank">AppIndicator
+              Support</a>
+          </li>
+          <li>
+            <a href="https://extensions.gnome.org/extension/1301/ubuntu-appindicators/" target="_blank">Ubuntu
+              AppIndicators</a>
+          </li>
+          <li>
+            <a href="https://extensions.gnome.org/extension/1503/tray-icons/" target="_blank">Tray Icons</a>
+          </li>
+          <li>
+            <a href="https://extensions.gnome.org/extension/2890/tray-icons-reloaded/" target="_blank">Tray Icons:
+              Reloaded</a>
+          </li>
+        </ul>
+      </details>
+      <details id="faqs-doesnt-show-notification">
+        <summary>
+          [Linux] Normcap doesn't show a notification after capture
+        </summary>
+        <p>
+          NormCap's notifications depend on the system tray functionality. Try
+          running normcap with the <code>--tray</code> flag, and if nothing is
+          shown in the system tray, proceed like in the question above.
+        </p>
+      </details>
 
-        <h4>Development</h4>
-        <details id="faqs-no-such-file">
-          <summary>
-            "No such file or directory" error when running
-            <code>briefcase build</code>
-          </summary>
-          <p>
-            To verify, if this is the issue you are facing, run te build docker
-            interactively and try to run the
-            <code>linuxdeploy-*.AppImage</code> file there:
-          </p>
-          <pre><code>$ docker run -it \
+      <h4>Development</h4>
+      <details id="faqs-no-such-file">
+        <summary>
+          "No such file or directory" error when running
+          <code>briefcase build</code>
+        </summary>
+        <p>
+          To verify, if this is the issue you are facing, run the docker image
+          interactively and try to run the
+          <code>linuxdeploy-*.AppImage</code> file there:
+        </p>
+        <pre><code>$ docker run -it \
   --volume /home/&lt;USER&gt;/&lt;PROJECT PATH&gt;/normcap/linux:/app:z \
   --volume /home/&lt;USER&gt;/.briefcase:/home/brutus/.briefcase:z \
   --env VERSION=0.2.0 briefcase/eu.dynobo.normcap:py3.9 \
   /bin/bash
 $ /home/brutus/.briefcase/tools/linuxdeploy-x86_64.AppImage</code></pre>
-          <p>
-            If that results in a `No such file or directory` error, according to
-            <a
-              href="https://github.com/AppImage/AppImageKit/issues/1027#issuecomment-641601097"
-              target="_blank"
-              >this issue</a
-            >
-            and
-            <a
-              href="https://github.com/AppImage/AppImageKit/issues/828"
-              target="_blank"
-              >this one</a
-            >
-            a workaround is to correct the "magic" bytes of the AppImage. This
-            worked for me:
-          </p>
-          <pre><code>sed '0,/AI\x02/{s|AI\x02|\x00\x00\x00|}' -i linuxdeploy-x86_64.AppImage</code></pre>
-        </details>
-      </article>
+        <p>
+          If that results in a `No such file or directory` error, according to
+          <a href="https://github.com/AppImage/AppImageKit/issues/1027#issuecomment-641601097" target="_blank">this
+            issue</a>
+          and
+          <a href="https://github.com/AppImage/AppImageKit/issues/828" target="_blank">this one</a>
+          a workaround is to correct the "magic" bytes of the AppImage. This
+          worked for me:
+        </p>
+        <pre><code>sed '0,/AI\x02/{s|AI\x02|\x00\x00\x00|}' -i linuxdeploy-x86_64.AppImage</code></pre>
+      </details>
+    </article>
 
-      <article id="python-package">
-        <div class="hgroup">
-          <h2>Python package</h2>
-          <h3>
-            An advanced installation method as <em>alternative</em> to the
-            prebuild packages.
-          </h3>
-        </div>
-        <details>
-          <summary>Comparision to prebuild packages</summary>
-          <div class="row comparison">
-            <div class="col-sm-6">
-              <p>Prebuild:</p>
-              <ul>
-                <li>Easier to install</li>
-                <li>Better system integration</li>
-                <li>No admin rights required</li>
-              </ul>
-            </div>
-            <div class="col-sm-6">
-              <p>Python package:</p>
-              <ul>
-                <li>Slightly faster startup</li>
-                <li>
-                  <span
-                    data-html="true"
-                    data-tooltip="Depends on your&#10;system setup"
-                    >Might</span
-                  >
-                  need less disk space
-                </li>
-              </ul>
-            </div>
+    <article id="python-package">
+      <div class="hgroup">
+        <h2>Python package</h2>
+        <h3>
+          An advanced installation method as <em>alternative</em> to the
+          prebuild packages.
+        </h3>
+      </div>
+      <details>
+        <summary>Comparison to prebuild packages</summary>
+        <div class="row comparison">
+          <div class="col-sm-6">
+            <p>Prebuild:</p>
+            <ul>
+              <li>Easier to install</li>
+              <li>Better system integration</li>
+              <li>No admin rights required</li>
+            </ul>
           </div>
-        </details>
-        <details id="python-package-install-on-linux">
-          <summary>Install on Linux</summary>
-          <ol>
-            <li>
-              Install dependencies:
-              <ul>
-                <li>
-                  Ubuntu/Debian:
-                  <pre><code>sudo apt install tesseract-ocr tesseract-ocr-eng
+          <div class="col-sm-6">
+            <p>Python package:</p>
+            <ul>
+              <li>Slightly faster startup</li>
+              <li>Requires an installation of Python >=3.9</li>
+              <li>
+                <span data-html="true" data-tooltip="Depends on your&#10;system setup">Might</span>
+                need less disk space
+              </li>
+            </ul>
+          </div>
+        </div>
+      </details>
+      <details id="python-package-install-on-linux">
+        <summary>Install on Linux</summary>
+        <ol>
+          <li>
+            Install dependencies:
+            <ul>
+              <li>
+                Ubuntu/Debian:
+                <pre><code>sudo apt install build-essential tesseract-ocr tesseract-ocr-eng
                     libtesseract-dev libleptonica-dev</code></pre>
-                </li>
-                <li>
-                  Arch:
-                  <pre><code>sudo pacman -S tesseract tesseract-data-eng</code></pre>
-                </li>
-                <li>
-                  Fedora:
-                  <pre><code>sudo dnf install tesseract</code></pre>
-                </li>
-                <li>
-                  openSUSE:
-                  <pre><code>sudo zypper install python3-devel tesseract-ocr
+              </li>
+              <li>
+                Arch:
+                <pre><code>sudo pacman -S tesseract tesseract-data-eng</code></pre>
+              </li>
+              <li>
+                Fedora:
+                <pre><code>sudo dnf install tesseract</code></pre>
+              </li>
+              <li>
+                openSUSE:
+                <pre><code>sudo zypper install python3-devel tesseract-ocr
                     tesseract-ocr-devel</code></pre>
-                </li>
-              </ul>
+              </li>
+            </ul>
+          </li>
+          <li>
+            Install NormCap:
+            <pre><code>pip install normcap</code></pre>
+          </li>
+          <li>
+            Run:
+            <pre><code>./normcap</code></pre>
+          </li>
+        </ol>
+      </details>
+      <details id="python-package-install-on-macos">
+        <summary>Install on MacOS</summary>
+        <ol>
+          <li>
+            Install dependencies:
+            <pre><code>brew install tesseract tesseract-lang</code></pre>
+          </li>
+          <li>
+            Install NormCap:
+            <pre><code>pip install normcap</code></pre>
+          </li>
+          <li>
+            Run:
+            <pre><code>./normcap</code></pre>
+          </li>
+        </ol>
+      </details>
+      <details id="python-package-install-on-windows">
+        <summary>Install on Windows</summary>
+        <div>
+          <ol>
+            <li>
+              Install "Tesseract 5", e.g. by using the
+              <a href="https://github.com/UB-Mannheim/tesseract/wiki" target="_blank">installer provided by UB
+                Mannheim</a>.
             </li>
             <li>
-              Install NormCap:
-              <pre><code>pip install normcap</code></pre>
+              Set the environment variable TESSDATA_PREFIX to Tesseract's data
+              folder, e.g.:
+              <pre><code>setx TESSDATA_PREFIX "C:\Program Files\Tesseract-OCR\tessdata"</code></pre>
             </li>
             <li>
-              Run:
-              <pre><code>./normcap</code></pre>
+              Append Tesseract's location to the environment variable "Path",
+              e.g.:
+              <pre><code>setx Path "%Path%;C:\Program Files\Tesseract-OCR"</code></pre>
             </li>
-          </ol>
-        </details>
-        <details id="python-package-install-on-macos">
-          <summary>Install on MacOS</summary>
-          <ol>
             <li>
-              Install dependencies:
-              <pre><code>brew install tesseract tesseract-lang</code></pre>
+              Make sure to close and reopen your current terminal window to
+              apply the new variables. Test it by running:
+              <pre><code>tesseract --list-langs</code></pre>
             </li>
             <li>
               Install NormCap:
@@ -774,55 +721,18 @@ <h3>
               <pre><code>./normcap</code></pre>
             </li>
           </ol>
-        </details>
-        <details id="python-package-install-on-windows">
-          <summary>Install on Windows</summary>
-          <div>
-            <ol>
-              <li>
-                Install "Tesseract 5", e.g. by using the
-                <a
-                  href="https://github.com/UB-Mannheim/tesseract/wiki"
-                  target="_blank"
-                  >installer provided by UB Mannheim</a
-                >.
-              </li>
-              <li>
-                Set the environment variable TESSDATA_PREFIX to Tesseract's data
-                folder, e.g.:
-                <pre><code>setx TESSDATA_PREFIX "C:\Program Files\Tesseract-OCR\tessdata"</code></pre>
-              </li>
-              <li>
-                Append Tesseract's location to the environment variable "Path",
-                e.g.:
-                <pre><code>setx Path "%Path%;C:\Program Files\Tesseract-OCR"</code></pre>
-              </li>
-              <li>
-                Make sure to close and reopen your current terminal window to
-                apply the new variables. Test it by running:
-                <pre><code>tesseract --list-langs</code></pre>
-              </li>
-              <li>
-                Install NormCap:
-                <pre><code>pip install normcap</code></pre>
-              </li>
-              <li>
-                Run:
-                <pre><code>./normcap</code></pre>
-              </li>
-            </ol>
-          </div>
-        </details>
-      </article>
-    </main>
+        </div>
+      </details>
+    </article>
+  </main>
+
+  <footer class="container-fluid">
+    <small>Built with <span class="primary">♥</span> and
+      <a href="https://picocss.com" class="secondary" target="_blank">Pico</a>
+    </small>
+  </footer>
 
-    <footer class="container-fluid">
-      <small
-        >Built with <span class="primary">♥</span> and
-        <a href="https://picocss.com" class="secondary" target="_blank">Pico</a>
-      </small>
-    </footer>
+  <script src="script.js"></script>
+</body>
 
-    <script src="script.js"></script>
-  </body>
 </html>
diff --git a/package/build.py b/package/build.py
new file mode 100644
index 00000000..f1f4b7d8
--- /dev/null
+++ b/package/build.py
@@ -0,0 +1,38 @@
+import argparse
+import sys
+
+from platforms.linux_briefcase import LinuxBriefcase
+from platforms.linux_nuitka import LinuxNuitka
+from platforms.macos_briefcase import MacBriefcase
+from platforms.macos_nuitka import MacNuitka
+from platforms.windows_briefcase import WindowsBriefcase
+from platforms.windows_nuitka import WindowsNuitka
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        prog="Package NormCap", description="Create prebuild packages of Normcap."
+    )
+    parser.add_argument(
+        "--framework",
+        required=True,
+        action="store",
+        choices=["nuitka", "briefcase"],
+        help="Select python bundling framework.",
+    )
+    parser.add_argument(
+        "--dev",
+        action="store_true",
+        help="Development build with version 0.0.1.",
+    )
+    args = parser.parse_args()
+
+    if sys.platform.startswith("win"):
+        builder = WindowsNuitka if args.framework == "nuitka" else WindowsBriefcase
+
+    elif sys.platform.startswith("darwin"):
+        builder = MacNuitka if args.framework == "nuitka" else MacBriefcase
+
+    elif sys.platform.startswith("linux"):
+        builder = LinuxNuitka if args.framework == "nuitka" else LinuxBriefcase
+
+    builder().create()
diff --git a/src/normcap/resources/normcap-128.png b/package/imgs/normcap-128.png
similarity index 100%
rename from src/normcap/resources/normcap-128.png
rename to package/imgs/normcap-128.png
diff --git a/src/normcap/resources/normcap-16.png b/package/imgs/normcap-16.png
similarity index 100%
rename from src/normcap/resources/normcap-16.png
rename to package/imgs/normcap-16.png
diff --git a/src/normcap/resources/normcap-256.png b/package/imgs/normcap-256.png
similarity index 100%
rename from src/normcap/resources/normcap-256.png
rename to package/imgs/normcap-256.png
diff --git a/src/normcap/resources/normcap-32.png b/package/imgs/normcap-32.png
similarity index 100%
rename from src/normcap/resources/normcap-32.png
rename to package/imgs/normcap-32.png
diff --git a/src/normcap/resources/normcap-512.png b/package/imgs/normcap-512.png
similarity index 100%
rename from src/normcap/resources/normcap-512.png
rename to package/imgs/normcap-512.png
diff --git a/src/normcap/resources/normcap-64.png b/package/imgs/normcap-64.png
similarity index 100%
rename from src/normcap/resources/normcap-64.png
rename to package/imgs/normcap-64.png
diff --git a/src/normcap/resources/normcap.icns b/package/imgs/normcap.icns
similarity index 100%
rename from src/normcap/resources/normcap.icns
rename to package/imgs/normcap.icns
diff --git a/src/normcap/resources/normcap.ico b/package/imgs/normcap.ico
similarity index 100%
rename from src/normcap/resources/normcap.ico
rename to package/imgs/normcap.ico
diff --git a/src/normcap/resources/normcap.svg b/package/imgs/normcap.svg
similarity index 100%
rename from src/normcap/resources/normcap.svg
rename to package/imgs/normcap.svg
diff --git a/src/normcap/resources/normcap_install.bmp b/package/imgs/normcap_install.bmp
similarity index 100%
rename from src/normcap/resources/normcap_install.bmp
rename to package/imgs/normcap_install.bmp
diff --git a/src/normcap/resources/normcap_install.icns b/package/imgs/normcap_install.icns
similarity index 100%
rename from src/normcap/resources/normcap_install.icns
rename to package/imgs/normcap_install.icns
diff --git a/src/normcap/resources/normcap_install.png b/package/imgs/normcap_install.png
similarity index 100%
rename from src/normcap/resources/normcap_install.png
rename to package/imgs/normcap_install.png
diff --git a/src/normcap/resources/normcap_install_bg.bmp b/package/imgs/normcap_install_bg.bmp
similarity index 100%
rename from src/normcap/resources/normcap_install_bg.bmp
rename to package/imgs/normcap_install_bg.bmp
diff --git a/src/normcap/resources/normcap_install_bg.png b/package/imgs/normcap_install_bg.png
similarity index 100%
rename from src/normcap/resources/normcap_install_bg.png
rename to package/imgs/normcap_install_bg.png
diff --git a/src/normcap/resources/normcap_install_top.bmp b/package/imgs/normcap_install_top.bmp
similarity index 100%
rename from src/normcap/resources/normcap_install_top.bmp
rename to package/imgs/normcap_install_top.bmp
diff --git a/src/normcap/resources/metainfo b/package/metainfo
similarity index 100%
rename from src/normcap/resources/metainfo
rename to package/metainfo
diff --git a/package/normcap.wxs b/package/normcap.wxs
new file mode 100644
index 00000000..8a661d54
--- /dev/null
+++ b/package/normcap.wxs
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<?define ProductVersion = "0.3.4" ?>
+<?define ProductUpgradeCode = "63ee06c1-0030-59d7-a5ae-31b45fc8261a" ?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+   <Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)" Name="NormCap" Version="$(var.ProductVersion)" Manufacturer="dynobo" Language="1033">
+        <Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package" InstallScope="perUser" /><Property Id="ALLUSERS" Value="2" />
+        <Property Id="MSIINSTALLPERUSER" Value="1" />
+
+
+        <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
+
+        <Icon Id="ProductIcon" SourceFile="normcap.ico" />
+
+        <Property Id="ARPPRODUCTICON" Value="ProductIcon" />
+        <Property Id="ARPURLINFOABOUT" Value="https://github.com/dynobo/normcap" />
+
+        <Property Id="ARPCONTACT" Value="dynobo@mailbox.org" />
+
+        <Property Id="ARPNOREPAIR" Value="1" />
+        <Property Id="ARPNOMODIFY" Value="1" />
+
+        <Directory Id="TARGETDIR" Name="SourceDir">
+            <Directory Id="ProgramFilesFolder">
+                <Directory Id="normcap_ROOTDIR" Name="NormCap" />
+            </Directory>
+
+            <Directory Id="ProgramMenuFolder">
+                <Directory Id="ProgramMenuSubfolder" Name="NormCap">
+                    <Component Id="ApplicationShortcuts" Guid="*">
+                        <Shortcut Id="ApplicationShortcut1" Name="NormCap" Icon="ProductIcon" Description="OCR-powered screen-capture tool to capture information instead of images" Target="[normcap_ROOTDIR]NormCap.exe" WorkingDirectory="normcap_ROOTDIR" />
+                        <RegistryValue Root="HKCU" Key="Software\dynobo\NormCap" Name="installed" Type="integer" Value="1" KeyPath="yes" />
+                        <RemoveFolder Id="ProgramMenuSubfolder" On="uninstall" />
+                    </Component>
+                </Directory>
+            </Directory>
+        </Directory>
+
+        <Feature Id="DefaultFeature" Level="1">
+            <ComponentGroupRef Id="normcap_COMPONENTS" />
+            <ComponentRef Id="ApplicationShortcuts" />
+        </Feature>
+
+        <UI Id="UserInterface">
+          <Property Id="WIXUI_INSTALLDIR" Value="TARGETDIR" />
+          <Property Id="WixUI_Mode" Value="Custom" />
+
+          <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
+          <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="9" Bold="yes" />
+          <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
+
+          <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
+
+          <DialogRef Id="ProgressDlg" />
+          <DialogRef Id="ErrorDlg" />
+          <DialogRef Id="FilesInUse" />
+          <DialogRef Id="FatalError" />
+          <DialogRef Id="UserExit" />
+
+          <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
+          <Publish Dialog="WelcomeDlg" Control="Next" Event="EndDialog" Value="Return" Order="2" />
+
+        </UI>
+
+        <UIRef Id="WixUI_Common" />
+    <WixVariable Id="WixUIDialogBmp" Value="normcap_install_bg.bmp" /><WixVariable Id="WixUIBannerBmp" Value="normcap_install_top.bmp" /><MajorUpgrade DowngradeErrorMessage="Can't downgrade. Uninstall first." /></Product>
+</Wix>
diff --git a/package/platforms/__init__.py b/package/platforms/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/package/platforms/linux_briefcase.py b/package/platforms/linux_briefcase.py
new file mode 100644
index 00000000..7bf9f638
--- /dev/null
+++ b/package/platforms/linux_briefcase.py
@@ -0,0 +1,131 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import inspect
+import os
+import shutil
+from pathlib import Path
+
+import briefcase  # type: ignore
+from platforms.utils import BRIEFCASE_EXCLUDES, BuilderBase, rm_recursive
+
+
+class LinuxBriefcase(BuilderBase):
+    """Create prebuild package for Linux using Briefcase."""
+
+    binary_suffix = ""
+
+    def patch_briefcase_appimage_to_prune_deps(self):
+        """Insert code into briefcase appimage code to remove unnecessary libs."""
+        def_rm_recursive = inspect.getsource(rm_recursive)
+
+        file_path = (
+            Path(briefcase.__file__).parent / "platforms" / "linux" / "appimage.py"
+        )
+        patch = f"""
+import shutil, os
+{def_rm_recursive}
+app_dir = self.appdir_path(app) / "usr" / "app_packages"
+rm_recursive(directory=app_dir, exclude={BRIEFCASE_EXCLUDES["app_packages"]})
+rm_recursive(directory=app_dir / "PySide6", exclude={BRIEFCASE_EXCLUDES["pyside6"]})
+
+lib_dir = self.appdir_path(app) / "usr" / "lib"
+rm_recursive(directory=lib_dir / "PySide6", exclude={BRIEFCASE_EXCLUDES["pyside6"]})
+"""
+        insert_after = 'self.logger.info("Building AppImage...", prefix=app.app_name)'
+        self.patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
+
+    def patch_briefcase_appimage_to_include_tesseract(self):
+        """Insert code into briefcase appimage code to remove unnecessary libs."""
+        file_path = (
+            Path(briefcase.__file__).parent / "platforms" / "linux" / "appimage.py"
+        )
+        insert_after = '"appimage",'
+        patch = """
+"--executable",
+"/usr/bin/tesseract",
+"""
+        self.patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
+
+    def patch_briefcase_create_to_adjust_dockerfile(self):
+        """Add code to add tesseract ppa to Dockerfile."""
+        file_path = Path(briefcase.__file__).parent / "commands" / "create.py"
+        insert_after = "self.install_app_support_package(app=app)"
+        patch = """
+if "linux" in str(bundle_path):
+    print()
+    print("Patching Dockerfile on Linux")
+    import fileinput
+    patch = "\\nRUN apt-add-repository ppa:alex-p/tesseract-ocr-devel"
+    for line in fileinput.FileInput(bundle_path / "Dockerfile", inplace=1):
+        if "RUN apt-add-repository ppa:deadsnakes/ppa" in line:
+            line = line.replace(line, line + patch)
+        print(line, end="")
+"""
+        self.patch_file(file_path=file_path, insert_after=insert_after, patch=patch)
+
+    def bundle_tesseract(self):  # noqa: D102
+        target_path = self.RESOURCE_PATH / "tesseract"
+        target_path.mkdir(exist_ok=True)
+        lib_cache_path = self.BUILD_PATH / ".cache"
+        lib_cache_path.mkdir(exist_ok=True)
+        try:
+            shutil.copy("/usr/bin/tesseract", target_path)
+        except shutil.SameFileError:
+            print("'tesseract' already copied.")
+        self.run(
+            r"ldd /usr/bin/tesseract | grep '=> /' | awk '{print $3}' | "
+            "xargs -I '{}' cp -v '{}' " + f"{(lib_cache_path).resolve()}/"
+        )
+        print(f"Copying tesseract dependencies to {target_path.resolve()}...")
+        for pattern in ("liblept*", "libtesseract*"):
+            dependency = list(lib_cache_path.glob(pattern))[0]
+            print(f"{dependency.resolve()}")
+            shutil.copy(dependency, target_path)
+
+    def install_system_deps(self):  # noqa: D102
+        if system_requires := self.get_system_requires():
+            github_actions_uid = 1001
+            if os.getuid() == github_actions_uid:  # type: ignore
+                self.run(cmd="sudo apt update")
+                self.run(cmd=f"sudo apt install {' '.join(system_requires)}")
+
+    def run_framework(self):  # noqa: D102
+        self.run(cmd="briefcase create --no-input", cwd=self.PROJECT_PATH)
+        self.run(cmd="briefcase build", cwd=self.PROJECT_PATH)
+        self.add_metainfo_to_appimage()
+        self.run(cmd="briefcase package", cwd=self.PROJECT_PATH)
+
+    def rename_package_file(self):  # noqa: D102
+        source = list(Path(self.PROJECT_PATH / "linux").glob("*.AppImage"))[0]
+        target = (
+            self.BUILD_PATH
+            / f"NormCap-{self.get_version()}-x86_64{self.binary_suffix}.AppImage"
+        )
+        target.unlink(missing_ok=True)
+        shutil.move(source, target)
+
+    def add_metainfo_to_appimage(self):
+        """Copy metainfo file with info for appimage hub."""
+        metainfo = self.BUILD_PATH / "metainfo"
+        target_path = (
+            self.PROJECT_PATH
+            / "linux"
+            / "appimage"
+            / "NormCap"
+            / "NormCap.AppDir"
+            / "usr"
+            / "share"
+        )
+        shutil.copy(metainfo, target_path / "metainfo")
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.install_system_deps()
+        # self.bundle_tesseract()
+
+        self.patch_briefcase_appimage_to_prune_deps()
+        self.patch_briefcase_appimage_to_include_tesseract()
+        self.patch_briefcase_create_to_adjust_dockerfile()
+
+        self.run_framework()
+        self.rename_package_file()
diff --git a/package/platforms/linux_nuitka.py b/package/platforms/linux_nuitka.py
new file mode 100644
index 00000000..8b31f214
--- /dev/null
+++ b/package/platforms/linux_nuitka.py
@@ -0,0 +1,74 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import os
+import shutil
+
+from platforms.utils import BuilderBase
+
+
+class LinuxNuitka(BuilderBase):
+    """Create prebuild package for Linux using Nuitka."""
+
+    binary_suffix = "_EXPERIMENTAL"
+
+    def bundle_tesseract(self):  # noqa: D102
+        target_path = self.RESOURCE_PATH / "tesseract"
+        target_path.mkdir(exist_ok=True)
+        lib_cache_path = self.BUILD_PATH / ".cache"
+        lib_cache_path.mkdir(exist_ok=True)
+        try:
+            shutil.copy("/usr/bin/tesseract", target_path)
+        except shutil.SameFileError:
+            print("'tesseract' already copied.")
+        self.run(
+            r"ldd /usr/bin/tesseract | grep '=> /' | awk '{print $3}' | "
+            "xargs -I '{}' cp --verbose '{}' " + f"{(lib_cache_path).resolve()}/"
+        )
+
+        print(f"Copying tesseract dependencies to {target_path.resolve()}...")
+        # deps = ("liblept*", "libtesseract*", "libtiff*", "libjbig*", "*")
+        deps = ("*",)
+        for pattern in deps:
+            dependency = list(lib_cache_path.glob(pattern))[0]
+            print(f"{dependency.resolve()}")
+            shutil.copy(dependency, target_path)
+
+    def install_system_deps(self):  # noqa: D102
+        if system_requires := self.get_system_requires():
+            github_actions_uid = 1001
+            if os.getuid() == github_actions_uid:  # type: ignore
+                self.run(cmd="sudo apt update")
+                self.run(cmd=f"sudo apt install {' '.join(system_requires)}")
+
+    def run_framework(self):  # noqa: D102
+        TLS_PATH = (
+            self.VENV_PATH
+            / "lib"
+            / "python3.10"
+            / "site-packages"
+            / "PySide6"
+            / "Qt"
+            / "plugins"
+            / "tls"
+        )
+        self.run(
+            cmd=f"""python -m nuitka \
+                    --onefile \
+                    --assume-yes-for-downloads \
+                    --linux-onefile-icon={(self.IMG_PATH / "normcap.svg").resolve()} \
+                    --enable-plugin=pyside6 \
+                    --include-data-dir={(self.RESOURCE_PATH).resolve()}=normcap/resources \
+                    --include-data-dir={(TLS_PATH).resolve()}=PySide6/qt-plugins/tls \
+                    --include-data-files={(self.BUILD_PATH / "metainfo").resolve()}=usr/share/ \
+                    --include-data-files={(self.BUILD_PATH / ".cache").resolve()}/*.*=./ \
+                    -o NormCap-{self.get_version()}-x86_64{self.binary_suffix}.AppImage \
+                    {(self.PROJECT_PATH / "src"/ "normcap" / "app.py").resolve()}
+            """,
+            cwd=self.BUILD_PATH,
+        )
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.install_system_deps()
+        self.bundle_tesseract()
+        self.run_framework()
diff --git a/package/platforms/macos_briefcase.py b/package/platforms/macos_briefcase.py
new file mode 100644
index 00000000..cd51911e
--- /dev/null
+++ b/package/platforms/macos_briefcase.py
@@ -0,0 +1,94 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import shutil
+from pathlib import Path
+
+from platforms.utils import BRIEFCASE_EXCLUDES, BuilderBase, rm_recursive
+
+
+class MacBriefcase(BuilderBase):
+    """Create prebuild package for MacOS using Briefcase."""
+
+    binary_suffix = ""
+
+    def run_framework(self):  # noqa: D102
+        app_dir = (
+            self.PROJECT_PATH
+            / "macOS"
+            / "app"
+            / "NormCap"
+            / "NormCap.app"
+            / "Contents"
+            / "Resources"
+            / "app_packages"
+        )
+        self.run(cmd="briefcase create", cwd=self.PROJECT_PATH)
+
+        rm_recursive(directory=app_dir, exclude=BRIEFCASE_EXCLUDES["app_packages"])
+        rm_recursive(
+            directory=app_dir / "PySide6", exclude=BRIEFCASE_EXCLUDES["pyside6"]
+        )
+        self.bundle_tesseract()
+
+        self.run(cmd="briefcase build", cwd=self.PROJECT_PATH)
+        # TODO: Re-enable if we have a solution for unfocusing on MacOS
+        # patch_info_plist_for_proper_fullscreen()
+        self.run(cmd="briefcase package macos app --no-sign", cwd=self.PROJECT_PATH)
+
+    def bundle_tesseract(self):  # noqa: D102
+        print("Bundling tesseract libs...")
+        app_pkg_path = (
+            self.PROJECT_PATH
+            / "macOS/app/NormCap/NormCap.app/Contents/Resources/app_packages"
+        )
+        tesseract_source = Path("/usr/local/bin/tesseract")
+        tesseract_target = app_pkg_path / "tesseract"
+        install_path = "@executable_path/"
+        self.run(
+            cmd="dylibbundler "
+            + f"--fix-file {tesseract_source.resolve()} "
+            + f"--dest-dir {app_pkg_path.resolve()} "
+            + f"--install-path {install_path} "
+            + "--bundle-deps "
+            + "--overwrite-files",
+            cwd=self.BUILD_PATH,
+        )
+        shutil.copy(tesseract_source, tesseract_target)
+
+    def patch_info_plist_for_proper_fullscreen(self):
+        """Set attribute to keep dock and menubar hidden in fullscreen.
+
+        See details:
+        https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/20001431-113616
+        """
+        file_path = Path("macOS/app/NormCap/NormCap.app/Contents") / "Info.plist"
+        patch = """
+    <key>LSUIPresentationMode</key>
+    <integer>3</integer>
+"""
+        insert_after = "<string>normcap</string>"
+        self.patch_file(
+            file_path=file_path,
+            insert_after=insert_after,
+            patch=patch,
+            mark_patched=False,
+        )
+
+    def install_system_deps(self):  # noqa: D102
+        self.run(cmd="brew install tesseract")
+        self.run(cmd="brew install dylibbundler")
+
+    def rename_package_file(self):  # noqa: D102
+        source = list(Path(self.PROJECT_PATH / "macOS").glob("*.dmg"))[0]
+        target = (
+            self.BUILD_PATH
+            / f"NormCap-{self.get_version()}-MacOS{self.binary_suffix}.dmg"
+        )
+        target.unlink(missing_ok=True)
+        shutil.move(source, target)
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.install_system_deps()
+        self.run_framework()
+        self.rename_package_file()
diff --git a/package/platforms/macos_nuitka.py b/package/platforms/macos_nuitka.py
new file mode 100644
index 00000000..90d19118
--- /dev/null
+++ b/package/platforms/macos_nuitka.py
@@ -0,0 +1,122 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import os
+import shutil
+
+from platforms.utils import BuilderBase
+
+
+class MacNuitka(BuilderBase):
+    """Create prebuild package for MacOS using Nuitka."""
+
+    binary_suffix = "_EXPERIMENTAL"
+
+    def run_framework(self):  # noqa: D102
+        print(f"{'='*40}\nRun framework\n{'='*40}")
+
+        self.run(
+            cmd=f"""python -m nuitka \
+                    --standalone \
+                    --onefile \
+                    --assume-yes-for-downloads \
+                    --macos-target-arch=x86_64 \
+                    --macos-create-app-bundle \
+                    --macos-disable-console \
+                    --macos-app-icon={(self.IMG_PATH / "normcap.icns").resolve()} \
+                    --macos-signed-app-name=eu.dynobo.normcap \
+                    --macos-app-name=NormCap \
+                    --macos-app-version={self.get_version()} \
+                    --enable-plugin=pyside6 \
+                    --include-data-dir={(self.RESOURCE_PATH).resolve()}=resources\
+                    --include-data-dir={(self.BUILD_PATH / ".cache").resolve()}=PySide6/qt-plugins/tls \
+                    {(self.PROJECT_PATH / "src"/ "normcap" / "app.py").resolve()}
+                """,
+            cwd=self.BUILD_PATH,
+        )
+        old_app_path = self.BUILD_PATH / "app.app"
+        new_app_path = self.BUILD_PATH / "NormCap.app"
+        shutil.rmtree(new_app_path, ignore_errors=True)
+        os.rename(old_app_path, new_app_path)
+        os.rename(
+            new_app_path / "Contents" / "MacOS" / "app",
+            new_app_path / "Contents" / "MacOS" / "NormCap",
+        )
+        shutil.make_archive(
+            base_name=self.BUILD_PATH
+            / f"NormCap-{self.get_version()}-MacOS{self.binary_suffix}",
+            format="zip",
+            root_dir=self.BUILD_PATH,
+            base_dir="NormCap.app",
+        )
+
+    def bundle_tesseract(self):  # noqa: D102
+        print(f"{'='*40}\nBundle tesseract\n{'='*40}")
+        tesseract_source = "/usr/local/bin/tesseract"
+        install_path = "@executable_path/"
+        self.run(
+            cmd="dylibbundler "
+            + f"--fix-file {tesseract_source} "
+            + f"--dest-dir {self.TESSERACT_PATH.resolve()} "
+            + f"--install-path {install_path} "
+            + "--bundle-deps "
+            + "--overwrite-files",
+            cwd=self.BUILD_PATH,
+        )
+        shutil.copy(tesseract_source, self.TESSERACT_PATH)
+
+    def bundle_tls(self):  # noqa: D102
+        print(f"{'='*40}\nBundle TLS\n{'='*40}")
+        cache_path = self.BUILD_PATH / ".cache"
+        cache_path.mkdir(exist_ok=True)
+        shutil.rmtree(cache_path)
+        TLS_PATH = (
+            self.VENV_PATH
+            / "lib"
+            / "python3.10"
+            / "site-packages"
+            / "PySide6"
+            / "Qt"
+            / "plugins"
+            / "tls"
+        )
+        shutil.copytree(TLS_PATH, cache_path)
+        dylibs = [
+            "libqcertonlybackend.dylib",
+            "libqopensslbackend.dylib",
+            "libqsecuretransportbackend.dylib",
+        ]
+        for dylib in dylibs:
+            self.run(
+                cmd="install_name_tool -change "
+                + "'@rpath/QtNetwork.framework/Versions/A/QtNetwork' '@executable_path/QtNetwork' "
+                + f"{(cache_path / dylib).resolve()}",
+                cwd=cache_path,
+            )
+            self.run(
+                cmd="install_name_tool -change "
+                + "'@rpath/QtCore.framework/Versions/A/QtCore' '@executable_path/QtCore' "
+                + f"{(cache_path / dylib).resolve()}",
+                cwd=cache_path,
+            )
+
+    def install_system_deps(self):  # noqa: D102
+        print(f"{'='*40}\nInstall system deps\n{'='*40}")
+        self.run(cmd="brew install tesseract")
+        self.run(cmd="brew install dylibbundler")
+
+    def reinstall_pillow_without_binary(self):  # noqa: D102
+        output = self.run(cmd="poetry run pip show pillow | grep Version")
+        version = output.decode("utf-8").split(":")[1].strip()
+        self.run(cmd="pip uninstall pillow -y", cwd=self.PROJECT_PATH)
+        self.run(
+            cmd=f"pip install --no-binary=pillow pillow=={version}",
+            cwd=self.PROJECT_PATH,
+        )
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.install_system_deps()
+        self.bundle_tesseract()
+        self.bundle_tls()
+        self.reinstall_pillow_without_binary()
+        self.run_framework()
diff --git a/package/platforms/utils.py b/package/platforms/utils.py
new file mode 100644
index 00000000..4ac3a56b
--- /dev/null
+++ b/package/platforms/utils.py
@@ -0,0 +1,271 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import fileinput
+import hashlib
+import os
+import re
+import shutil
+import subprocess
+import sys
+import urllib.request
+import zipfile
+from abc import ABC, abstractmethod
+from pathlib import Path
+from typing import Union
+
+import toml
+
+BRIEFCASE_EXCLUDES = dict(
+    pyside6=[
+        "3danimation",
+        "3dcore",
+        "3dextras",
+        "3drender",
+        "assistant",
+        "audio",
+        "bluetooth",
+        "canbus",
+        "charts",
+        "datavisualization",
+        "designer",
+        "examples",
+        "gamepad",
+        "geoservices",
+        "help",
+        "icudtl",
+        "labs",
+        "libexec",
+        "linguist",
+        "location",
+        "lupdate",
+        "mediaservice",
+        "multimedia",
+        "nfc",
+        "openglfunct",
+        "pdf",
+        "purchasing",
+        "qt63d",
+        "qt6quick",
+        "qt6shadertools",
+        "qtopengl",
+        "qtquick",
+        "rcc",
+        "remoteobjects",
+        "scene",
+        "sensor",
+        "serialport",
+        "sql",
+        "test",
+        "texttospeech",
+        "uic",
+        "uitools",
+        "virtualkeyboard",
+        "webchannel",
+        "webengine",
+        "websockets",
+        "webview",
+    ],
+    app_packages=[
+        "/tests/",
+        "docs",
+    ],
+    lib=["qt6"],
+)
+
+
+def rm_recursive(directory, exclude):
+    """Remove excluded files from package."""
+    for package_path in directory.glob(r"**/*"):
+        path_str = str(package_path.absolute()).lower()
+        if any(e in path_str for e in exclude):
+            if not package_path.exists():
+                continue
+            print(f"Removing: {package_path.absolute()}")
+            if package_path.is_dir():
+                shutil.rmtree(package_path)
+            if package_path.is_file():
+                os.remove(package_path)
+
+
+class BuilderBase(ABC):
+    """Creates a prebuild package."""
+
+    PROJECT_PATH = Path(__file__).absolute().parent.parent.parent
+    BUILD_PATH = (PROJECT_PATH / "package").resolve()
+    IMG_PATH = BUILD_PATH / "imgs"
+    RESOURCE_PATH = PROJECT_PATH / "src" / "normcap" / "resources"
+    TESSERACT_PATH = RESOURCE_PATH / "tesseract"
+    PYPROJECT_PATH = PROJECT_PATH / "pyproject.toml"
+    VENV_PATH = Path(os.environ["VIRTUAL_ENV"])
+    binary_suffix = "_legacy"
+
+    @abstractmethod
+    def run_framework(self):
+        """Run nuitka compiler and rename resulting package."""
+
+    @abstractmethod
+    def bundle_tesseract(self):
+        """Include tesseract binary and its dependencies."""
+
+    @abstractmethod
+    def install_system_deps(self):
+        """Install system dependencies required for building."""
+
+    @abstractmethod
+    def create(self):
+        """Run all steps to build prebuild packages."""
+
+    def get_system_requires(self) -> list[str]:
+        """Get versions string from pyproject.toml."""
+        with open(self.PYPROJECT_PATH, encoding="utf8") as toml_file:
+            pyproject_toml = toml.load(toml_file)
+        return pyproject_toml["tool"]["briefcase"]["app"]["normcap"][sys.platform][
+            "system_requires"
+        ]
+
+    def get_version(self) -> str:
+        """Get versions string from pyproject.toml."""
+        if "--dev" in sys.argv:
+            return "0.0.1"
+
+        with open(self.PYPROJECT_PATH, encoding="utf8") as toml_file:
+            pyproject_toml = toml.load(toml_file)
+        return pyproject_toml["tool"]["poetry"]["version"]
+
+    @staticmethod
+    def run(cmd: Union[str, list], cwd=None):
+        """Executes a shell command and raises in case of error."""
+        if not isinstance(cmd, str):
+            cmd = " ".join(cmd)
+
+        cmd_str = re.sub(r"\s+", " ", cmd)
+        print(f">>> {cmd_str}")
+
+        completed_proc = subprocess.run(  # pylint: disable=subprocess-run-check
+            cmd, shell=True, cwd=cwd, capture_output=True
+        )
+        try:
+            print(completed_proc.stdout.decode(sys.__stdout__.encoding))
+            print(completed_proc.stderr.decode(sys.__stdout__.encoding))
+        except UnicodeDecodeError as e:
+            print(e)
+            print(completed_proc.stdout)
+            print(completed_proc.stderr)
+
+        if completed_proc.returncode != 0:
+            raise subprocess.CalledProcessError(
+                returncode=completed_proc.returncode,
+                cmd=cmd,
+                output=completed_proc.stdout,
+                stderr=completed_proc.stderr,
+            )
+
+        return completed_proc.stdout
+
+    def download_tessdata(self):
+        """Download trained data for tesseract to include in packages."""
+        print("Downloading tessdata...")
+        tessdata_path = self.RESOURCE_PATH / "tessdata"
+        url_prefix = (
+            "https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/4.1.0"
+        )
+        files = [
+            "ara.traineddata",
+            "chi_sim.traineddata",
+            "deu.traineddata",
+            "rus.traineddata",
+            "spa.traineddata",
+            "eng.traineddata",
+        ]
+
+        if len(list(tessdata_path.glob("*.traineddata"))) >= len(files):
+            print("Language data already present. Skipping download.")
+            return
+
+        print("Downloading language data...")
+        for file_name in files:
+            url = f"{url_prefix}/{file_name}"
+            urllib.request.urlretrieve(f"{url}", tessdata_path / file_name)
+            print(f"Downloaded {url} to {(tessdata_path / file_name).absolute()}")
+
+        print("Download done.")
+
+    @staticmethod
+    def patch_file(
+        file_path: Path, insert_after: str, patch: str, mark_patched: bool = True
+    ):
+        """Insert lines in file, if not already done.
+
+        Indents the patch like the line after which it is inserted.
+        """
+        patch_applied = False
+        patch_hash = hashlib.md5(patch.encode()).hexdigest()
+
+        with open(file_path, "r", encoding="utf8") as f:
+            if f.read().find(patch_hash) > -1:
+                print("Skipping patch. Already applied.")
+                return
+
+        print(f"Patching file {file_path.resolve()}")
+        if mark_patched:
+            patch = (
+                f"# dynobo: {patch_hash} >>>>>>>>>>>>>>"
+                + patch
+                + f"# dynobo: {patch_hash} <<<<<<<<<<<<<<\n"
+            )
+        for line in fileinput.FileInput(file_path, inplace=True):
+            if insert_after in line:
+                pad = len(line) - len(line.lstrip(" "))
+                patch = patch.replace("\n", f"\n{pad * ' '}")
+                line = line.replace(line, line + pad * " " + patch + "\n")
+                patch_applied = True
+            print(line, end="")
+
+        if not patch_applied:
+            raise RuntimeError(
+                f"Couldn't apply patch to file {file_path}! "
+                + f"Line '{insert_after}' not found!"
+            )
+
+
+def bundle_tesseract_windows(builder: BuilderBase):
+    """Download tesseract binaries including dependencies into resource path."""
+    # Link to download artifact might change
+
+    # https://ci.appveyor.com/project/zdenop/tesseract/build/artifacts
+    zip_path = builder.BUILD_PATH / "tesseract.zip"
+
+    if zip_path.exists():
+        print("Tesseract.exe already present. Skipping download.")
+        return
+
+    url = (
+        "https://ci.appveyor.com/api/projects/zdenop/tesseract/artifacts/tesseract.zip"
+    )
+    urllib.request.urlretrieve(f"{url}", zip_path)
+
+    if not zip_path.exists():
+        raise FileNotFoundError("Downloading of tesseract.zip might have failed!")
+
+    with zipfile.ZipFile(zip_path) as artifact_zip:
+        members = [
+            m
+            for m in artifact_zip.namelist()
+            if ".test." not in m and ".training." not in m
+        ]
+        subdir = members[0].split("/")[0]
+        artifact_zip.extractall(path=builder.RESOURCE_PATH, members=members)  #
+    zip_path.unlink()
+    print("Tesseract binaries downloaded.")
+
+    for each_file in Path(builder.RESOURCE_PATH / subdir).glob("*.*"):
+        (builder.TESSERACT_PATH / each_file.name).unlink(missing_ok=True)
+        each_file.rename(builder.TESSERACT_PATH / each_file.name)
+
+    (builder.TESSERACT_PATH / "tesseract.exe").unlink(missing_ok=True)
+    (builder.TESSERACT_PATH / "google.tesseract.tesseract-main.exe").rename(
+        builder.TESSERACT_PATH / "tesseract.exe"
+    )
+
+    shutil.rmtree(builder.RESOURCE_PATH / subdir)
+    print("Binaries moved. Tesseract.exe renamed.")
diff --git a/package/platforms/windows_briefcase.py b/package/platforms/windows_briefcase.py
new file mode 100644
index 00000000..3bd868ec
--- /dev/null
+++ b/package/platforms/windows_briefcase.py
@@ -0,0 +1,126 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import shutil
+import urllib
+import xml.etree.ElementTree as ET
+import zipfile
+from pathlib import Path
+
+from platforms.utils import (
+    BRIEFCASE_EXCLUDES,
+    BuilderBase,
+    bundle_tesseract_windows,
+    rm_recursive,
+)
+
+
+class WindowsBriefcase(BuilderBase):
+    """Create prebuild package for Windows using Nuitka."""
+
+    binary_suffix = ""
+
+    def bundle_tesseract(self):
+        """Download tesseract binaries including dependencies into resource path."""
+        bundle_tesseract_windows(self)
+
+    def download_openssl(self):
+        """Download openssl needed for QNetwork https connections."""
+        target_path = self.PROJECT_PATH / "src" / "normcap" / "resources" / "openssl"
+        target_path.mkdir(exist_ok=True)
+        zip_path = self.BUILD_PATH / "openssl.zip"
+        urllib.request.urlretrieve(
+            "http://wiki.overbyte.eu/arch/openssl-1.1.1q-win64.zip", zip_path
+        )
+        with zipfile.ZipFile(zip_path, "r") as zip_ref:
+            zip_ref.extractall(target_path)
+
+        zip_path.unlink()
+        print("Openssl extracted")
+
+    def patch_windows_installer(self):
+        """Customize wix-installer.
+
+        Currently only branding is added.
+        """
+        # pylint: disable=too-many-locals
+        print("Preparing installer...")
+
+        wxs_file = self.PROJECT_PATH / "windows" / "msi" / "NormCap" / "normcap.wxs"
+
+        # Cache header for inserting later
+        with open(wxs_file, encoding="utf-8") as f:
+            header_lines = f.readlines()[:3]
+
+        ns = "{http://schemas.microsoft.com/wix/2006/wi}"
+        ET.register_namespace("", ns[1:-1])
+
+        tree = ET.parse(wxs_file)
+        root = tree.getroot()
+        product = root.find(f"{ns}Product")
+
+        # Copy installer images
+        left = "normcap_install_bg.bmp"
+        top = "normcap_install_top.bmp"
+        for image in [left, top]:
+            original = self.IMG_PATH / image
+            target = self.PROJECT_PATH / "windows" / "msi" / "NormCap" / image
+            shutil.copy(original, target)
+
+        # Set installer images
+        ET.SubElement(
+            product, "WixVariable", {"Id": "WixUIDialogBmp", "Value": f"{left}"}
+        )
+        ET.SubElement(
+            product, "WixVariable", {"Id": "WixUIBannerBmp", "Value": f"{top}"}
+        )
+
+        # Allow upgrades
+        major_upgrade = ET.SubElement(product, "MajorUpgrade")
+        major_upgrade.set("DowngradeErrorMessage", "Can't downgrade. Uninstall first.")
+
+        sequence = product.find(f"{ns}InstallExecuteSequence")
+        product.remove(sequence)
+
+        upgrade = product.find(f"{ns}Upgrade")
+        product.remove(upgrade)
+
+        # Write & fix header
+        tree.write(wxs_file, encoding="utf-8", xml_declaration=False)
+        with open(wxs_file, "r+", encoding="utf-8") as f:
+            lines = f.readlines()
+            f.seek(0)
+            f.writelines(header_lines + lines)
+
+        print("Installer prepared.")
+
+    def rename_package_file(self):  # noqa: D102
+        source = list(Path(self.PROJECT_PATH / "windows").glob("*.msi"))[0]
+        target = (
+            self.BUILD_PATH
+            / f"NormCap-{self.get_version()}-Windows{self.binary_suffix}.msi"
+        )
+        target.unlink(missing_ok=True)
+        shutil.move(source, target)
+
+    def run_framework(self):  # noqa: D102
+        app_dir = (
+            self.PROJECT_PATH / "windows" / "msi" / "NormCap" / "src" / "app_packages"
+        )
+        self.run(cmd="briefcase create", cwd=self.PROJECT_PATH)
+        rm_recursive(directory=app_dir, exclude=BRIEFCASE_EXCLUDES["app_packages"])
+        rm_recursive(
+            directory=app_dir / "PySide6", exclude=BRIEFCASE_EXCLUDES["pyside6"]
+        )
+        self.run(cmd="briefcase build", cwd=self.PROJECT_PATH)
+        self.patch_windows_installer()
+        self.run(cmd="briefcase package", cwd=self.PROJECT_PATH)
+
+    def install_system_deps(self):  # noqa: D102
+        pass
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.download_openssl()
+        self.bundle_tesseract()
+        self.run_framework()
+        self.rename_package_file()
diff --git a/package/platforms/windows_nuitka.py b/package/platforms/windows_nuitka.py
new file mode 100644
index 00000000..2ad7d713
--- /dev/null
+++ b/package/platforms/windows_nuitka.py
@@ -0,0 +1,128 @@
+"""Adjustments executed while packaging with briefcase during CI/CD."""
+
+import shutil
+import urllib
+import zipfile
+
+from platforms.utils import BuilderBase, bundle_tesseract_windows
+
+
+class WindowsNuitka(BuilderBase):
+    """Create prebuild package for Windows using Nuitka."""
+
+    binary_suffix = "_EXPERIMENTAL"
+
+    def bundle_tesseract(self):
+        """Download tesseract binaries including dependencies into resource path."""
+        bundle_tesseract_windows(self)
+
+    def download_wix(self):  # noqa: D102
+        wix_path = self.BUILD_PATH / "wix"
+        wix_path.mkdir(exist_ok=True)
+        wix_zip = wix_path / "wix-binaries.zip"
+
+        print("Downloading wix toolkit...")
+        url = "https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip"
+        urllib.request.urlretrieve(f"{url}", wix_zip)
+
+        print(f"Downloaded {url} to {wix_zip.absolute()}")
+        with zipfile.ZipFile(wix_zip, "r") as zip_ref:
+            zip_ref.extractall(wix_path)
+
+        wix_zip.unlink()
+
+    def build_installer(self):  # noqa: D102
+        print("Copying wxs configuration file to app.dist folder...")
+        wxs = self.BUILD_PATH / "normcap.wxs"
+        shutil.copy(wxs, self.BUILD_PATH / "app.dist")
+
+        print("Copying images to app.dist folder...")
+        shutil.copy(
+            self.IMG_PATH / "normcap_install_bg.bmp", self.BUILD_PATH / "app.dist"
+        )
+        shutil.copy(
+            self.IMG_PATH / "normcap_install_top.bmp", self.BUILD_PATH / "app.dist"
+        )
+        shutil.copy(self.IMG_PATH / "normcap.ico", self.BUILD_PATH / "app.dist")
+
+        print("Compiling application manifest...")
+        wix_path = self.BUILD_PATH / "wix"
+        self.run(
+            cmd=f"""{(wix_path / "heat.exe").resolve()} \
+                dir \
+                app.dist \
+                -nologo \
+                -gg \
+                -sfrag \
+                -sreg \
+                -srd \
+                -scom \
+                -dr normcap_ROOTDIR \
+                -cg normcap_COMPONENTS \
+                -var var.SourceDir \
+                -out {(self.BUILD_PATH / "app.dist" / "normcap-manifest.wxs").resolve()}
+            """,
+            cwd=self.BUILD_PATH,
+        )
+        print("Compiling installer...")
+        self.run(
+            cmd=f"""{(wix_path / "candle.exe").resolve()} \
+                -nologo \
+                -ext WixUtilExtension \
+                -ext WixUIExtension \
+                -dSourceDir=. \
+                normcap.wxs \
+                normcap-manifest.wxs
+            """,
+            cwd=self.BUILD_PATH / "app.dist",
+        )
+        print("Linking installer...")
+        self.run(
+            cmd=f"""{(wix_path / "light.exe").resolve()} \
+                -nologo \
+                -ext WixUtilExtension \
+                -ext WixUIExtension \
+                -o {(self.BUILD_PATH / f"NormCap-{self.get_version()}-Windows{self.binary_suffix}.msi").resolve()} \
+                normcap.wixobj \
+                normcap-manifest.wixobj
+            """,
+            cwd=self.BUILD_PATH / "app.dist",
+        )
+
+    def run_framework(self):  # noqa: D102
+        TLS_PATH = (
+            self.VENV_PATH / "lib" / "site-packages" / "PySide6" / "plugins" / "tls"
+        )
+
+        self.run(
+            cmd=f"""python -m nuitka \
+                    --standalone \
+                    --assume-yes-for-downloads \
+                    --windows-company-name=dynobo \
+                    --windows-product-name=NormCap \
+                    --windows-file-description="OCR powered screen-capture tool to capture information instead of images." \
+                    --windows-product-version={self.get_version()} \
+                    --windows-icon-from-ico={(self.IMG_PATH / "normcap.ico").resolve()} \
+                    --windows-disable-console \
+                    --windows-force-stdout-spec=%PROGRAM%.log \
+                    --windows-force-stderr-spec=%PROGRAM%.log \
+                    --enable-plugin=pyside6 \
+                    --include-data-dir={(self.RESOURCE_PATH).resolve()}=normcap/resources \
+                    --include-data-dir={(TLS_PATH).resolve()}=PySide6/qt-plugins/tls \
+                    {(self.PROJECT_PATH / "src"/ "normcap" / "app.py").resolve()}
+                """,
+            cwd=self.BUILD_PATH,
+        )
+        normcap_exe = self.BUILD_PATH / "app.dist" / "NormCap.exe"
+        normcap_exe.unlink(missing_ok=True)
+        (self.BUILD_PATH / "app.dist" / "app.exe").rename(normcap_exe)
+
+    def install_system_deps(self):  # noqa: D102
+        pass
+
+    def create(self):  # noqa: D102
+        self.download_tessdata()
+        self.bundle_tesseract()
+        self.run_framework()
+        self.download_wix()
+        self.build_installer()
diff --git a/poetry.lock b/poetry.lock
index 8194d43b..a5aa588e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -11,7 +11,7 @@ python-dateutil = ">=2.7.0"
 
 [[package]]
 name = "astroid"
-version = "2.11.5"
+version = "2.11.7"
 description = "An abstract syntax tree for Python with inference support."
 category = "dev"
 optional = false
@@ -24,7 +24,7 @@ wrapt = ">=1.11,<2"
 
 [[package]]
 name = "atomicwrites"
-version = "1.4.0"
+version = "1.4.1"
 description = "Atomic file writes."
 category = "dev"
 optional = false
@@ -76,7 +76,7 @@ chardet = ">=3.0.2"
 
 [[package]]
 name = "black"
-version = "22.3.0"
+version = "22.6.0"
 description = "The uncompromising code formatter."
 category = "dev"
 optional = false
@@ -87,7 +87,7 @@ click = ">=8.0.0"
 mypy-extensions = ">=0.4.3"
 pathspec = ">=0.9.0"
 platformdirs = ">=2"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
 typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
 
 [package.extras]
@@ -98,7 +98,7 @@ uvloop = ["uvloop (>=0.15.2)"]
 
 [[package]]
 name = "briefcase"
-version = "0.3.7"
+version = "0.3.8"
 description = "Tools to support converting a Python project into a standalone native application."
 category = "dev"
 optional = false
@@ -108,12 +108,14 @@ python-versions = ">=3.7"
 cookiecutter = ">=1.0"
 dmgbuild = {version = ">=1.3.3", markers = "sys_platform == \"darwin\""}
 GitPython = ">=3.0.8"
+psutil = ">=5.9.0"
 requests = ">=2.22.0"
+rich = ">=12.4.1"
 tomli = {version = ">=2.0.0", markers = "python_version <= \"3.10\""}
 
 [[package]]
 name = "certifi"
-version = "2022.5.18.1"
+version = "2022.6.15"
 description = "Python package for providing Mozilla's CA Bundle."
 category = "dev"
 optional = false
@@ -129,19 +131,19 @@ python-versions = ">=3.6.1"
 
 [[package]]
 name = "chardet"
-version = "4.0.0"
-description = "Universal encoding detector for Python 2 and 3"
+version = "5.0.0"
+description = "Universal encoding detector for Python 3"
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "charset-normalizer"
-version = "2.0.12"
+version = "2.1.0"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 category = "dev"
 optional = false
-python-versions = ">=3.5.0"
+python-versions = ">=3.6.0"
 
 [package.extras]
 unicode_backport = ["unicodedata2"]
@@ -172,12 +174,23 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
 
 [[package]]
 name = "colorama"
-version = "0.4.4"
+version = "0.4.5"
 description = "Cross-platform colored terminal text."
 category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
+[[package]]
+name = "commonmark"
+version = "0.9.1"
+description = "Python parser for the CommonMark Markdown spec"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[package.extras]
+test = ["hypothesis (==3.55.3)", "flake8 (==3.7.8)"]
+
 [[package]]
 name = "contextlib2"
 version = "21.6.0"
@@ -205,7 +218,7 @@ requests = ">=2.23.0"
 
 [[package]]
 name = "coverage"
-version = "6.4.1"
+version = "6.4.2"
 description = "Code coverage measurement for Python"
 category = "dev"
 optional = false
@@ -246,7 +259,7 @@ graph = ["objgraph (>=1.7.2)"]
 
 [[package]]
 name = "distlib"
-version = "0.3.4"
+version = "0.3.5"
 description = "Distribution utilities"
 category = "dev"
 optional = false
@@ -343,7 +356,7 @@ gitdb = ">=4.0.1,<5"
 
 [[package]]
 name = "identify"
-version = "2.5.1"
+version = "2.5.2"
 description = "File identification library for Python"
 category = "dev"
 optional = false
@@ -362,7 +375,7 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "importlib-metadata"
-version = "4.11.4"
+version = "4.12.0"
 description = "Read metadata from Python packages"
 category = "dev"
 optional = false
@@ -374,7 +387,7 @@ zipp = ">=0.5"
 [package.extras]
 docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
 perf = ["ipython"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
+testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
 
 [[package]]
 name = "iniconfig"
@@ -400,7 +413,7 @@ plugins = ["setuptools"]
 
 [[package]]
 name = "jarowinkler"
-version = "1.0.2"
+version = "1.2.0"
 description = "library for fast approximate string matching using Jaro and Jaro-Winkler similarity"
 category = "dev"
 optional = false
@@ -415,8 +428,8 @@ optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"]
-trio = ["trio", "async-generator"]
+trio = ["async-generator", "trio"]
+test = ["async-timeout", "trio", "testpath", "pytest-asyncio (>=0.17)", "pytest-trio", "pytest"]
 
 [[package]]
 name = "jinja2"
@@ -454,14 +467,14 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "levenshtein"
-version = "0.18.1"
+version = "0.20.1"
 description = "Python extension for computing string edit distances and similarities."
 category = "dev"
 optional = false
 python-versions = ">=3.6"
 
 [package.dependencies]
-rapidfuzz = ">=2.0.1,<3.0.0"
+rapidfuzz = ">=2.3.0,<3.0.0"
 
 [[package]]
 name = "linkify-it-py"
@@ -475,10 +488,10 @@ python-versions = ">=3.6"
 uc-micro-py = "*"
 
 [package.extras]
-benchmark = ["pytest", "pytest-benchmark"]
-dev = ["pre-commit", "isort", "flake8", "black"]
-doc = ["sphinx", "sphinx-book-theme", "myst-parser"]
-test = ["coverage", "pytest", "pytest-cov"]
+test = ["pytest-cov", "pytest", "coverage"]
+doc = ["myst-parser", "sphinx-book-theme", "sphinx"]
+dev = ["black", "flake8", "isort", "pre-commit"]
+benchmark = ["pytest-benchmark", "pytest"]
 
 [[package]]
 name = "mac-alias"
@@ -579,7 +592,7 @@ python-versions = ">=3.6.1"
 mdformat = ">=0.7.5,<0.8.0"
 
 [package.extras]
-test = ["pytest (>=6.0,<7.0)", "coverage", "pytest-cov"]
+test = ["pytest-cov", "coverage", "pytest (>=6.0,<7.0)"]
 
 [[package]]
 name = "mdit-py-plugins"
@@ -593,9 +606,9 @@ python-versions = "~=3.6"
 markdown-it-py = ">=1.0.0,<3.0.0"
 
 [package.extras]
+testing = ["pytest-regressions", "pytest-cov", "pytest (>=3.6,<4)", "coverage"]
+rtd = ["sphinx-book-theme (>=0.1.0,<0.2.0)", "myst-parser (>=0.14.0,<0.15.0)"]
 code_style = ["pre-commit (==2.6)"]
-rtd = ["myst-parser (>=0.14.0,<0.15.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"]
-testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"]
 
 [[package]]
 name = "mdurl"
@@ -607,7 +620,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "mypy"
-version = "0.960"
+version = "0.971"
 description = "Optional static typing for Python"
 category = "dev"
 optional = false
@@ -633,10 +646,18 @@ python-versions = "*"
 
 [[package]]
 name = "nodeenv"
-version = "1.6.0"
+version = "1.7.0"
 description = "Node.js virtual environment builder"
 category = "dev"
 optional = false
+python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
+
+[[package]]
+name = "nuitka"
+version = "0.9.6"
+description = "Python compiler with full language support and CPython compatibility"
+category = "dev"
+optional = false
 python-versions = "*"
 
 [[package]]
@@ -676,14 +697,14 @@ python-versions = ">=2.6"
 
 [[package]]
 name = "pillow"
-version = "9.1.1"
+version = "9.2.0"
 description = "Python Imaging Library (Fork)"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"]
 tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
 
 [[package]]
@@ -707,12 +728,12 @@ optional = false
 python-versions = ">=3.6"
 
 [package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
+testing = ["pytest-benchmark", "pytest"]
+dev = ["tox", "pre-commit"]
 
 [[package]]
 name = "pre-commit"
-version = "2.19.0"
+version = "2.20.0"
 description = "A framework for managing and maintaining multi-language pre-commit hooks."
 category = "dev"
 optional = false
@@ -726,6 +747,17 @@ pyyaml = ">=5.1"
 toml = "*"
 virtualenv = ">=20.0.8"
 
+[[package]]
+name = "psutil"
+version = "5.9.1"
+description = "Cross-platform lib for process and system monitoring in Python."
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[package.extras]
+test = ["ipaddress", "mock", "enum34", "pywin32", "wmi"]
+
 [[package]]
 name = "py"
 version = "1.11.0"
@@ -736,7 +768,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "pydeps"
-version = "1.10.18"
+version = "1.10.22"
 description = "Display module dependencies"
 category = "dev"
 optional = false
@@ -759,17 +791,25 @@ snowballstemmer = "*"
 [package.extras]
 toml = ["toml"]
 
+[[package]]
+name = "pygments"
+version = "2.12.0"
+description = "Pygments is a syntax highlighting package written in Python."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+
 [[package]]
 name = "pylint"
-version = "2.14.0"
+version = "2.14.5"
 description = "python code static checker"
 category = "dev"
 optional = false
 python-versions = ">=3.7.2"
 
 [package.dependencies]
-astroid = ">=2.11.5,<=2.12.0-dev0"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
+astroid = ">=2.11.6,<=2.12.0-dev0"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
 dill = ">=0.2"
 isort = ">=4.2.5,<6"
 mccabe = ">=0.6,<0.8"
@@ -807,14 +847,14 @@ diagrams = ["railroad-diagrams", "jinja2"]
 
 [[package]]
 name = "pyside6-essentials"
-version = "6.3.0"
+version = "6.3.1"
 description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)"
 category = "main"
 optional = false
 python-versions = "<3.11,>=3.6"
 
 [package.dependencies]
-shiboken6 = "6.3.0"
+shiboken6 = "6.3.1"
 
 [[package]]
 name = "pytesseract"
@@ -862,15 +902,15 @@ coverage = {version = ">=5.2.1", extras = ["toml"]}
 pytest = ">=4.6"
 
 [package.extras]
-testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"]
+testing = ["virtualenv", "pytest-xdist", "six", "process-tests", "hunter", "fields"]
 
 [[package]]
 name = "pytest-qt"
-version = "4.0.2"
+version = "4.1.0"
 description = "pytest support for PyQt and PySide applications"
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
 
 [package.dependencies]
 pytest = ">=3.0.0"
@@ -916,6 +956,24 @@ text-unidecode = ">=1.3"
 [package.extras]
 unidecode = ["Unidecode (>=1.1.1)"]
 
+[[package]]
+name = "pytoolconfig"
+version = "1.2.1"
+description = "Python tool configuration"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+packaging = ">=21.3"
+tomli = {version = ">=2.0", markers = "python_version < \"3.11\""}
+
+[package.extras]
+validation = ["pydantic (>=1.7.4)"]
+global = ["appdirs (>=1.4.4)"]
+gen_docs = ["pytoolconfig", "sphinx-rtd-theme (>=1.0.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx (>=4.5.0)"]
+doc = ["sphinx (>=4.5.0)", "tabulate (>=0.8.9)"]
+
 [[package]]
 name = "pyvirtualdisplay"
 version = "3.0"
@@ -947,60 +1005,103 @@ mando = ">=0.6,<0.7"
 
 [[package]]
 name = "rapidfuzz"
-version = "2.0.11"
+version = "2.3.0"
 description = "rapid fuzzy string matching"
 category = "dev"
 optional = false
 python-versions = ">=3.6"
 
 [package.dependencies]
-jarowinkler = ">=1.0.2,<1.1.0"
+jarowinkler = ">=1.2.0,<2.0.0"
 
 [package.extras]
 full = ["numpy"]
 
 [[package]]
 name = "requests"
-version = "2.27.1"
+version = "2.28.1"
 description = "Python HTTP for Humans."
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
+python-versions = ">=3.7, <4"
 
 [package.dependencies]
 certifi = ">=2017.4.17"
-charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
-idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
+charset-normalizer = ">=2,<3"
+idna = ">=2.5,<4"
 urllib3 = ">=1.21.1,<1.27"
 
 [package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
-use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "rich"
+version = "12.5.1"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+category = "dev"
+optional = false
+python-versions = ">=3.6.3,<4.0.0"
+
+[package.dependencies]
+commonmark = ">=0.9.0,<0.10.0"
+pygments = ">=2.6.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
 
 [[package]]
 name = "rope"
-version = "1.1.1"
+version = "1.2.0"
 description = "a python refactoring library..."
 category = "dev"
 optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+pytoolconfig = ">=1.1.2"
+
+[package.extras]
+doc = ["sphinx-rtd-theme (>=1.0.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx (>=4.5.0)", "pytoolconfig"]
+dev = ["build (>=0.7.0)", "pytest-timeout (>=2.1.0)", "pytest (>=7.0.1)"]
+
+[[package]]
+name = "ruamel.yaml"
+version = "0.17.21"
+description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
+category = "dev"
+optional = false
 python-versions = ">=3"
 
+[package.dependencies]
+"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""}
+
 [package.extras]
-dev = ["build", "pytest", "pytest-timeout"]
+docs = ["ryd"]
+jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
 
 [[package]]
-name = "safety"
-version = "1.10.3"
-description = "Checks installed dependencies for known vulnerabilities."
+name = "ruamel.yaml.clib"
+version = "0.2.6"
+description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
 category = "dev"
 optional = false
 python-versions = ">=3.5"
 
+[[package]]
+name = "safety"
+version = "2.1.1"
+description = "Checks installed dependencies for known vulnerabilities and licenses."
+category = "dev"
+optional = false
+python-versions = "*"
+
 [package.dependencies]
-Click = ">=6.0"
+Click = ">=8.0.2"
 dparse = ">=0.5.1"
-packaging = "*"
+packaging = ">=21.0"
 requests = "*"
+"ruamel.yaml" = ">=0.17.21"
 
 [[package]]
 name = "schema"
@@ -1015,7 +1116,7 @@ contextlib2 = ">=0.5.5"
 
 [[package]]
 name = "shiboken6"
-version = "6.3.0"
+version = "6.3.1"
 description = "Python/C++ bindings helper module"
 category = "main"
 optional = false
@@ -1058,22 +1159,22 @@ develop = ["sphinx"]
 
 [[package]]
 name = "stevedore"
-version = "3.5.0"
+version = "4.0.0"
 description = "Manage dynamic plugins for Python applications"
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
 
 [package.dependencies]
 pbr = ">=2.0.0,<2.1.0 || >2.1.0"
 
 [[package]]
 name = "tabulate"
-version = "0.8.9"
+version = "0.8.10"
 description = "Pretty-print tabular data"
 category = "dev"
 optional = false
-python-versions = "*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [package.extras]
 widechars = ["wcwidth"]
@@ -1118,7 +1219,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "tomlkit"
-version = "0.11.0"
+version = "0.11.1"
 description = "Style preserving TOML library"
 category = "dev"
 optional = false
@@ -1126,7 +1227,7 @@ python-versions = ">=3.6,<4.0"
 
 [[package]]
 name = "types-pillow"
-version = "9.0.19"
+version = "9.2.0"
 description = "Typing stubs for Pillow"
 category = "dev"
 optional = false
@@ -1134,7 +1235,7 @@ python-versions = "*"
 
 [[package]]
 name = "types-requests"
-version = "2.27.30"
+version = "2.28.5"
 description = "Typing stubs for requests"
 category = "dev"
 optional = false
@@ -1145,7 +1246,7 @@ types-urllib3 = "<1.27"
 
 [[package]]
 name = "types-toml"
-version = "0.10.7"
+version = "0.10.8"
 description = "Typing stubs for toml"
 category = "dev"
 optional = false
@@ -1153,7 +1254,7 @@ python-versions = "*"
 
 [[package]]
 name = "types-urllib3"
-version = "1.26.15"
+version = "1.26.17"
 description = "Typing stubs for urllib3"
 category = "dev"
 optional = false
@@ -1161,7 +1262,7 @@ python-versions = "*"
 
 [[package]]
 name = "typing-extensions"
-version = "4.2.0"
+version = "4.3.0"
 description = "Backported and Experimental Type Hints for Python 3.7+"
 category = "dev"
 optional = false
@@ -1176,7 +1277,7 @@ optional = false
 python-versions = ">=3.6"
 
 [package.extras]
-test = ["coverage", "pytest", "pytest-cov"]
+test = ["pytest-cov", "pytest", "coverage"]
 
 [[package]]
 name = "unidecode"
@@ -1188,11 +1289,11 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "urllib3"
-version = "1.26.9"
+version = "1.26.11"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
 
 [package.extras]
 brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
@@ -1201,25 +1302,24 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [[package]]
 name = "virtualenv"
-version = "20.14.1"
+version = "20.16.1"
 description = "Virtual Python Environment builder"
 category = "dev"
 optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+python-versions = ">=3.6"
 
 [package.dependencies]
 distlib = ">=0.3.1,<1"
 filelock = ">=3.2,<4"
 platformdirs = ">=2,<3"
-six = ">=1.9.0,<2"
 
 [package.extras]
 docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"]
-testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"]
+testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "packaging (>=20.0)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)"]
 
 [[package]]
 name = "viztracer"
-version = "0.15.2"
+version = "0.15.3"
 description = "A debugging and profiling tool that can trace and visualize python code execution"
 category = "dev"
 optional = true
@@ -1233,7 +1333,7 @@ full = ["rich", "orjson"]
 
 [[package]]
 name = "vulture"
-version = "2.4"
+version = "2.5"
 description = "Find dead code"
 category = "dev"
 optional = true
@@ -1252,15 +1352,15 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 
 [[package]]
 name = "zipp"
-version = "3.8.0"
+version = "3.8.1"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
+docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
+testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
 
 [extras]
 analysis = []
@@ -1268,7 +1368,7 @@ analysis = []
 [metadata]
 lock-version = "1.1"
 python-versions = ">=3.9,<3.11"
-content-hash = "8b39649e7f5af09493d0f21019181ead7b52d117ef2f747e00b9e997f449eb5d"
+content-hash = "d19f343eb2e0fb306deed31ca1689fb1274b286cd495e1da2f2eabf4fb76a4ec"
 
 [metadata.files]
 arrow = [
@@ -1276,12 +1376,11 @@ arrow = [
     {file = "arrow-1.2.2.tar.gz", hash = "sha256:05caf1fd3d9a11a1135b2b6f09887421153b94558e5ef4d090b567b47173ac2b"},
 ]
 astroid = [
-    {file = "astroid-2.11.5-py3-none-any.whl", hash = "sha256:14ffbb4f6aa2cf474a0834014005487f7ecd8924996083ab411e7fa0b508ce0b"},
-    {file = "astroid-2.11.5.tar.gz", hash = "sha256:f4e4ec5294c4b07ac38bab9ca5ddd3914d4bf46f9006eb5c0ae755755061044e"},
+    {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"},
+    {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"},
 ]
 atomicwrites = [
-    {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
-    {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
+    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
 ]
 attrs = [
     {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
@@ -1296,49 +1395,49 @@ binaryornot = [
     {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
 ]
 black = [
-    {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
-    {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
-    {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
-    {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
-    {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
-    {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
-    {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
-    {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
-    {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
-    {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
-    {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
-    {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
-    {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
-    {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
-    {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
-    {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
-    {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
-    {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
-    {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
-    {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
-    {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
-    {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
-    {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
+    {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"},
+    {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"},
+    {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"},
+    {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"},
+    {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"},
+    {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"},
+    {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"},
+    {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"},
+    {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"},
+    {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"},
+    {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"},
+    {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"},
+    {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"},
+    {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"},
+    {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"},
+    {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"},
+    {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"},
+    {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"},
+    {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"},
+    {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"},
+    {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"},
+    {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"},
+    {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"},
 ]
 briefcase = [
-    {file = "briefcase-0.3.7-py2.py3-none-any.whl", hash = "sha256:f2e5f34063c36a3a8b699cef68fb8771b4dac9c36d03a1843582902f9fe10ad8"},
-    {file = "briefcase-0.3.7.tar.gz", hash = "sha256:6302adfa71f1bdef45e15a2436995b251feca1638c371bbb8171727e357056d0"},
+    {file = "briefcase-0.3.8-py2.py3-none-any.whl", hash = "sha256:a7f907ea47a08f324b038298a30d72834defeaf945acdd1ce3535abd561b78f8"},
+    {file = "briefcase-0.3.8.tar.gz", hash = "sha256:31a1e07449b569d15dfe558e790dd3d6ac3fa19a87d7274f8bac14e8455761ce"},
 ]
 certifi = [
-    {file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"},
-    {file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"},
+    {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
+    {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
 ]
 cfgv = [
     {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
     {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
 ]
 chardet = [
-    {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
-    {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
+    {file = "chardet-5.0.0-py3-none-any.whl", hash = "sha256:d3e64f022d254183001eccc5db4040520c0f23b1a3f33d6413e099eb7f126557"},
+    {file = "chardet-5.0.0.tar.gz", hash = "sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa"},
 ]
 charset-normalizer = [
-    {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
-    {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
+    {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"},
+    {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"},
 ]
 cli-ui = [
     {file = "cli-ui-0.17.0.tar.gz", hash = "sha256:19a35b658bd19a1278dcb75330b28505a18753507fbbbe82cde59c7514e7cdee"},
@@ -1349,8 +1448,12 @@ click = [
     {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
 ]
 colorama = [
-    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
-    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
+    {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
+    {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
+]
+commonmark = [
+    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
+    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
 ]
 contextlib2 = [
     {file = "contextlib2-21.6.0-py2.py3-none-any.whl", hash = "sha256:3fbdb64466afd23abaf6c977627b75b6139a5a3e8ce38405c5b413aed7a0471f"},
@@ -1361,47 +1464,47 @@ cookiecutter = [
     {file = "cookiecutter-2.1.1.tar.gz", hash = "sha256:f3982be8d9c53dac1261864013fdec7f83afd2e42ede6f6dd069c5e149c540d5"},
 ]
 coverage = [
-    {file = "coverage-6.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b"},
-    {file = "coverage-6.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4"},
-    {file = "coverage-6.4.1-cp310-cp310-win32.whl", hash = "sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df"},
-    {file = "coverage-6.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6"},
-    {file = "coverage-6.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6"},
-    {file = "coverage-6.4.1-cp37-cp37m-win32.whl", hash = "sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e"},
-    {file = "coverage-6.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28"},
-    {file = "coverage-6.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54"},
-    {file = "coverage-6.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83"},
-    {file = "coverage-6.4.1-cp38-cp38-win32.whl", hash = "sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b"},
-    {file = "coverage-6.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c"},
-    {file = "coverage-6.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df"},
-    {file = "coverage-6.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264"},
-    {file = "coverage-6.4.1-cp39-cp39-win32.whl", hash = "sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9"},
-    {file = "coverage-6.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397"},
-    {file = "coverage-6.4.1-pp36.pp37.pp38-none-any.whl", hash = "sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815"},
-    {file = "coverage-6.4.1.tar.gz", hash = "sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c"},
+    {file = "coverage-6.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a9032f9b7d38bdf882ac9f66ebde3afb8145f0d4c24b2e600bc4c6304aafb87e"},
+    {file = "coverage-6.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e0524adb49c716ca763dbc1d27bedce36b14f33e6b8af6dba56886476b42957c"},
+    {file = "coverage-6.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4548be38a1c810d79e097a38107b6bf2ff42151900e47d49635be69943763d8"},
+    {file = "coverage-6.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f23876b018dfa5d3e98e96f5644b109090f16a4acb22064e0f06933663005d39"},
+    {file = "coverage-6.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fe75dcfcb889b6800f072f2af5a331342d63d0c1b3d2bf0f7b4f6c353e8c9c0"},
+    {file = "coverage-6.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2f8553878a24b00d5ab04b7a92a2af50409247ca5c4b7a2bf4eabe94ed20d3ee"},
+    {file = "coverage-6.4.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d774d9e97007b018a651eadc1b3970ed20237395527e22cbeb743d8e73e0563d"},
+    {file = "coverage-6.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d56f105592188ce7a797b2bd94b4a8cb2e36d5d9b0d8a1d2060ff2a71e6b9bbc"},
+    {file = "coverage-6.4.2-cp310-cp310-win32.whl", hash = "sha256:d230d333b0be8042ac34808ad722eabba30036232e7a6fb3e317c49f61c93386"},
+    {file = "coverage-6.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:5ef42e1db047ca42827a85e34abe973971c635f83aed49611b7f3ab49d0130f0"},
+    {file = "coverage-6.4.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:25b7ec944f114f70803d6529394b64f8749e93cbfac0fe6c5ea1b7e6c14e8a46"},
+    {file = "coverage-6.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bb00521ab4f99fdce2d5c05a91bddc0280f0afaee0e0a00425e28e209d4af07"},
+    {file = "coverage-6.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dff52b3e7f76ada36f82124703f4953186d9029d00d6287f17c68a75e2e6039"},
+    {file = "coverage-6.4.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:147605e1702d996279bb3cc3b164f408698850011210d133a2cb96a73a2f7996"},
+    {file = "coverage-6.4.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:422fa44070b42fef9fb8dabd5af03861708cdd6deb69463adc2130b7bf81332f"},
+    {file = "coverage-6.4.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8af6c26ba8df6338e57bedbf916d76bdae6308e57fc8f14397f03b5da8622b4e"},
+    {file = "coverage-6.4.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5336e0352c0b12c7e72727d50ff02557005f79a0b8dcad9219c7c4940a930083"},
+    {file = "coverage-6.4.2-cp37-cp37m-win32.whl", hash = "sha256:0f211df2cba951ffcae210ee00e54921ab42e2b64e0bf2c0befc977377fb09b7"},
+    {file = "coverage-6.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a13772c19619118903d65a91f1d5fea84be494d12fd406d06c849b00d31bf120"},
+    {file = "coverage-6.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f7bd0ffbcd03dc39490a1f40b2669cc414fae0c4e16b77bb26806a4d0b7d1452"},
+    {file = "coverage-6.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0895ea6e6f7f9939166cc835df8fa4599e2d9b759b02d1521b574e13b859ac32"},
+    {file = "coverage-6.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e7ced84a11c10160c0697a6cc0b214a5d7ab21dfec1cd46e89fbf77cc66fae"},
+    {file = "coverage-6.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80db4a47a199c4563d4a25919ff29c97c87569130375beca3483b41ad5f698e8"},
+    {file = "coverage-6.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3def6791adf580d66f025223078dc84c64696a26f174131059ce8e91452584e1"},
+    {file = "coverage-6.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f89d8e03c8a3757aae65570d14033e8edf192ee9298303db15955cadcff0c63"},
+    {file = "coverage-6.4.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6d0b48aff8e9720bdec315d67723f0babd936a7211dc5df453ddf76f89c59933"},
+    {file = "coverage-6.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2b20286c2b726f94e766e86a3fddb7b7e37af5d0c635bdfa7e4399bc523563de"},
+    {file = "coverage-6.4.2-cp38-cp38-win32.whl", hash = "sha256:d714af0bdba67739598849c9f18efdcc5a0412f4993914a0ec5ce0f1e864d783"},
+    {file = "coverage-6.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:5f65e5d3ff2d895dab76b1faca4586b970a99b5d4b24e9aafffc0ce94a6022d6"},
+    {file = "coverage-6.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a697977157adc052284a7160569b36a8bbec09db3c3220642e6323b47cec090f"},
+    {file = "coverage-6.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c77943ef768276b61c96a3eb854eba55633c7a3fddf0a79f82805f232326d33f"},
+    {file = "coverage-6.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54d8d0e073a7f238f0666d3c7c0d37469b2aa43311e4024c925ee14f5d5a1cbe"},
+    {file = "coverage-6.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f22325010d8824594820d6ce84fa830838f581a7fd86a9235f0d2ed6deb61e29"},
+    {file = "coverage-6.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b04d305ea172ccb21bee5bacd559383cba2c6fcdef85b7701cf2de4188aa55"},
+    {file = "coverage-6.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:866ebf42b4c5dbafd64455b0a1cd5aa7b4837a894809413b930026c91e18090b"},
+    {file = "coverage-6.4.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e36750fbbc422c1c46c9d13b937ab437138b998fe74a635ec88989afb57a3978"},
+    {file = "coverage-6.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:79419370d6a637cb18553ecb25228893966bd7935a9120fa454e7076f13b627c"},
+    {file = "coverage-6.4.2-cp39-cp39-win32.whl", hash = "sha256:b5e28db9199dd3833cc8a07fa6cf429a01227b5d429facb56eccd765050c26cd"},
+    {file = "coverage-6.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:edfdabe7aa4f97ed2b9dd5dde52d2bb29cb466993bb9d612ddd10d0085a683cf"},
+    {file = "coverage-6.4.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:e2618cb2cf5a7cc8d698306e42ebcacd02fb7ef8cfc18485c59394152c70be97"},
+    {file = "coverage-6.4.2.tar.gz", hash = "sha256:6c3ccfe89c36f3e5b9837b9ee507472310164f352c9fe332120b764c9d60adbe"},
 ]
 coveralls = [
     {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"},
@@ -1412,8 +1515,8 @@ dill = [
     {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"},
 ]
 distlib = [
-    {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
-    {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"},
+    {file = "distlib-0.3.5-py2.py3-none-any.whl", hash = "sha256:b710088c59f06338ca514800ad795a132da19fda270e3ce4affc74abf955a26c"},
+    {file = "distlib-0.3.5.tar.gz", hash = "sha256:a7f75737c70be3b25e2bee06288cec4e4c221de18455b2dd037fe2a795cab2fe"},
 ]
 dmgbuild = [
     {file = "dmgbuild-1.5.2.tar.gz", hash = "sha256:65bfb7c267cb9475cb52a32c04779e1cec12dfb9bcb7d02cf2b6bee5faf088f4"},
@@ -1444,16 +1547,16 @@ gitpython = [
     {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"},
 ]
 identify = [
-    {file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"},
-    {file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"},
+    {file = "identify-2.5.2-py2.py3-none-any.whl", hash = "sha256:feaa9db2dc0ce333b453ce171c0cf1247bbfde2c55fc6bb785022d411a1b78b5"},
+    {file = "identify-2.5.2.tar.gz", hash = "sha256:a3d4c096b384d50d5e6dc5bc8b9bc44f1f61cefebd750a7b3e9f939b53fb214d"},
 ]
 idna = [
     {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
     {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
 ]
 importlib-metadata = [
-    {file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
-    {file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
+    {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"},
+    {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"},
 ]
 iniconfig = [
     {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
@@ -1464,86 +1567,90 @@ isort = [
     {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
 ]
 jarowinkler = [
-    {file = "jarowinkler-1.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:71772fcd787e0286b779de0f1bef1e0a25deb4578328c0fc633bc345f13ffd20"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:912ee0a465822a8d659413cebc1ab9937ac5850c9cd1e80be478ba209e7c8095"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0320f7187dced1ad413bf2c3631ec47567e65dfdea92c523aafb2c085ae15035"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58bc6a8f01b0dfdf3721f9a4954060addeccf8bbe5e72a71cf23a88ce0d30440"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:679ec7a42f70baa61f3a214d1b59cec90fc036021c759722075efcc8697e7b1f"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dde57d47962d6a4436d8a3b477bcc8233c6da28e675027eb3a490b0d6dc325be"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:657f50204970fac8f120c293e52a3451b742c9b26125010405ec7365cb6e2a49"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04f18a7398766b36ffbe4bcd26d34fcd6ed01f4f2f7eea13e316e6cca0e10c98"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33a24b380e2c076eabf2d3e12eee56b6bf10b1f326444e18c36a495387dbf0de"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e1d7d6e6c98fb785026584373240cc4076ad21033f508973faae05e846206e8c"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e50c750a45c800d91134200d8cbf746258ed357a663e97cc0348ee42a948386a"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:5b380afce6cdc25a4dafd86874f07a393800577c05335c6ad67ccda41db95c60"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e73712747ac5d2218af3ed3c1600377f18a0a45af95f22c39576165aea2908b4"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-win32.whl", hash = "sha256:9511f4e1f00c822e08dbffeb69e15c75eb294a5f24729815a97807ecf03d22eb"},
-    {file = "jarowinkler-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a5c44f92e9ac6088286292ecb69e970adc2b98e139b8923bce9bbb9d484e6a0f"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:02b0bf34ffc2995b695d9b10d2f18c1c447fbbdb7c913a84a0a48c186ccca3b8"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df7a8e45176298a1210c06f8b2328030cc3c93a45dab068ac1fbc9cf075cd95b"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da27a9c206249a50701bfa5cfbbb3a04236e1145b2b0967e825438acb14269bf"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43ea0155379df92021af0f4a32253be3953dfa0f050ec3515f314b8f48a96674"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f33b6b1687db1be1abba60850628ee71547501592fcf3504e021274bc5ccb7a"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff304de32ee6acd5387103a0ad584060d8d419aa19cbbeca95204de9c4f01171"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:662dd6f59cca536640be0cda32c901989504d95316b192e6aa41d098fa08c795"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:01f85abb75fa43e98db34853d35570d98495ee2fcbbf45a93838e0289c162f19"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5b9332dcc8130af4101c9752a03e977c54b8c12982a2a3ca4c2e4cc542accc00"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:af765b037404a536c372e33ddd4c430aea28f1d82a8ef51a2955442b8b690577"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aea2c7d66b57c56d00f9c45ae7862d86e3ae84368ecea17f3552c0052a7f3bcf"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-win32.whl", hash = "sha256:8b1288a09a8d100e9bf7cf9ce1329433db73a0d0350d74c2c6f5c31ac69096cf"},
-    {file = "jarowinkler-1.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:ed39199b0e806902347473c65e5c05933549cf7e55ba628c6812782f2c310b19"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:473b057d7e5a0f5e5b8c0e0f7960d3ca2f2954c3c93fd7a9fb2cc4bc3cc940fb"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb892dbbbd77b3789a10b2ce5e8acfe5821cc6423e835bae2b489159f3c2211"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:012a8333328ce061cba1ff081843c8d80eb1afe8fa2889ad29d767ea3fdc7562"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3421120c07ee6d3f59c5adde32eb9a050cfd1b3666b0e2d8c337d934a9d091f9"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dad57327cc90f8daa3afb98e2d274d7dd1b60651f32717449be95d3b3366d61a"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4fd1757eff43df97227fd63d9c8078582267a0b25cefef6f6a64d3e46e80ba2"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:32269ebbcb860f01c055d9bb145b4cc91990f62c7644a85b21458b4868621113"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3b5a0839e84f5ff914b01b5b94d0273954affce9cc2b2ee2c31fe2fcb9c8ae76"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:6c9d3a9ef008428b5dce2855eebe2b6127ea7a7e433aedf240653fad4bd4baa6"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:a3d7759d8a66ee05595bde012f93da8a63499f38205e2bb47022c52bd6c47108"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2ba1b1b0bf45042a9bbb95d272fd8b0c559fe8f6806f088ec0372899e1bc6224"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-win32.whl", hash = "sha256:4cb33f4343774d69abf8cf65ad57919e7a171c44ba6ad57b08147c3f0f06b073"},
-    {file = "jarowinkler-1.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0392b72ddb5ab5d6c1d5df94dbdac7bf229670e5e64b2b9a382d02d6158755e5"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:94f663ad85bc7a89d7e8b6048f93a46d2848a0570ab07fc895a239b9a5d97b93"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:895a10766ff3db15e7cf2b735e4277bee051eaafb437aaaef2c5de64a5c3f05c"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0c1a84e770b3ec7385a4f40efb30bdc96f96844564f91f8d3937d54a8969d82c"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27defe81d76e02b3929322baea999f5232837e7f308c2dc5b37de7568c2bc583"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:158f117481388f8d23fe4bd2567f37be0ccae0f4631c34e4b0345803147da207"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:427c675b4f3e83c79a4b6af7441f29e30a173c7a0ae72a54f51090eee7a8ae02"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90a7f3fd173339bc62e52c02f43d50c947cb3af9cda41646e218aea13547e0c2"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3975cbe8b6ae13fc63d74bcbed8dac1577078d8cd8728e60621fe75885d2a8c5"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:141840f33345b00abd611839080edc99d4d31abd2dcf701a3e50c90f9bfb2383"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f592f9f6179e347a5f518ca7feb9bf3ac068f2fad60ece5a0eef5e5e580d4c8b"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:30565d70396eb9d1eb622e1e707ddc2f3b7a9692558b8bf4ea49415a5ca2f854"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:35fc430c11b80a43ed826879c78c4197ec665d5150745b3668bec961acf8a757"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf4b7090f0c4075bec1638717f54b22c3b0fe733dc87146a19574346ed3161"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-win32.whl", hash = "sha256:199f4f7edbc49439a97440caa1e244d2e33da3e16d7b0afce4e4dfd307e555c7"},
-    {file = "jarowinkler-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:b587e8fdd96cc470d6bdf428129c65264731b09b5db442e2d092e983feec4aab"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4b233180b3e2f2d7967aa570d36984e9d2ec5a9067c0d1c44cd3b805d9da9363"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2220665a1f52262ae8b76e3baf474ebcd209bfcb6a7cada346ffd62818f5aa3e"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08c98387e04e749c84cc967db628e5047843f19f87bf515a35b72f7050bc28ad"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d710921657442ad3c942de684aba0bdf16b7de5feed3223b12f3b2517cf17f7c"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:401c02ac7245103826f54c816324274f53d50b638ab0f8b359a13055a7a6e793"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a1929a0029f208cc9244499dc93b4d52ee8e80d2849177d425cf6e0be1ea781"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ab25d147be9b04e7de2d28a18e72fadc152698c3e51683c6c61f73ffbae2f9e"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:465cfdff355ec9c55f65fd1e1315260ec20c8cff0eb90d9f1a0ad8d503dc002b"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:29ef1113697cc74c2f04bc15008abbd726cb2d5b01c040ba87c6cb7abd1d0e0d"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:61b57c8b36361ec889f99f761441bb0fa21b850a5eb3305dea25fef68f6a797b"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ee9d9af1bbf194d78f4b69c2139807c23451068b27a053a1400d683d6f36c61d"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a9b33b0ceb472bbc65683467189bd032c162256b2a137586ee3448a9f8f886ec"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:582f6e213a6744883ced44482a51efcc21ae632defac27f12f6430a8e99b1070"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-win32.whl", hash = "sha256:4d1c8f403016d5c0262de7a8588eee370c37a609e1f529f8407e99a70d020af7"},
-    {file = "jarowinkler-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:ab50ffa66aa201616871c1b90ac0790f56666118db3c8a8fcb3a7a6e03971510"},
-    {file = "jarowinkler-1.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8e59a289dcf93504ab92795666c39b2dbe98ac18655201992a7e6247de676bf4"},
-    {file = "jarowinkler-1.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c36eccdc866f06a7b35da701bd8f91e0dfc83b35c07aba75ce8c906cbafaf184"},
-    {file = "jarowinkler-1.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123163f01a5c43f12e4294e7ce567607d859e1446b1a43bd6cd404b3403ffa07"},
-    {file = "jarowinkler-1.0.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41fdecd907189e47c7d478e558ad417da38bf3eb34cc20527035cb3fca3e2b8"},
-    {file = "jarowinkler-1.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7829368fc91de225f37f6325f8d8ec7ad831dc5b0e9547f1977e2fdc85eccc1"},
-    {file = "jarowinkler-1.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278595417974553a8fdf3c8cce5c2b4f859335344075b870ecb55cc416eb76cf"},
-    {file = "jarowinkler-1.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:208fc49741db5d3e6bbd4a2f7b32d32644b462bf205e7510eca4e2d530225f03"},
-    {file = "jarowinkler-1.0.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:924afcab6739c453f1c3492701d185d71dc0e5ba15692bd0bfa6d482c7e8f79e"},
-    {file = "jarowinkler-1.0.2.tar.gz", hash = "sha256:788ac33e6ffdbd78fd913b481e37cfa149288575f087a1aae1a4ce219cb1c654"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:072a30b179840ab783951bb6b667fc0e05330ee17081ed8c47febd000ee65826"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173a7eeec0a15710ad9b5e7c63b7d0569e8a6f19c8e2b5da24d887b86ab9b84f"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff8b400810c7439f3fe3649e09c7901e5cad1cb115141e30e2fc22f749054de4"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8be7251976221f91b61e2c3b405185374a4dd0c07e8a489773a6db2cc819c02"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65f3b980358ce6e210b280a91d5195e5e50f28d990bb752dcf10d2321a2b5686"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772646cbed2dc779868980c60b6183c81f6545528e98110adfb5c362146f7950"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa487efd80a590f774155750a4c38bbbb8775eb4a73bffe2db65dc9b5d2f5b7"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2026ca328bec047003ce6be878b80c7b302f9a5873fd451695921448c3af2eb8"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19f1c6383f4baee88ec98ff380249319ea4101e86086a82b61e5383a0ff12399"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fc9312565a9995ab870d77d8daececbcf121dedd33a144e2bb6ed784a23d710f"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a38d98b58a4322b44fd844e886b1cfc1d43bdd0b9209e3e6b41a96e93ebc3a88"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3a1a5abc4dba50a8a2e98ae35a8f44108d6f7beaba7ff51172e45645b3b63621"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ecf80ac7f7b9b8ff047b9db5564ecc314ac2e062c196b24868671d6704381853"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-win32.whl", hash = "sha256:2831ae4b065b71a7413153ea74e8d9287b00a1bace0fb7096206b7a1cee23541"},
+    {file = "jarowinkler-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:daea4481e676e20001d28265c59955540963f4a06198014d6aee9de825599bc7"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e5002d2b20f4c603e11ac1989c92470c86a5f74af373d17acb26df472a83baaf"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:116b7c5f03991fcddbfb2ba151a00fe0b1750c44bd766b512e31293a160e5edd"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6594ff438eef7465a34673ec9ea71f183321d173f8775ec56c2c8b9a69d01786"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:377065ceb7c23a239b83266cf0e1a0308caf1caaea915214383dfe7bf36a8b09"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb139159b37e2d74f0e00170c228c40549e0f7f24df2c06c1c75f81e9b97ed24"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d268782c386287f7ffddc988f14c973c0c12fe373df1466bc96fa067bf0cc4a7"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8c62e0bfc8763fffb33b988bfc2f17683ea7d3110ee6c749d221524f973b7f2f"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:a563d1aa47cd222f0eb4042d4b07b971c87eda247fe537a88f0e8ab02a42c7d7"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:c0878585233e9ebcee8ccb172cf302e409fdd07a40feb932260888297eb96294"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:37815d23f114da7a15dc46d5e74b9aab2a346f972185bb80c70ec1ac97d9b563"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2511ff5a87884d208841a18240dbb66456968455a792f027a2f566fc9a2192f4"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:b4d027abebd28f1051b9118ffc443ccac0183ed5121f5a5dc7ab751ca0423dff"},
+    {file = "jarowinkler-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:135c903adda1b9fe593e13c54c9a0e2d9d366c5668d361097432e2e93837c509"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:08b95989efb9f89b8b9aa5a2dcc41c180cb950e65c3199c2a8b333caec3c52b2"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e384a84a55c0eeadf7b448dbb8e89d6748eebb690c02c18cb34d33800379fbd8"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51e01a16b385f480da896fe4354b216ec2d34de039a9893ee7023e12c3c8a02f"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63d2c7248c94589bb2e6f3b197697350f6956465086f38c56574fbf7e67ef463"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91c01ec16dd162ab0ecf167336e041b6d00cb461cfc0fe6d1c408fdba74013da"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d71157d5b5d955cb29e754bf05c7953155c3e2a92587935bacfb1e89ab89873"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9895ec7857ab132857d259b7716894420bb153d5d4aee7af6807ceb42cd0b3e0"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f5295a0af62fc012e9211d79f393dc05dbed071962a05e1ed917af1d62f30916"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:678d6af42f8cf6d7067f591fac8657b9ddec53f0551afdef713c78cacbbc230c"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ce9f958d18eb9df9d2a29a20211f6b67a7daebcc15df2fa5a1642e08c1eeea14"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:90ba602a3976c3d65922f8ac89cba4eabc50ae5bf08c99ec142d16d2367cacc1"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:7677cc7796f9159bb5038204bddd29a694eb77f78a797d4a5dacfba2cbbb4879"},
+    {file = "jarowinkler-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5c73483e00953506472fcfc1ee602fc41b91a15b4b90d0853ff1484df3274696"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4ae845cedbeed0e32e5981cd07e9a0acceb0a1672f7ffe42dd3a94d79f91d7e2"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d57b9dfc9cb4e10e1ccf97b6eb74a95d7d7aa90bb8a28c8665ee10097210cc18"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b0309231c6f567ff07781ff2dd421c2b79b8bbd8ede6d468075e2624fc1e3e50"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bcc91cc0d77889388d7e28a82e2ba10730b8af5afefbb51761280493f13b421"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e757b89daa8709128b5d906abd58271042d0e75e06c8b38496e75f3d3512e63c"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:671be0c780d7ad054aead45bd8b3c1076a4b222f954e71933b671161e9e13940"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb5b7934eba8e7091f712c919a19bbfb11d9a6ac44264f2f96ec2dadb9e1a389"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:116a4b51603670d418d60de599d2677d534172a1865316080eb120ef44f27297"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d9f44eb1700feb0ab9d612622b7d674cceee64357226e748f4fc37a231d7bf5"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:454d790eb260c0ba9b9eb8675140754efa3ce1c2c445f2639543c0fab3b02005"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd986c9d43ccdf1a85454cd8f1a46e574cfff88d2aea89edac400d802028c75f"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3a38511b552e5508e1ff7b996ab143046dab2727ce9c370a5a23e8b739057364"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93303ecac07ef2a1dddbe98c991ae3c6f6eec9c005c9e5aba97c3d7f185e0e6f"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-win32.whl", hash = "sha256:d82df91795ad08858ec6cc3cde185565db68f46c47d43731bdbfc662b2a0a41c"},
+    {file = "jarowinkler-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:d5ee7ae2588400f70530d9c0cb0097df111cefb83e54b64674fa4350db2e814e"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:806fcb69b4978c4db39cfc39b459b109afb65653268e5eb48f489fdb81ffbefc"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:43567e403c4a478169cfb6be4d00ccc1055f6bc8ff115496cfa1b94e1ba2c1ae"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9ff8bb8e15bf583c5c7e22f7839341d87c41395cd211c1181bf552001f2a31f1"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2fd6629da5a285aad6e0178e2af155941e84fb388052e2605421acbe664ff9d"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b8754229b2957fb40b55c661a77ea2c107ca41d767c89564616a185c494531b"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617c29660e0c5a4be19fc637735211b4b44f01e34dd6ec58e2b322d5694b41bf"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b75b4284496e5192fa6eca6eb106fa7a6c4d519127f37751947de52702855c48"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7109ad809f9ae3e742865cada44b874d655deb00994d19814114bb8cde379620"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b6ab6330dad214f32dee7136e052412cef428535e9d69a79612bf7e83d1506c"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:56d5327f165156171de4391cd1d602a1b1315f79f466b6fc8a38342338101104"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:57ed9497cda6ce205053ea769765948d544ab7492a44febd082fead841d97cc0"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:018f7205b9c4f6a58272c2d89c0dae6c06cab390c905092026f88ea9cbc4c18b"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dcb76e132f3ee3fd8554e6639a5cc6c8e5bd2f2136d5660c2d2d38c77d0fbb0f"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-win32.whl", hash = "sha256:26608ea1df35a60f6431e61a1879c112fd55afc9a3f63ca0c40e7d2d527d89b2"},
+    {file = "jarowinkler-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:2eac93391cd444c1495f38daa605fd0163151c637ee44efa0cc78e32e56200a7"},
+    {file = "jarowinkler-1.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:815abc42f652e99e84bc31d3f0a61081734e3bc99d354824486f438e100c7726"},
+    {file = "jarowinkler-1.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56329b8c8599d497719c64b46eb027cb4aa89dc96f09c37bdb5c71fb1a9e426a"},
+    {file = "jarowinkler-1.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcf0fb54519adbacbd48b419f7ca318ed993260b4f7115e1fbc6ac76a7993be3"},
+    {file = "jarowinkler-1.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa5c1cde44b31baea6e408b76074b09e4ad53dac4b791144f79427ae4a5a919"},
+    {file = "jarowinkler-1.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:86fa003ff50d9485ba3a5b3fb03a4b3418fbfd27c3ee949b824e320bcf4ebfd7"},
+    {file = "jarowinkler-1.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c5c9532e438825baf7ae9747af1048a4a0fe34afed8ac5a6782899f17306d7"},
+    {file = "jarowinkler-1.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2daf51c6a2ec933c16d600c0584071d4c337f2fa97d60a731df32806afccdb"},
+    {file = "jarowinkler-1.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3469307b08cd3e91f561e6ccc7defbb1f2bea20d257c19a8dfa5d3e3e1bf4a9f"},
+    {file = "jarowinkler-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5d5eaeb3075c3762afba3a13e4d3482ac38e5159dbf44bb3ac77e6ac3adb3ca7"},
+    {file = "jarowinkler-1.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b42cdf4c8a7cbb4d190bccde9c8477a1766cf4703d6f27ec00d660cf64d601f8"},
+    {file = "jarowinkler-1.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd959378d71f7cb5f5f8d2525db6d7371aad77081a48fad9410c40724c39e4c8"},
+    {file = "jarowinkler-1.2.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b258b1537f89902cb77312f0c28edcd45cec6a64f357dc86ace526ce6b55431"},
+    {file = "jarowinkler-1.2.0.tar.gz", hash = "sha256:7118976b9c1dca4ad77c97a0595d3917cead5f9b2856b14948a3bcf5f2438c44"},
 ]
 jeepney = [
     {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"},
@@ -1597,59 +1704,87 @@ lazy-object-proxy = [
     {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"},
 ]
 levenshtein = [
-    {file = "Levenshtein-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdb13e975cc23d927fdef2edda6635b43e420abd351be049abd5049e9c678bda"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28b43dde3a0606b8834a807b035565bb7926a1461dccc8e47d303d24e94e3748"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:18f1976ed2e834bf77e4d4b18b0d403496c7b39573e027d774c2c5b2842a7732"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de8e832ef06ef180b7d1c1879141bd8cc1132e5402a0e3459576988628ac589"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd55fb26bb8252050e391db4f506f4fe57d537026191f8eda45c3f73e0d6c937"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17fc2fca012a5e3c0dae500f0c581bf78050189c4aa368153e715a08e0acf714"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91c9e7e4ad1c68e03df9a46a35c971f54afe9565d356d3d76502cfee111607f4"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35b19bd4f9e774f9405f99aff4b443af396f4b2ba7b26f75984a1adbca26339e"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-win32.whl", hash = "sha256:f0e9216b10981ce7357008b321b212349f15e60ad837af70df4718d59d306592"},
-    {file = "Levenshtein-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f56f92bc676a8722052773d25a2f8df79fc2b1adc213e34975598a1103fede1"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e4f137d27c6eec86483c6d2e872339d3ac77942947c2a94a141607e352e50961"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5870b203b06fd1e16ff3d923898b260f7af3827fc0b1f768ce40d0305cb68d5"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c4c116eeecce0e963518ee485510c21efe4d39e5ed180c2eb059fdaf31267c"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3df1ef5cade58dfb9fa0036ef36c8a66fce387a39466fe03c8bed5eb55f5eaa3"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e08fb872385f32190c7071a60526b02e1fc17c81ac4b62002ccd7f97536b110"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1313b17f28485cc8647bdfc2150f6993aaae562c971267c4ffa7d4e330f5145a"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-win32.whl", hash = "sha256:1d2b0852186cce6bf2495225c63bfaa6c93cdf3ae9af6bfb12b2641446a07713"},
-    {file = "Levenshtein-0.18.1-cp36-cp36m-win_amd64.whl", hash = "sha256:bd4ec38b41a78a7b5b0df91a80e9eff1a6bf45e13b1de19211d8404f693ad6f8"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76c04292b9f599bb7167dda11fbd9de95c5d7398dc7c1e0c8789685257bae0a6"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46413b0f6a921a985ce48126959eff3e0d2c8fbb4cba54447b20c3c482714509"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e669f603c38a98681572cb53e866d33db62b884a28ae348bebd234afa01a783c"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c24c2dc2bd9b77b2af3f93035a1b33323cbb76f880f72638c292d270464f6753"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa2cab500a976151b7f573e115c63d020cbd2c8f9d235fb7de84deff620e0375"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6d801202f496159864044ddbdd9d98af7ade702f602e90bb6e1477d8d711292"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:1ad95c0f2eb7610d8e301ff9f30a80f02f49587e7039c98edd910d47b72339b2"},
-    {file = "Levenshtein-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a6952a66b56e79b12c4915de19efea03e4dcda3d0ae63be6ebac697091440f2c"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:659da46f9e16ae7467b543f3a62598b2019757c9f25516186c1c37f5af2784d8"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:667220edab4d336a85b938dc4620424950a7f3e82f86e83132587cfd842458b8"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9e83b4df9b96507dc3d51ef80849c8fc9abffecb30760ae627d4839b26adb749"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:360a1c23a0e87cd34e9c9da3a9cd8bc5a3e179d12a094db5be395f986ecff9e5"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:009460c0c39032dbc6d0dbde0fb7bd04c03b606d90b5e3485a0d8e7a31787b52"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87aedc94bab1f9cff01d0b79bb05d714bbbb0d6540d9ad03e906f32e72db3d57"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ccd594bfcfa81e7de4370b4de3fd648098c6d51c6e4aaf3f362ad401efbf591"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11521080952625676b0b43b99a49e1e955ce2c5be43b148a7c838f3fc411eea"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-win32.whl", hash = "sha256:f1df012108880a962b44f714be0cecb1436db6fd21640888e8083a424fa2d32e"},
-    {file = "Levenshtein-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:38596b1ce50fbfe75f043e542557ba76a8112828f561e4c6e1e1a005552088f2"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7090a85521829e3e577963fed4413cb6cb0cf91b7d52dbd8efc21a65f57e7380"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8fc66a9e6d166edd1b98e0d4d1cf369bbb270fdc99d00ea0797386371aec9907"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3bc4d4cbb3cab23db38b10fdca00c61b50be253e26e962b1a4268c96743b3e17"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:931982c924d6893ee7d261e63fa3ac772c2c41264b2176f6e4aab812479dbba0"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdc76bbf7c0633270af4d380feadaed4d1f9ec1c851525c09717d152134d1f4e"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b07438451dd6c2b2884385ceebb1df1bb05cff4d424ccb9faae04c9d3813f625"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4a1097a7e88e74fc59561e36a8816b29dadce870821c358f2ff13ddbc74111e9"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddfdad88ae6539f22d1baeeea2c4137b7d4f2fad5a4cb4e81d9d15bf5ea02e01"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-win32.whl", hash = "sha256:58c7923781293b902ece8ff79365fa08cfd6a6578115fa47def4869aa000767d"},
-    {file = "Levenshtein-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:699ee235b5dce88105ea475ddf17a5b765ad3300c143fb850e6c99eb67637e9e"},
-    {file = "Levenshtein-0.18.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49f9bbab4417c3ed448e2a7a5f3c52a77e1658c64b0260f679fa47944da1a1e8"},
-    {file = "Levenshtein-0.18.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71dd80a5cc6d85dd478efc5c949ab40f550c29ff4cccebbc22a9ac76daa24ed1"},
-    {file = "Levenshtein-0.18.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a43074f525ed619be164bf734d4f478d3f168a2bb2466de426aa2d8ebedbda04"},
-    {file = "Levenshtein-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6b24c2ec34248c593a0d3e203565efc2991b678b6882bb3837cbd9e1e30859b"},
-    {file = "Levenshtein-0.18.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4e023d5bfacc11d62ad901bf6f02742112828eab120390ab3c1f86b4457b24f"},
-    {file = "Levenshtein-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfef7f2cb5406c57fcd764255476e6f073339c64eeed77b1642dc636a45af3e9"},
-    {file = "Levenshtein-0.18.1.tar.gz", hash = "sha256:c9bda0d6daaec0635f4562eec00e68f3d289557c4259e8c8277b6942108764e8"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1f806b7a6e4e46ed23bddf0aa29c94cf45ff9bc7b9d1148efa39d8def54563d5"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cff9f96efd5f01040621e0e3d63c13245042c8259215dad937dbdd060d1e6d11"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf06842e31f95da09069c595d8a2afb0ddf0f0874b18133d0d1069460ead0006"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68021de8117c0c7131a6a11d41809b0f2711a3cb07506adf6638b5e6f4a73393"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a7bc7a919bb1222f13e9420a6efba629731b67fa0eb6919ac4fb4f3a1573a5"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ac8e7a598a7477e50be71c40a76ae4037297b9135409fd707dbaf7aacf6b6889"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f524421ebb171d8d42a96eacb31cc456af9ccf25fc8edc7293e0adcaf970b274"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00226683d278b99f6a7ccf3c25dda994ecdbccfec403e151ee2df686ca73abb5"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1d7b22f0b989c7544554b205ed4531b126b57a8e16e5587173c198917fc767ab"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3487d33032faae581eba53925c6037194f3a0960cdf981ab7be1da440dfffec"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b00a1fb5946904dbdfdd021c2cae5d8e30b7ce5c0061cfef7c4d77e649aef0d0"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:10c7aac0d20552d75a8deb2aa754a8b90382ae4d656443e3bf225417248ddad0"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9f01a0dc94d5f98353e87d937e6ed4a14ad4bbf24c4cc649067b7132a499ad62"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-win32.whl", hash = "sha256:38a118cc87171cf7a2589c37c136c233d2b28f5262a7ebbaa6a9e6f62a4a9f35"},
+    {file = "Levenshtein-0.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:e6f8f322a94692386feae2e639c50cf182a0a62e0e5b081f7bec7637aa1edb24"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:138213eb57db8725b550d52f6f41188b84d76fac293db7cc2d795b00ba2d7b0c"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fc64cc225d050c67e4e022b87c6848dd4518b7bb2c27fc4ef9695ef65a7f79"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8fb0a90e2fba97f2da88c2e284e39d98b3a6ff57746e024fd1c34ed5a5e6bf6"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07180e4d8712fa57346d6bb533f0612758ed2244f9807aaca7918cb92d1bebf9"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbb392730838d84efaf20812ca1d9fa82a99d89576ef0710b9704535399cf832"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e1a0f5144aaa2fb65b8a2a74912bebd13918511931853dce02d5fa24501afc"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:80defb6b560cb3e952a4288b0a9c0f84071f5ecfc850a6ad87d02d69d764b461"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:9998a9aaadffa165f1bccf687990f36faf56c55037824638f6ade331f3566a79"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1111ba8af1f6b1825111e3683673504c7c3abd8787b6f195f50f0213ce88e5fb"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:10fdd4dbb77fbb82190e041791d74e94560c48efa9923857b855d9b132df283e"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8b9fe78bbc7bb2dbf36c4b13aeb99e630cee99e8761d6a0febd5b89a7af9a8c8"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-win32.whl", hash = "sha256:8456ed134aa127b99dbe8e94003f370a6bcd579b431a72031b5f35decc710138"},
+    {file = "Levenshtein-0.20.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6a3d2ead22c30298f08e38f799d47b215a8ea6c50285ea5f2bbdff15c2d5abc0"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:03b5c805a0b36f00ec8b7eba4635c1949ede37764b1a40ea7f62b44369499174"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:466d11ea0dcac6a4596be6a2c246d0d0938edccc9116806068aa9ef3800a171c"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0d5aa091c1ca772d8190d24a0a4ef92c86e90cf8fc1de5f576960808e3550d"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0e062f776e7dcec321ee8f8e6b37e0d3825bf5ce1e7ecc4cbe2eaee7ae1a9ad"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69b67d11269ab72996227fedebaa40961de9d35ed489bbee9a63954e44bd5ac"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5de93c8be94399756a3bdd66538cbd5cffcef39dea17ea8ac1b3f7b9a090245f"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:12cff94db43e0fa5c8e54eedd52fd563482576ed740d463c0929ed45ff5c4f1a"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:31e8488211deb0134c5e8ba5f3841cbc28e535477390aa18fb09927658c3489a"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5dc10fb2089eb77d721f925a804b782134b015d66a675e8b6497579f7cc2814a"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7c76924cc9f7562412291a8fae1420517938387fe5061e1278771f41f77748a8"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5945dc789a72b7068b180be1838172d2394ad2863207b70d7ff9eda29875d4f3"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-win32.whl", hash = "sha256:c651af7890400355038f824a05959fb160c3116d51bd47448d520c39f3755432"},
+    {file = "Levenshtein-0.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c0f16483b12fede6ab2bcbbec780142612c5b01b76b3fafc71d0e618000e8d8f"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cfeb890c51348e10d43a5f569b7fa83f253186000a139fc9ee54fd2885959e9e"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5e1dc57de06fc6e59307b181d4d13cd1824e0e5223d523e4e0472d87920f689c"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2d94bef7af9434003a5acd96c92a9e28a1fa50a1606427298e5e3610585fb4d4"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6847655727e07628f892a1adf0ac9e27bc9cdd8aa05de48d918362dac8b1cb5f"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc0f9d48e52c8d285654b5bd45789631bb19fefce20f9fd45979a7c9975e5a2"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87b21fb7ec154993a2ed273001c725fdd91162f8154c2394924eaca8989d975a"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:659c3d9d31bfb137b9d23dd4c58786b49244847598ee4963df1d2c9f189f4c66"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afe1b3cdce8248967be3bede505bac06a51ff5308cf634115f0fc1c6d0b3a49c"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:225ebfc72797cb787b830f902aaf9446acb881bb8a2061d4b9c950aecd0f26df"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:41f576905e3e958c8bfaebbd3184afb7fc3bbab882bcc778fdcb9fd1758b4de7"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1a7872b0e02adc9503ffaa3c9abc5be83a3dd6a7aa2c0a9e4d299cbc2dcf1cbb"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:37e14128727e5e19a5976f64410c8f11f92b28a087fdb4965bd435f4b302e293"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42aca55423c9cf40da97c9971696eca14b61ca7829041d6c5af3419398d1dacc"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-win32.whl", hash = "sha256:a26151d9202d3110c4ece2fe3d823cdfafc628e8cbc8156cfbc32155eafd723b"},
+    {file = "Levenshtein-0.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:9c96d7ef54038040a69c598f5089b42964ba76f53e5fd74502389e720c749afd"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b8531dc9934736205e21d788e2dc4a002a1fbe236db0a60c109b25e6176e8eb"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:baf0cad12908aeb7b81510cf30ac27dd3411f3b20b3607b1d6e1e63c53957670"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:47029a80027832ac5df34af2f4266b52ae80d8ccd6f7a702a7a76c6d9b8df23c"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d5451f52ebe968b7af0c5e7f52ffc297eeaf7d6b34be1fce87ce850e479316"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a40e439bcf2c3e032df3eaa584a1b15f7c7fd13201694e91335ea2a3b441b0a"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b25f11bad38a79e11a065cc9bdd09955977351e80b7a923bb9f912b492b1c662"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caad22e694b0556794009241165b5d2d3e0cbae2a07445a1430e261ea1488ed6"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf3bc9782a9ac6707c7d54e322dac3b3274a1c5fd88bc45d1a0d23cda247a0"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b06362b89e286de63ada5a345aa14c825d32bfe20520860da676eba0d849b34a"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:aef088da3fb3ab96fb90a17f9c3b80aa63193436ca29dd36a8ce1c33dec7ecb2"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:3b16a7137faca31c68b1cd5cd411008c15f9aa1d01527c9bf868aab4b850b768"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:82e97a9b15def6b90126588db5e1e90c8072c1065277fe1f0eeacf8e307b0501"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ede221d77b8801c35b7aad581dac65b3d2d4b0f6cb8a4e1ba3cfa01ffbc1dc99"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-win32.whl", hash = "sha256:1ea00397a7a7b2feec93b8122f01766f287c0a3e580aed80f19f9f0442ac8400"},
+    {file = "Levenshtein-0.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:7aaafbfb9968c0f31a897bf0ac686ca23ffba8a0e54f07b7e12a78ab12f32bee"},
+    {file = "Levenshtein-0.20.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9a1dcc4724acf7f6bbef32fb23773541de0b31483dfa4a5f8c174d022eb8721"},
+    {file = "Levenshtein-0.20.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5af3a29ec5902db1da3637f910d9baf78246153abade4f416024c045c777371b"},
+    {file = "Levenshtein-0.20.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23c8372ba2549e339cfb783944806517407e8ce2d980be3ad1acc61426ab0d01"},
+    {file = "Levenshtein-0.20.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8c57c57a248e4f6919887266a476beeddeb12623c317c44ca26ece561ce5a2b"},
+    {file = "Levenshtein-0.20.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4a61dc61e27e5d821f36fe9bda040a23f62f206b964171ba8d77d1cf9f6b46"},
+    {file = "Levenshtein-0.20.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:03a08cb2cb9cb51d2137a7d9b6aa2413a004700eaf20f4b8a7622373683929f1"},
+    {file = "Levenshtein-0.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe68718cbaa5f907a0446e9155019013564a0122da7bd3813d494d409366e502"},
+    {file = "Levenshtein-0.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:830367809974f0317a882f96021cda8619406628295d7e8bb8a239ad6652da4c"},
+    {file = "Levenshtein-0.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a32b24a6da72b79695264c736e1a5af5e69777370c2c02ddb06c167faad8fa00"},
+    {file = "Levenshtein-0.20.1.tar.gz", hash = "sha256:75c5f64595955f323de84c5d8cf3a6896b7bd978d53bf48af61bcfefc850161e"},
 ]
 linkify-it-py = [
     {file = "linkify-it-py-1.0.3.tar.gz", hash = "sha256:2b3f168d5ce75e3a425e34b341a6b73e116b5d9ed8dbbbf5dc7456843b7ce2ee"},
@@ -1733,37 +1868,40 @@ mdurl = [
     {file = "mdurl-0.1.1.tar.gz", hash = "sha256:f79c9709944df218a4cdb0fcc0b0c7ead2f44594e3e84dc566606f04ad749c20"},
 ]
 mypy = [
-    {file = "mypy-0.960-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3a3e525cd76c2c4f90f1449fd034ba21fcca68050ff7c8397bb7dd25dd8b8248"},
-    {file = "mypy-0.960-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a76dc4f91e92db119b1be293892df8379b08fd31795bb44e0ff84256d34c251"},
-    {file = "mypy-0.960-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffdad80a92c100d1b0fe3d3cf1a4724136029a29afe8566404c0146747114382"},
-    {file = "mypy-0.960-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7d390248ec07fa344b9f365e6ed9d205bd0205e485c555bed37c4235c868e9d5"},
-    {file = "mypy-0.960-cp310-cp310-win_amd64.whl", hash = "sha256:925aa84369a07846b7f3b8556ccade1f371aa554f2bd4fb31cb97a24b73b036e"},
-    {file = "mypy-0.960-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:239d6b2242d6c7f5822163ee082ef7a28ee02e7ac86c35593ef923796826a385"},
-    {file = "mypy-0.960-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f1ba54d440d4feee49d8768ea952137316d454b15301c44403db3f2cb51af024"},
-    {file = "mypy-0.960-cp36-cp36m-win_amd64.whl", hash = "sha256:cb7752b24528c118a7403ee955b6a578bfcf5879d5ee91790667c8ea511d2085"},
-    {file = "mypy-0.960-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:826a2917c275e2ee05b7c7b736c1e6549a35b7ea5a198ca457f8c2ebea2cbecf"},
-    {file = "mypy-0.960-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3eabcbd2525f295da322dff8175258f3fc4c3eb53f6d1929644ef4d99b92e72d"},
-    {file = "mypy-0.960-cp37-cp37m-win_amd64.whl", hash = "sha256:f47322796c412271f5aea48381a528a613f33e0a115452d03ae35d673e6064f8"},
-    {file = "mypy-0.960-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2c7f8bb9619290836a4e167e2ef1f2cf14d70e0bc36c04441e41487456561409"},
-    {file = "mypy-0.960-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbfb873cf2b8d8c3c513367febde932e061a5f73f762896826ba06391d932b2a"},
-    {file = "mypy-0.960-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc537885891382e08129d9862553b3d00d4be3eb15b8cae9e2466452f52b0117"},
-    {file = "mypy-0.960-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:481f98c6b24383188c928f33dd2f0776690807e12e9989dd0419edd5c74aa53b"},
-    {file = "mypy-0.960-cp38-cp38-win_amd64.whl", hash = "sha256:29dc94d9215c3eb80ac3c2ad29d0c22628accfb060348fd23d73abe3ace6c10d"},
-    {file = "mypy-0.960-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:33d53a232bb79057f33332dbbb6393e68acbcb776d2f571ba4b1d50a2c8ba873"},
-    {file = "mypy-0.960-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d645e9e7f7a5da3ec3bbcc314ebb9bb22c7ce39e70367830eb3c08d0140b9ce"},
-    {file = "mypy-0.960-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85cf2b14d32b61db24ade8ac9ae7691bdfc572a403e3cb8537da936e74713275"},
-    {file = "mypy-0.960-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a85a20b43fa69efc0b955eba1db435e2ffecb1ca695fe359768e0503b91ea89f"},
-    {file = "mypy-0.960-cp39-cp39-win_amd64.whl", hash = "sha256:0ebfb3f414204b98c06791af37a3a96772203da60636e2897408517fcfeee7a8"},
-    {file = "mypy-0.960-py3-none-any.whl", hash = "sha256:bfd4f6536bd384c27c392a8b8f790fd0ed5c0cf2f63fc2fed7bce56751d53026"},
-    {file = "mypy-0.960.tar.gz", hash = "sha256:d4fccf04c1acf750babd74252e0f2db6bd2ac3aa8fe960797d9f3ef41cf2bfd4"},
+    {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"},
+    {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"},
+    {file = "mypy-0.971-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3"},
+    {file = "mypy-0.971-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655"},
+    {file = "mypy-0.971-cp310-cp310-win_amd64.whl", hash = "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103"},
+    {file = "mypy-0.971-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca"},
+    {file = "mypy-0.971-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417"},
+    {file = "mypy-0.971-cp36-cp36m-win_amd64.whl", hash = "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09"},
+    {file = "mypy-0.971-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8"},
+    {file = "mypy-0.971-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0"},
+    {file = "mypy-0.971-cp37-cp37m-win_amd64.whl", hash = "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2"},
+    {file = "mypy-0.971-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27"},
+    {file = "mypy-0.971-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856"},
+    {file = "mypy-0.971-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71"},
+    {file = "mypy-0.971-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27"},
+    {file = "mypy-0.971-cp38-cp38-win_amd64.whl", hash = "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58"},
+    {file = "mypy-0.971-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6"},
+    {file = "mypy-0.971-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe"},
+    {file = "mypy-0.971-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9"},
+    {file = "mypy-0.971-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf"},
+    {file = "mypy-0.971-cp39-cp39-win_amd64.whl", hash = "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0"},
+    {file = "mypy-0.971-py3-none-any.whl", hash = "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9"},
+    {file = "mypy-0.971.tar.gz", hash = "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56"},
 ]
 mypy-extensions = [
     {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
     {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
 ]
 nodeenv = [
-    {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"},
-    {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"},
+    {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
+    {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"},
+]
+nuitka = [
+    {file = "Nuitka-0.9.6.tar.gz", hash = "sha256:293f1909c611da53a3f0f9a17c129c4fa06b4b893dfbe7bf57b986214ef02e21"},
 ]
 objprint = [
     {file = "objprint-0.2.2-py3-none-any.whl", hash = "sha256:9f50bb3b7cbe95b6d22c79e4f08a5273e3f7e5ff5ce35e146f6e7854abd276a0"},
@@ -1782,44 +1920,64 @@ pbr = [
     {file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"},
 ]
 pillow = [
-    {file = "Pillow-9.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe"},
-    {file = "Pillow-9.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e"},
-    {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602"},
-    {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530"},
-    {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2"},
-    {file = "Pillow-9.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a"},
-    {file = "Pillow-9.1.1-cp310-cp310-win32.whl", hash = "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c"},
-    {file = "Pillow-9.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108"},
-    {file = "Pillow-9.1.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b"},
-    {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d"},
-    {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84"},
-    {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4"},
-    {file = "Pillow-9.1.1-cp37-cp37m-win32.whl", hash = "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578"},
-    {file = "Pillow-9.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9"},
-    {file = "Pillow-9.1.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf"},
-    {file = "Pillow-9.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b"},
-    {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546"},
-    {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f"},
-    {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a"},
-    {file = "Pillow-9.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1"},
-    {file = "Pillow-9.1.1-cp38-cp38-win32.whl", hash = "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54"},
-    {file = "Pillow-9.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf"},
-    {file = "Pillow-9.1.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92"},
-    {file = "Pillow-9.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a"},
-    {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251"},
-    {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d"},
-    {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1"},
-    {file = "Pillow-9.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601"},
-    {file = "Pillow-9.1.1-cp39-cp39-win32.whl", hash = "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45"},
-    {file = "Pillow-9.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c"},
-    {file = "Pillow-9.1.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6"},
-    {file = "Pillow-9.1.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098"},
-    {file = "Pillow-9.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c"},
-    {file = "Pillow-9.1.1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd"},
-    {file = "Pillow-9.1.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340"},
-    {file = "Pillow-9.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765"},
-    {file = "Pillow-9.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8"},
-    {file = "Pillow-9.1.1.tar.gz", hash = "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0"},
+    {file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"},
+    {file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"},
+    {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"},
+    {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c"},
+    {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1"},
+    {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58"},
+    {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544"},
+    {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"},
+    {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"},
+    {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"},
+    {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8"},
+    {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9"},
+    {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"},
+    {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"},
+    {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"},
+    {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c"},
+    {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a"},
+    {file = "Pillow-9.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1"},
+    {file = "Pillow-9.2.0-cp311-cp311-win32.whl", hash = "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf"},
+    {file = "Pillow-9.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c"},
+    {file = "Pillow-9.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069"},
+    {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f"},
+    {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8"},
+    {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b"},
+    {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467"},
+    {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59"},
+    {file = "Pillow-9.2.0-cp37-cp37m-win32.whl", hash = "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc"},
+    {file = "Pillow-9.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d"},
+    {file = "Pillow-9.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14"},
+    {file = "Pillow-9.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3"},
+    {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402"},
+    {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f"},
+    {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8"},
+    {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff"},
+    {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1"},
+    {file = "Pillow-9.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76"},
+    {file = "Pillow-9.2.0-cp38-cp38-win32.whl", hash = "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f"},
+    {file = "Pillow-9.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8"},
+    {file = "Pillow-9.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc"},
+    {file = "Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da"},
+    {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4"},
+    {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c"},
+    {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421"},
+    {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20"},
+    {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60"},
+    {file = "Pillow-9.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4"},
+    {file = "Pillow-9.2.0-cp39-cp39-win32.whl", hash = "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885"},
+    {file = "Pillow-9.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"},
+    {file = "Pillow-9.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3"},
+    {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb"},
+    {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be"},
+    {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd"},
+    {file = "Pillow-9.2.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013"},
+    {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490"},
+    {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac"},
+    {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e"},
+    {file = "Pillow-9.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927"},
+    {file = "Pillow-9.2.0.tar.gz", hash = "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04"},
 ]
 platformdirs = [
     {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
@@ -1830,24 +1988,62 @@ pluggy = [
     {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
 ]
 pre-commit = [
-    {file = "pre_commit-2.19.0-py2.py3-none-any.whl", hash = "sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10"},
-    {file = "pre_commit-2.19.0.tar.gz", hash = "sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615"},
+    {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"},
+    {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"},
+]
+psutil = [
+    {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87"},
+    {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af"},
+    {file = "psutil-5.9.1-cp27-cp27m-win32.whl", hash = "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc"},
+    {file = "psutil-5.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2"},
+    {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0"},
+    {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22"},
+    {file = "psutil-5.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9"},
+    {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8"},
+    {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de"},
+    {file = "psutil-5.9.1-cp310-cp310-win32.whl", hash = "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329"},
+    {file = "psutil-5.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021"},
+    {file = "psutil-5.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237"},
+    {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453"},
+    {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685"},
+    {file = "psutil-5.9.1-cp36-cp36m-win32.whl", hash = "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36"},
+    {file = "psutil-5.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d"},
+    {file = "psutil-5.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc"},
+    {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676"},
+    {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4"},
+    {file = "psutil-5.9.1-cp37-cp37m-win32.whl", hash = "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b"},
+    {file = "psutil-5.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680"},
+    {file = "psutil-5.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1"},
+    {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4"},
+    {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b"},
+    {file = "psutil-5.9.1-cp38-cp38-win32.whl", hash = "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689"},
+    {file = "psutil-5.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0"},
+    {file = "psutil-5.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81"},
+    {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e"},
+    {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537"},
+    {file = "psutil-5.9.1-cp39-cp39-win32.whl", hash = "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574"},
+    {file = "psutil-5.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5"},
+    {file = "psutil-5.9.1.tar.gz", hash = "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954"},
 ]
 py = [
     {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
     {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
 ]
 pydeps = [
-    {file = "pydeps-1.10.18-py3-none-any.whl", hash = "sha256:865b5361e8c99c492ee1625da21776854f4c5eeeb09ebe3fa2384a134b4d457a"},
-    {file = "pydeps-1.10.18.tar.gz", hash = "sha256:d512f6f0984947a45553598798cdf229a4a23a2c1389eaf60139416a68fcec5f"},
+    {file = "pydeps-1.10.22-py3-none-any.whl", hash = "sha256:5f4ee42289182b61322054ff58af83f174b9a7e59fca78e115166ed942b84f31"},
+    {file = "pydeps-1.10.22.tar.gz", hash = "sha256:d9e96f13a6fb1858a960410bf7993336ebba2f7d62318d00ca77d4eecb415b8a"},
 ]
 pydocstyle = [
     {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"},
     {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
 ]
+pygments = [
+    {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
+    {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
+]
 pylint = [
-    {file = "pylint-2.14.0-py3-none-any.whl", hash = "sha256:ef64ce5d4c17b8906caeaf2c2914ef3036a3a1b7f4a86f5fbf6caff9067c5f63"},
-    {file = "pylint-2.14.0.tar.gz", hash = "sha256:10d291ea5133645f73fc1b51ca137ad6531223c1461a5632a1db029a9bc033b5"},
+    {file = "pylint-2.14.5-py3-none-any.whl", hash = "sha256:fabe30000de7d07636d2e82c9a518ad5ad7908590fe135ace169b44839c15f90"},
+    {file = "pylint-2.14.5.tar.gz", hash = "sha256:487ce2192eee48211269a0e976421f334cf94de1806ca9d0a99449adcdf0285e"},
 ]
 pylint-pytest = [
     {file = "pylint_pytest-1.1.2-py2.py3-none-any.whl", hash = "sha256:fb20ef318081cee3d5febc631a7b9c40fa356b05e4f769d6e60a337e58c8879b"},
@@ -1857,9 +2053,9 @@ pyparsing = [
     {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
 ]
 pyside6-essentials = [
-    {file = "PySide6_Essentials-6.3.0-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:1c2a2a2b26fc923b3527907462ae5828b7e50a2c0fcf9923b086781af3911060"},
-    {file = "PySide6_Essentials-6.3.0-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a486abe04be6270da798eae9c78b40f605008f19d5d9c880b1683783c715882d"},
-    {file = "PySide6_Essentials-6.3.0-cp36-abi3-win_amd64.whl", hash = "sha256:7304353ab13cc9b5b0a86b3487f24b133a68c5b8c1312516510c0d49469f80d8"},
+    {file = "PySide6_Essentials-6.3.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:55696693325a2de7bf5b56274b534f191032d218d61a948baa95933f6e642e59"},
+    {file = "PySide6_Essentials-6.3.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e27962beb2cc45fe13a1a1c24a454c3c3c3c3082c4a84bc5dcf6b306979ba013"},
+    {file = "PySide6_Essentials-6.3.1-cp36-abi3-win_amd64.whl", hash = "sha256:fa825c5396a5dfedf59635e904239187e2f2225c7f65917d4e973062c9a6b916"},
 ]
 pytesseract = [
     {file = "pytesseract-0.3.9-py2.py3-none-any.whl", hash = "sha256:fecda37d1e4eaf744c657cd03a5daab4eb97c61506ac5550274322c8ae32eca2"},
@@ -1874,8 +2070,8 @@ pytest-cov = [
     {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"},
 ]
 pytest-qt = [
-    {file = "pytest-qt-4.0.2.tar.gz", hash = "sha256:dfc5240dec7eb43b76bcb5f9a87eecae6ef83592af49f3af5f1d5d093acaa93e"},
-    {file = "pytest_qt-4.0.2-py2.py3-none-any.whl", hash = "sha256:e03847ac02a890ccaac0fde1748855b9dce425aceba62005c6cfced6cf7d5456"},
+    {file = "pytest-qt-4.1.0.tar.gz", hash = "sha256:027f3d3f5dd04af0530d846cf50fb858f719f7e87c2e4a1c686abd4e0f72172a"},
+    {file = "pytest_qt-4.1.0-py2.py3-none-any.whl", hash = "sha256:edd08dae3b207405edddfc482d4dda4b848e85a8e6a0e7c36f20bac11ab328de"},
 ]
 pytest-xvfb = [
     {file = "pytest-xvfb-2.0.0.tar.gz", hash = "sha256:c4ba642de05499940db7f65ee111621939be513e3e75c3da9156b7235e2ed8cf"},
@@ -1889,6 +2085,10 @@ python-slugify = [
     {file = "python-slugify-6.1.2.tar.gz", hash = "sha256:272d106cb31ab99b3496ba085e3fea0e9e76dcde967b5e9992500d1f785ce4e1"},
     {file = "python_slugify-6.1.2-py2.py3-none-any.whl", hash = "sha256:7b2c274c308b62f4269a9ba701aa69a797e9bca41aeee5b3a9e79e36b6656927"},
 ]
+pytoolconfig = [
+    {file = "pytoolconfig-1.2.1-py3-none-any.whl", hash = "sha256:5f291567f0363a7314406be4f2381ece4e552a8608d2629544679e4d36d0df2b"},
+    {file = "pytoolconfig-1.2.1.tar.gz", hash = "sha256:5ac82f78d731531f9f82e5cc7f5ebae9473b1404c0e75aa5ac0b8b41cd99b510"},
+]
 pyvirtualdisplay = [
     {file = "PyVirtualDisplay-3.0-py3-none-any.whl", hash = "sha256:40d4b8dfe4b8de8552e28eb367647f311f88a130bf837fe910e7f180d5477f0e"},
     {file = "PyVirtualDisplay-3.0.tar.gz", hash = "sha256:09755bc3ceb6eb725fb07eca5425f43f2358d3bf08e00d2a9b792a1aedd16159"},
@@ -1933,73 +2133,146 @@ radon = [
     {file = "radon-5.1.0.tar.gz", hash = "sha256:cb1d8752e5f862fb9e20d82b5f758cbc4fb1237c92c9a66450ea0ea7bf29aeee"},
 ]
 rapidfuzz = [
-    {file = "rapidfuzz-2.0.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb54edd0fa8620d37a7c0762895260bc75a6cc083d161b14d40a562b6f303975"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8093b5f234be618bb8cfe34d65c072fee362fbd13f6c1b37f80eac0f30c24cfa"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea72586c08ba8ce08c37c21bb7c383df740dc7d6e921423e1881570be62ed15"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ee9a057b7638e91377b217df3724d4adefec3936617180b3df1f64fa64cd995"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bad453a76f6832a99251beb89c352a4f436f4e7687a5843b080c294dba68d8d6"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a545627a7d45ea4ad1cb66fb6ad7b951825b0e97053056cda9d2f5fbb30abe3e"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-win32.whl", hash = "sha256:8e583595efe5afdd68a7b5423cbd5fff0d1870d60cee16af17897f701f39d933"},
-    {file = "rapidfuzz-2.0.11-cp310-cp310-win_amd64.whl", hash = "sha256:09efd5a02a33dfb18ec6f28b85f102b51cbac080e624924f3a4f36d3b08962ef"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c81216ecff325765bb441caf7f50a1f55aa66192aca12ec6d448b509c9387a39"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b555dbebb413ab66c2cd394338c860094a5464f9b63faeb40ebec44271c460b"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a007fe85dfff7a961daba13884629dcd9ab45197a2fc40749a7e8f750e7715a4"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1031420c083681b41346267e26f9f76ef2c1544a0129fa67b07239d7a9ab9fd6"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-win32.whl", hash = "sha256:4b16147122ec4c5e4a31131b8530e674ba1b3e74e2b43b73aedc6bd0021fcae6"},
-    {file = "rapidfuzz-2.0.11-cp36-cp36m-win_amd64.whl", hash = "sha256:de7559765e1da54d8d42495368e0a9852041cf8d4e077fb27811d6f009611a4b"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ace59b7857e5d5b252564dd60d840667c19c00d357c7ba32e9671b68615dc49a"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09d83e5ab57fb61a6003a3607494b1f443978e8d6b199fed3094e92f466f3bba"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3a53797613b53e93adbf9c410260aecde5ab1d7cd1b07792be1ee4800716598"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9084a550719aff3752e5a63e32d381d64b09264cabf35d5e21e6a9f0e91baca"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-win32.whl", hash = "sha256:35c8f2cae3e2079616fdf90c6b6bcf850d3810c9184c6e89a4826b6d0af88974"},
-    {file = "rapidfuzz-2.0.11-cp37-cp37m-win_amd64.whl", hash = "sha256:1da580130b37a007684ab9dc6f85125e3c0d06c9f9df349e7bd52e312811c436"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:757ae64598a93d0f8a21007c1abd6800f38c04e4b89167ca7b833ce30f54aef3"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f5b0fd8f6bde8d89c07b76643c9f3a01e2e089b246a97b721e7fe97fdaa41820"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a13cea3303b444af49417352cd11830ea2245d4e5a82bb06b6895638b81c6029"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d96dba6ef863cba7efd22077ba28e19a8829b523c7c7e41304c568a6ab91fc4d"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcecc662df808ad051d9524608a3682fd80d882c93664adbaab4c7b0796e385"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff74f3abd0ed473f81ba67d3207ca6db74b8b50ebae1a6734ba199a8d90d67b4"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-win32.whl", hash = "sha256:b3e7eea1dd304bac4ac74a1af71da35bb68bf6060f5d6b4ad8a3e4e2c84d5110"},
-    {file = "rapidfuzz-2.0.11-cp38-cp38-win_amd64.whl", hash = "sha256:5b203e83adc10dbe961a3000fa09cc47f5672d2c98c3fd2f6bb7b0df225805ee"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1fe837f8b305c59549e2eec6fe8dbdd7344eeef0033fa4ee90af65f72b32c25f"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc2c8aa23de4a0bef2162440f5095f606052c289059fbeb03180740783e25e6b"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ebb03a6a5171233958b6adcada00c7521186ea4b78b6652b99d94d5dbf59c809"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f21d8754ee49ee8da73ad5e746495a27fd29ab769f5e45ede4d8232955e0237"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23c79ca555f188445f2e054b40a89c82e5d21b22d34f00da6e7491a6d70feff5"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b10de1ea834be1f26d1f35f3e1d1f8c003c7951a7475ab9b28b5a62e9f6f0c0"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-win32.whl", hash = "sha256:1bda150aca38c4d4739780c3a99c190c05101839adc10ab7804ed86000440267"},
-    {file = "rapidfuzz-2.0.11-cp39-cp39-win_amd64.whl", hash = "sha256:f4ea654ef221a57b47523fe70d7423254dd285f73948b9d8c1215610d2a38e9e"},
-    {file = "rapidfuzz-2.0.11-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2542f0a3c4079b15c0485ece589e5a248633de84326e4a3ca63ea024a0b59775"},
-    {file = "rapidfuzz-2.0.11-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dca3c02511d23a58ef14f2fbcd7b311eae1bc40e3d36be493ef22b9572ebed1"},
-    {file = "rapidfuzz-2.0.11-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fbb649a978fab0232cefdeb67321d853c676b3ebb7481b8b80030905a42d799"},
-    {file = "rapidfuzz-2.0.11-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:081415323e94e0016109715438d4ccb233ab038b09ba3cf79038e50601a410e9"},
-    {file = "rapidfuzz-2.0.11-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a80efb64f1b38c64f04f4ca6881c9684d7912dc9124ecbf953c9b541f935b33c"},
-    {file = "rapidfuzz-2.0.11-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ac8ab8106bc7b0ffab539baa5279a850c61b71ccad86dc11503bc084f6ac1af"},
-    {file = "rapidfuzz-2.0.11-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3933a1cfdf6ab4e059d8eb68460fa430a4f6be06431d1a8b05f7fecdd63e586e"},
-    {file = "rapidfuzz-2.0.11-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:537b72d954ff395cefc210fc7e41810a26e84ed7f1e93d0dffe3669277d6ea23"},
-    {file = "rapidfuzz-2.0.11-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2d167b1bf92a60eefbaea3abf646baa2a3aa7125595e129c8890072706a80ac"},
-    {file = "rapidfuzz-2.0.11.tar.gz", hash = "sha256:934b65fea75e3bd310d74903ec69ff3df061b3058ab5b7f49ab772958109bca8"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:40b70a4277c73401bf06cfe833317c4c6616943e74497689412634721601a3c6"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd956594eedcc8ee9d10c6907f89b22e09cdd1b707a66ed77ecfdb31c707addb"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:06121384ceca291c1b5215d44cdbbf3d87db8880c3eab2297f933ca1ce5128ad"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c265ba6648f20cbb03f146bf75426b162814ac55bd466db3d87aba16a275c5b"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a061cab4f8ed57644deeaaebeddf4da8ba4a3fcd77d6106e0e91d77b8ef09c4"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a88097cb0c15f48548a38263d8ef4878ebc7581209cd5e7f34e98208fdc7fc3d"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c268c6cf8fadb50bc710da7d8194f49c221d2e1cf4da229639dd0ba7cc75bddb"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a1f64e599eb3c42371d6d0d5dd5d057991739ca510b8bd6a5c0aafce4ac0c7"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11808afdfd60b7549d31da6320f812eb8b9e7ea6785878486dfd182a53833b6e"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9e5a6c2366d732aab1d820c1f373a05460c94242f62c3eec8d69885d9c81bf3e"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:260c230ce47cbed24bf222e05ec0a5f9a28293c2b566a97f142a6465a53d3350"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:1ea250cd8417ccc7b8de62fdd12428ef2ec70f61a5233643e49f8a9b89fa1ed9"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df947d7a09efd33528a05acfb9676c039b28c964a083018a8004569564daa8ba"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-win32.whl", hash = "sha256:e925443a16e8c4481be9f7394e0e6894937462c193ebfc922669358dad26041d"},
+    {file = "rapidfuzz-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:3f8f70e19a25afe921551d27ab732237a7e824eaa7987610d766f0d810036b63"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dbe2352103bd2e860f40b5b62830b93663889260c65349bae52e493835af9d20"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26ed50072d9c2fc85b75d06dfd5da939c9b19b1240560d0860aa2f4f2d689e56"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8221952fa345e9a4e3716e73d7ea773a96b4b22d7e86a0cfc659d5597ce7025d"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30169918f58d4695efed40d0cf4752f9a8700fbc78c370f019de228d4aa2cd13"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc10f600b7cf15ff5158509287b0095b954a1f5498c5ea23f102ef06c1b0cd3a"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51606a7dd226cece687730566bcbab69db215739c0bfdc0ebf3c1f61841862bc"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:bdae4684f90cbe97a04c06fea2809842dd443ddad822da3d4b1c1ceaf8e023ec"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:62204b908ebadb8056851f3ea2ba8eace16b84a8e9d65350ce7087b95ba45dbe"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2d40f26f9782403335574d07062e0ebf64937f829b29992a2df2dc9d7aff626d"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:35ff00448a75649ab181e03c264bdf0c3fc46eae29382f6ec7a635fdcb49346c"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5302ab15055150e232bf9506ad4d33170fb81337943c49e5ad1f98907ab0e015"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-win32.whl", hash = "sha256:23c1a16e0930b74d9766b80fb6fea3d78536cccf127c7e0d693f5c9a8655460a"},
+    {file = "rapidfuzz-2.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2fc9bf751408396260fe2b6cd0e2ba5361229e22f26e3b59b08c08815830968b"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f57ab7f66b5e8f8ad66b7115b2f04316fce6b6beb19b89f151b590a53c7c7a6"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99657acaeeace8add81da35b8625783e06f251685ff2b582fc748f501a82826c"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d830db60d293ff0602ba7798e792bcbc0ec9eda6bb80bac6df2850056dc0705"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76cb19a9454dd1773a81f0c65cc33eadc8dceea892f5be86646150dbbc4fef70"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:229daf8051cac2f60c380e8385fd91d8c461201957b547867b5f9d50c0099c17"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95b28d765d53111f932f5a57925b8191783015156e386533b51fc3a4c442d828"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3fe0a4d0f545efab85232a2a67628fd371fd4430cf832f5617f7cbf09b2f0ea2"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:66e70f89e80640f1351d116806e4ce57b3581725b47ca4a7ebca193fab6033a5"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b4618e4879924726c9dcde0da82ca20b6115dfd65fadc959732fe65019a4ffd"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:b933103b3264927fc9c561709277aa6de199371560a09b5db4177bca7bc1ac82"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:31fc180736bc871718d9d992c36241818e1d280091bb57059f90275cdf398fdd"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-win32.whl", hash = "sha256:480eba6f533e53d516f0e3477a67324b2b9a2f67f57a169784b8e4a62ad788c8"},
+    {file = "rapidfuzz-2.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d649358105683c0bb4422b934a2fa9aedd25854648ba5041826a99607e274f40"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4307eeea7e37097ab4d9e22a6553a753cd6beaf7727422a92d18b156d48f7145"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08093590a70d8bd2a66fc26b29635017779a5c6380e795f6050e79d6edc78911"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2cf4ab0bd45892e9a9ed2e6d7d41d1cf571e479ff0f3358deac029086fd8c920"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81f01fce0a5fad68c6108143911abae0d765acb85b1c1379341b26590154056f"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54ce466224791171ef0ece47bdfe5fdbda459a644c0090af804a7384bba9fc96"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10e67a6c2131661ef5633c6e36d77dc65e3436088f77a44e802f6410bc292af6"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:975ed43da9f3f4e98c47fbc503859438c734ff283fa485a532c81f5b844d7781"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee7a3745a0e76565de1036af4591a64489319834e3abd8d61565e1c86ae35e8"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cb086c659a913fc8a1fb0746557abaeb1d0c2ac4dc60905c46478d80898e3448"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a7aa7ab003f4ec26389521d280ce8d43c471db7ca30eda0c22a9279bed58c839"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3b96fbf1c1ff5fc8c07a77bb2ed20dcb95608963cb08cb8fe3f6265c90f7cba2"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:287a0e70ffe26275325fae08739a5034e013434e3af163e8ccadb6131b292d64"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e55fc8ade3768ea4738ee89b725a290f689cd2c3ee57f61383be04782f2bbe18"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-win32.whl", hash = "sha256:6c67598d1d074d5f81d36ca651558d252b0cc7fbd5302389a9c1206e021dcf55"},
+    {file = "rapidfuzz-2.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:699be4042f420c9469be7297c2f465aac1ece48d8ab5efcb1b071d54224b946e"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:44aa685ff81fea37487e2255205b5db5d448e7f07cb483ca0896350aa38f920a"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:af2aec580734e04933533d94ba76f7c6d7b590aff7246d960e30049ef412bc0e"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a3dcc7744a3b5f488b48c39d9e7a7e4e059a5c419bf2fdcc373af873fb565eb3"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e44809e3200d9cd78bf5093fd149857de61be5ab7aeb633ba1bea9e84719a0e2"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e985a889e23770061b7c221170a41d65a3df53a3488bfd422f2a315ae1299fb"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f51eb2effe7c3061840821f8c9102aab58a2d46a3a4dd6a2df99e08067e6e3f"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:11c40d1094aa638b18968ede4661e2562753c04ab2d8a04c6184f845c0ea8d1b"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c00cfa91551c58aa3f6646ae0f06d4a28391f3b0fc78975999c2275272872b8"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:58ef0edebb11c8f076759b0b54c34ae9a05209e2a4725bd5308db08606526f65"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:34dc7096e76ffa0eab7d4071d0020c3c7e2588ba70287156d3694a5e4a202451"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c5bba51120e00320e7e2f6866a0cd6757848b73eb11795cc4247a3cea8555f29"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f7a90ac59dda626f981f958b42158956b57e8c61c2577c91d2459a0595c9a79"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f779edfe9abf56bd10e6cbfddb156b471e63a9853802a897ec54762383a3"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-win32.whl", hash = "sha256:70339dbb6b2111d3f2f570c172ba53664b3775218ea59183e4c7f9246c2aa06d"},
+    {file = "rapidfuzz-2.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:abc22ee309d4c41c014b1c3f697072a5c1dff2ec72b2fa32dcdfb6adc224ce14"},
+    {file = "rapidfuzz-2.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:605a8f1a29500cd37ba80e9152565424dfc8d9a5c4de2cefca6317535464839a"},
+    {file = "rapidfuzz-2.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36ecb511f6521f892fd69833765422d708a09a8f486b4d1cdf4921095a2c1ca3"},
+    {file = "rapidfuzz-2.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9fd10265f4c8ff480529e615b4ad115a63ee8c346c0752118f25381ece22a253"},
+    {file = "rapidfuzz-2.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b4fa5ddb212baa5b73cf9cc124532d9fd641812afb301d04b16472844330ee9"},
+    {file = "rapidfuzz-2.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:612ef2909fa89b01eff9a549b814390a28a1a293eae78ccd9d1d1353ae6f5c41"},
+    {file = "rapidfuzz-2.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:137f0711db4908b68cbedadf1e1a60fa112e7f5c3b90bba561aad32d740cb84d"},
+    {file = "rapidfuzz-2.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d95b5550dcd195b10fee90686d853b5b86fc408e441b5d5e2f0f0d62ee6c7c9"},
+    {file = "rapidfuzz-2.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca9e9472957d8bd84f1cda25b1da6b815220c7a0127f7a1c4b34ecce6875f858"},
+    {file = "rapidfuzz-2.3.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:96c16c807803bbebf59e6bf54a7b970791040d5728f05c5022dcdcab3af8c885"},
+    {file = "rapidfuzz-2.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d339bb04dbb1f07fc07b8ed51211cee579a2cc72127095a04b2b4f1693efc0c"},
+    {file = "rapidfuzz-2.3.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb670143463cca6fb3346e7d61eebd53041547d91729df08f6f4827bab83e8d7"},
+    {file = "rapidfuzz-2.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b9f5c1681ec4bfcfcf2975453892346ec1ddf00a70d489c0cc67dfd8cc8e23"},
+    {file = "rapidfuzz-2.3.0.tar.gz", hash = "sha256:426d176c7d17f3ae0954d2bb30a3352cc9fa9f819daf458b5af7980e8e4dcd93"},
 ]
 requests = [
-    {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
-    {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
+    {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
+    {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
+]
+rich = [
+    {file = "rich-12.5.1-py3-none-any.whl", hash = "sha256:2eb4e6894cde1e017976d2975ac210ef515d7548bc595ba20e195fb9628acdeb"},
+    {file = "rich-12.5.1.tar.gz", hash = "sha256:63a5c5ce3673d3d5fbbf23cd87e11ab84b6b451436f1b7f19ec54b6bc36ed7ca"},
 ]
 rope = [
-    {file = "rope-1.1.1-py3-none-any.whl", hash = "sha256:216390b6342bde8ef1f27a6663554de0ea0b1fdad7c421deb3d5a3f6c5fc01e7"},
-    {file = "rope-1.1.1.tar.gz", hash = "sha256:13048ff0245a0fa187f282697a55add46e4ccf083e7670f868bdf54ee9e47f2e"},
+    {file = "rope-1.2.0-py3-none-any.whl", hash = "sha256:14e2e9b74ff345d038988fd62b7ef4226351e4a1181123596abb3a147fea9019"},
+    {file = "rope-1.2.0.tar.gz", hash = "sha256:f762542c9cfe52124aa55d33822a269fc4b0da70fe3170c6086de2733ed52f22"},
+]
+"ruamel.yaml" = [
+    {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"},
+    {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"},
+]
+"ruamel.yaml.clib" = [
+    {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"},
+    {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"},
+    {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"},
+    {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"},
+    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"},
+    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"},
+    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"},
+    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"},
+    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"},
+    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"},
+    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"},
+    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"},
+    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"},
+    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"},
+    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"},
+    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"},
+    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"},
+    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"},
+    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"},
+    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"},
+    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"},
+    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"},
+    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"},
+    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"},
+    {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"},
 ]
 safety = [
-    {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"},
-    {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"},
+    {file = "safety-2.1.1-py3-none-any.whl", hash = "sha256:05ba551fb61ef24c864835d21089f75bc8b37292680047b9f29693a6552e2fc7"},
+    {file = "safety-2.1.1.tar.gz", hash = "sha256:dbc5dffa2e47da76cc43dfe8cbbbfca99d29118d0c6c54dfcfa11c2bd349dff6"},
 ]
 schema = [
     {file = "schema-0.7.5-py2.py3-none-any.whl", hash = "sha256:f3ffdeeada09ec34bf40d7d79996d9f7175db93b7a5065de0faa7f41083c1e6c"},
     {file = "schema-0.7.5.tar.gz", hash = "sha256:f06717112c61895cabc4707752b88716e8420a8819d71404501e114f91043197"},
 ]
 shiboken6 = [
-    {file = "shiboken6-6.3.0-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ead1cee2fea2566321e725a50070c40a9e67aaa015a20a84a39a9e72ff9b426e"},
-    {file = "shiboken6-6.3.0-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e68e3cbb595c3047c4d893b84ef88eb5b23dea4e94241e80f5509dcb6613ad3d"},
-    {file = "shiboken6-6.3.0-cp36-abi3-win_amd64.whl", hash = "sha256:096e6b2254e59729ae61acbb80d09c31ad7ea35b6624ec120c15a35b95c70b69"},
+    {file = "shiboken6-6.3.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6393aa330101b098631a88dfb99b6b46794046c7f63b5c1ac93ae2fcef4773ff"},
+    {file = "shiboken6-6.3.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:aad9aa8e7ecd3c889cc789e41abf3990101126b5b02edfcf87f1ef331c9dc45a"},
+    {file = "shiboken6-6.3.1-cp36-abi3-win_amd64.whl", hash = "sha256:cb9cf4ad858e59237642bf6b8be1fe6f19cb090799ff00e4c2643768d73e8ebe"},
 ]
 six = [
     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
@@ -2018,12 +2291,13 @@ stdlib-list = [
     {file = "stdlib_list-0.8.0-py3-none-any.whl", hash = "sha256:2ae0712a55b68f3fbbc9e58d6fa1b646a062188f49745b495f94d3310a9fdd3e"},
 ]
 stevedore = [
-    {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
-    {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
+    {file = "stevedore-4.0.0-py3-none-any.whl", hash = "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8"},
+    {file = "stevedore-4.0.0.tar.gz", hash = "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786"},
 ]
 tabulate = [
-    {file = "tabulate-0.8.9-py3-none-any.whl", hash = "sha256:d7c013fe7abbc5e491394e10fa845f8f32fe54f8dc60c6622c6cf482d25d47e4"},
-    {file = "tabulate-0.8.9.tar.gz", hash = "sha256:eb1d13f25760052e8931f2ef80aaf6045a6cceb47514db8beab24cded16f13a7"},
+    {file = "tabulate-0.8.10-py3-none-any.whl", hash = "sha256:0ba055423dbaa164b9e456abe7920c5e8ed33fcc16f6d1b2f2d152c8e1e8b4fc"},
+    {file = "tabulate-0.8.10-py3.8.egg", hash = "sha256:436f1c768b424654fce8597290d2764def1eea6a77cfa5c33be00b1bc0f4f63d"},
+    {file = "tabulate-0.8.10.tar.gz", hash = "sha256:6c57f3f3dd7ac2782770155f3adb2db0b1a269637e42f27599925e64b114f519"},
 ]
 tbump = [
     {file = "tbump-6.9.0-py3-none-any.whl", hash = "sha256:683eab2e5a4d4861b6928c422d9e51e1d3aeccbbd69d0281fab2c374345e1d9f"},
@@ -2042,28 +2316,28 @@ tomli = [
     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
 ]
 tomlkit = [
-    {file = "tomlkit-0.11.0-py3-none-any.whl", hash = "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1"},
-    {file = "tomlkit-0.11.0.tar.gz", hash = "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd"},
+    {file = "tomlkit-0.11.1-py3-none-any.whl", hash = "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5"},
+    {file = "tomlkit-0.11.1.tar.gz", hash = "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e"},
 ]
 types-pillow = [
-    {file = "types-Pillow-9.0.19.tar.gz", hash = "sha256:bad0de01fd2b6cfdcfcab580fc4025db2b5068e6237707d8f2f4493cd4c4fe16"},
-    {file = "types_Pillow-9.0.19-py3-none-any.whl", hash = "sha256:34f8380d9e5367baa075e3ef2961c65908f6b69b9161c2b08feb8937200aa25c"},
+    {file = "types-Pillow-9.2.0.tar.gz", hash = "sha256:6823851e179dcc157424175b5dc0e1204b1c949e1de32417ff2fbfa7e3d3f45b"},
+    {file = "types_Pillow-9.2.0-py3-none-any.whl", hash = "sha256:f367d22b54239b09607fcd8d4514b86bac6bf7d6ed1d5bdfa41782ea62083b2a"},
 ]
 types-requests = [
-    {file = "types-requests-2.27.30.tar.gz", hash = "sha256:ca8d7cc549c3d10dbcb3c69c1b53e3ffd1270089c1001a65c1e9e1017eb5e704"},
-    {file = "types_requests-2.27.30-py3-none-any.whl", hash = "sha256:b9b6cd0a6e5d500e56419b79f44ec96f316e9375ff6c8ee566c39d25e9612621"},
+    {file = "types-requests-2.28.5.tar.gz", hash = "sha256:ac618bfefcb3742eaf97c961e13e9e5a226e545eda4a3dbe293b898d40933ad1"},
+    {file = "types_requests-2.28.5-py3-none-any.whl", hash = "sha256:98ab647ae88b5e2c41d6d20cfcb5117da1bea561110000b6fdeeea07b3e89877"},
 ]
 types-toml = [
-    {file = "types-toml-0.10.7.tar.gz", hash = "sha256:a567fe2614b177d537ad99a661adc9bfc8c55a46f95e66370a4ed2dd171335f9"},
-    {file = "types_toml-0.10.7-py3-none-any.whl", hash = "sha256:05a8da4bfde2f1ee60e90c7071c063b461f74c63a9c3c1099470c08d6fa58615"},
+    {file = "types-toml-0.10.8.tar.gz", hash = "sha256:b7e7ea572308b1030dc86c3ba825c5210814c2825612ec679eb7814f8dd9295a"},
+    {file = "types_toml-0.10.8-py3-none-any.whl", hash = "sha256:8300fd093e5829eb9c1fba69cee38130347d4b74ddf32d0a7df650ae55c2b599"},
 ]
 types-urllib3 = [
-    {file = "types-urllib3-1.26.15.tar.gz", hash = "sha256:c89283541ef92e344b7f59f83ea9b5a295b16366ceee3f25ecfc5593c79f794e"},
-    {file = "types_urllib3-1.26.15-py3-none-any.whl", hash = "sha256:6011befa13f901fc934f59bb1fd6973be6f3acf4ebfce427593a27e7f492918f"},
+    {file = "types-urllib3-1.26.17.tar.gz", hash = "sha256:73fd274524c3fc7cd8cd9ceb0cb67ed99b45f9cb2831013e46d50c1451044800"},
+    {file = "types_urllib3-1.26.17-py3-none-any.whl", hash = "sha256:0d027fcd27dbb3cb532453b4d977e05bc1e13aefd70519866af211b3003d895d"},
 ]
 typing-extensions = [
-    {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
-    {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
+    {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
+    {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
 ]
 uc-micro-py = [
     {file = "uc-micro-py-1.0.1.tar.gz", hash = "sha256:b7cdf4ea79433043ddfe2c82210208f26f7962c0cfbe3bacb05ee879a7fdb596"},
@@ -2074,58 +2348,54 @@ unidecode = [
     {file = "Unidecode-1.3.4.tar.gz", hash = "sha256:8e4352fb93d5a735c788110d2e7ac8e8031eb06ccbfe8d324ab71735015f9342"},
 ]
 urllib3 = [
-    {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
-    {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
+    {file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"},
+    {file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"},
 ]
 virtualenv = [
-    {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"},
-    {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"},
+    {file = "virtualenv-20.16.1-py2.py3-none-any.whl", hash = "sha256:bde925b831f36053a0fa7a468ca337dee26851c9f0bfc3d72a79d534703102d2"},
+    {file = "virtualenv-20.16.1.tar.gz", hash = "sha256:6cc42cad4d1a15c7ea5ed68e602eb49cc243b52d2eead36e577555cb56bf8705"},
 ]
 viztracer = [
-    {file = "viztracer-0.15.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:ff66b52193b788c20730db2df64cb711dff9e51f8eaf468a189d8b9ac1cee59c"},
-    {file = "viztracer-0.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54850e9c50a48799bd377de4fa16163acb20ee08fe8466f061cbb87f1a5ab61d"},
-    {file = "viztracer-0.15.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:4f7fdfa3553cb91895ab238646ca3e8fdf95d5abe92b00be62e8c5abb6f09d73"},
-    {file = "viztracer-0.15.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de40d208462e958f9f8cd9a5259af8b35a8a4d16d167704f6a488710cc118d51"},
-    {file = "viztracer-0.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1ba8111f647f33eeae5272e537696a28b4c4db189ba4d955c1e174ee806ec50"},
-    {file = "viztracer-0.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f201b2b3aad260888798b509f28eff7d538c1b47421e02fb39fec8b831e0141b"},
-    {file = "viztracer-0.15.2-cp310-cp310-win32.whl", hash = "sha256:c680bfd5f1793e025b392bbc043c140c5c29412c4199a15c8885927a2793816d"},
-    {file = "viztracer-0.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:9161c94aee48a7328c4b0fe91673d6ee894fdcdf84f94b6a3e9d145738177d50"},
-    {file = "viztracer-0.15.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:31d4342e56e69ad38b02298051ceb4f37e5491867fa11b82aeae9015e81690a7"},
-    {file = "viztracer-0.15.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc50f79b4f56279c9acf13d3febc49bfeb74deb0c63a687b7f98935afd9371f4"},
-    {file = "viztracer-0.15.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:cb54513dd7689f37e78f4b97d8b0b6ddb0eb9e3dffcbb072d8d23208e6a25435"},
-    {file = "viztracer-0.15.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdeb778b8d9be543b1c023c3af659d2dc078dc869d3d7c8e91f7fa62a378e28a"},
-    {file = "viztracer-0.15.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97c867724828d954762cd0c6454bfd1d202cd25900b9a7a744a0a04d6e19908c"},
-    {file = "viztracer-0.15.2-cp36-cp36m-win32.whl", hash = "sha256:b2e60a821175680059855ee70e4a117046441533efc929cb5cc77e13216932d3"},
-    {file = "viztracer-0.15.2-cp36-cp36m-win_amd64.whl", hash = "sha256:c7f3229ff68576d484ecc2708f06524c862f30a8aeebd6eb2502aee5042df304"},
-    {file = "viztracer-0.15.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:23dd0d08901e10a43a47fa1de9743f1e10c2368309b2380a7a0e12a16bb0b130"},
-    {file = "viztracer-0.15.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f21d6f822fe79d7aff66d4ddda21579d2710f65df63908794608773c56b8066"},
-    {file = "viztracer-0.15.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:95c86408c1977d56c2ac40fcba7521cad7fd11b88bc425d0c0a0fdc3306903ef"},
-    {file = "viztracer-0.15.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:979eb8eacf07b9d0d9f25529b5c4d7516acad79673b1e0c3ccd7f6f4e8cb5eb5"},
-    {file = "viztracer-0.15.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efce535747832d094cea2f7dd6449d443f28739a85e62274c7f52b7f802daa1d"},
-    {file = "viztracer-0.15.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:197036e8e1e640b3c34888a20c2023f1f1ef95299ea8d546695d8e5967ba4c0d"},
-    {file = "viztracer-0.15.2-cp37-cp37m-win32.whl", hash = "sha256:7a17bbd21c064faef3952874258af874e9d24772ed8a8a165d479dbdd98500bb"},
-    {file = "viztracer-0.15.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b1b1fa061dd00a4e2571fd34b48771683370a12b4b16e60bf77015a951bcf7bf"},
-    {file = "viztracer-0.15.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e0a9eea55588be965d6a1fdebc11ce1aa66f95275116beaef815ff7819110cc9"},
-    {file = "viztracer-0.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e189e0050778b90c6a92158d07c22b4008089ea80fdf34b2ffbff1fa979fe05"},
-    {file = "viztracer-0.15.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:4e295925525d8442531287676c6c43f99be7825efd07e2bbe643ac5800a90424"},
-    {file = "viztracer-0.15.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76e0b6f405ed8dc2d8bdda4d37acdfa1eaa3bd981e3ea4ba775e4b9045707f0f"},
-    {file = "viztracer-0.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc41e10dc833539d0bbcf11825a7fe8b2705dd9f3ce530105113329779c553a"},
-    {file = "viztracer-0.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e410cc46369d93ad702b334ab75f5578f7ef75656a8be7875cb8e9e58deec1d8"},
-    {file = "viztracer-0.15.2-cp38-cp38-win32.whl", hash = "sha256:1f41b8adc0a3d093b3d152b602bad3bdb8e1e27fd7abbc4e0b3e2196d59d7eac"},
-    {file = "viztracer-0.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:e11d802bdc2edd501c84117246c7f1f767db4e5b1659e3816e2fe52471d9509d"},
-    {file = "viztracer-0.15.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:2c2d0cf2c42d2bb2cc0d793639ea296a857cdfe16f58bc768fe63e59062ba39f"},
-    {file = "viztracer-0.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a36bae2079cc253e0f6e565ac732fdfdffa032ac4fc566b9086b9418f71d948"},
-    {file = "viztracer-0.15.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:9dd6499bee5d0125c7554bf2bfe2d9b7a755a27c0a8a0f9b06d966f9f37d77cf"},
-    {file = "viztracer-0.15.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50e2baace1d80172451d579610f72664ff33cad73126856375d6f932e184dc5e"},
-    {file = "viztracer-0.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84571c6165d7bc347d0846847f76712ac9b5e928c4fe998fa12a29a2c4206963"},
-    {file = "viztracer-0.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2f92e454b25a309617c59d499f371008de19bd90429c6420c8e81d06b9522b27"},
-    {file = "viztracer-0.15.2-cp39-cp39-win32.whl", hash = "sha256:fa0754f2c177e7fd4a3e832bbdba422c2258e3d2497bc4dff84a53700d08ef36"},
-    {file = "viztracer-0.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:4ab70019ad12bad116dd6eadb0f7667551b0fa337972f4300fb78967148839de"},
-    {file = "viztracer-0.15.2.tar.gz", hash = "sha256:3833b7f49b6ff0d1133777955ef98d7f542e15041da6156c74179060a9e5996c"},
+    {file = "viztracer-0.15.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1ae9c70ea45f6d56faab89f46e387e31c5e20484b024cbf8cb4542140f131060"},
+    {file = "viztracer-0.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5799fc9c284047030f6de1448ef9681782ffb49f4e54ce3f9d890dd214436991"},
+    {file = "viztracer-0.15.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:7fad5c50857c4ed0c7b3a43c867c3e79d148ef173ec35a3019eeb9ade032ac2a"},
+    {file = "viztracer-0.15.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:871b29f74155189e160e9d3849a30a476cd398ca2e823e09ab4fd571edaee588"},
+    {file = "viztracer-0.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a55e5851e292d3b110d08612f19fe0f0a92105ab717e95582ff910c9b29fc424"},
+    {file = "viztracer-0.15.3-cp310-cp310-win32.whl", hash = "sha256:d4a855370d309b529b38684a63adb118a1afa8f407d988db8396e052059d1ade"},
+    {file = "viztracer-0.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:ee03edbd153b315e126bc6f5e13965c4926735f0762d3a76bf7414c7ded8c047"},
+    {file = "viztracer-0.15.3-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:d30a0f5b0794fa68fd3dae9de9131d925b24d6b39826c5f421b0871417e59ab4"},
+    {file = "viztracer-0.15.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb127260dc9ce12d594500852052b4936e1f5b199abedea1a86d6853c943337b"},
+    {file = "viztracer-0.15.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:111e5d2f9bebb328987abbde23e6b649260bf6965d01ba14e566f5beb03e3333"},
+    {file = "viztracer-0.15.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4282210f6fe4bbcd0ef6a52e28e3b016d6058b3f8b2b3cd529360c2dedeb55"},
+    {file = "viztracer-0.15.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9006f8cc4ab7f79be92c42b6af6c0c4d6058a3a1402c1f6985834ff4b8e54ff1"},
+    {file = "viztracer-0.15.3-cp36-cp36m-win32.whl", hash = "sha256:670aea21f07a89b991ba684fc646276182a7bda012e47ae1cf8adad17d6e44f4"},
+    {file = "viztracer-0.15.3-cp36-cp36m-win_amd64.whl", hash = "sha256:4998f252fc1b2f1221521537b73777716a8b3591548d0a82d80dfbea5cbe55fe"},
+    {file = "viztracer-0.15.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:7f72ed27ee847dc840835cca74211086a9a99dc4f5d4e74d12d5b11ecf462f66"},
+    {file = "viztracer-0.15.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:924e5e5a01fde11e27c5d631c6a35c57a44927b9dfbe4786470fadeb922c38ba"},
+    {file = "viztracer-0.15.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:86bad516a3709ec278d894b2530b84dfbbbdcfb1d09f43bdaef586e7d17c39ed"},
+    {file = "viztracer-0.15.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:082c07fb5c0b6df016f7209df0f351d67fb0d94a2b7478c638f6913897fe424c"},
+    {file = "viztracer-0.15.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f843f9482d7b52c51e606023b649ef82c5dc6b22611d024d85cf07b4e0e573c"},
+    {file = "viztracer-0.15.3-cp37-cp37m-win32.whl", hash = "sha256:c202e5c9a841766aad2be240edb2256d8dac3f69005d608d357319abea412d2b"},
+    {file = "viztracer-0.15.3-cp37-cp37m-win_amd64.whl", hash = "sha256:51d39a405295af404bf3fc8bbc68baa05940cff7b29742cd8df7fb0bfc9b8b30"},
+    {file = "viztracer-0.15.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:54f51c08f8d53b86bbb8d2bbdbaf4b56c797d077952185e38980811333facb3e"},
+    {file = "viztracer-0.15.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9acfa872af1d9282f3c7999ee56a9d981e901ba795d6a87e69da9f17ded398"},
+    {file = "viztracer-0.15.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:ae833b1000c2c9e2272898459bd09ca45cbab66281e632eee96f3e07bfb2b25e"},
+    {file = "viztracer-0.15.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c90d94f2f38d508a62cb6c3c802344ef2f250ae3b236d13c89dc093cd1f492f5"},
+    {file = "viztracer-0.15.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6c99923ba13dda455cb6324500c3917262007277f3c04b603e27fbf6579d553"},
+    {file = "viztracer-0.15.3-cp38-cp38-win32.whl", hash = "sha256:f5988e6a6437890420a067ba74e3b315911674816d5e9ef523d3dbe7bd2f8419"},
+    {file = "viztracer-0.15.3-cp38-cp38-win_amd64.whl", hash = "sha256:a27bd61f8a860e0e0f457b4d3efbd65054e3204779f47c812fde18b47c862627"},
+    {file = "viztracer-0.15.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:7b34ec770f30014e929616b2e6da10de04d13fd0fe436cc25ef332b74730f90a"},
+    {file = "viztracer-0.15.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d07ebb2cc225a26070fa2a0415b6112330a213d6aa9110850116c59680a9f90d"},
+    {file = "viztracer-0.15.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.manylinux_2_24_i686.whl", hash = "sha256:a502382413997e95ffea2f03e3809d31f28a2e6ae2ccbfc6bc5e291a07d0a8d4"},
+    {file = "viztracer-0.15.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30e0b520e7eed63c46a45a65b463c669da883bca9819a0bd7f1ff3c6cd92523b"},
+    {file = "viztracer-0.15.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271817e017d35090fa0838992da32530be2591f2ca46353e05d59254d57db083"},
+    {file = "viztracer-0.15.3-cp39-cp39-win32.whl", hash = "sha256:b24eb667f05990016b08a892a110bb61bd3642dd008473b34a2b2a2166b36a63"},
+    {file = "viztracer-0.15.3-cp39-cp39-win_amd64.whl", hash = "sha256:4280b59d699ed5aec175eb3c825e494779b6501d59cc6281195efe4ab4bfa812"},
+    {file = "viztracer-0.15.3.tar.gz", hash = "sha256:f28de150304c300b27b3335993e0bdc47f5a7ba7b6f8c43dc54c4e74efa32cd6"},
 ]
 vulture = [
-    {file = "vulture-2.4-py2.py3-none-any.whl", hash = "sha256:25acfcacc24884e4344c13601ff43bbfa59faa9cdf330ccce6f4a09c49a2057c"},
-    {file = "vulture-2.4.tar.gz", hash = "sha256:819439294a76b4e0b8e08c70d75565a8ce3dc1f6e03558ed123a5f2bb737c0ea"},
+    {file = "vulture-2.5-py2.py3-none-any.whl", hash = "sha256:a7c7e7a23b11e78840fdd821509d05a6134aa9fd60418fe39d60b3026fe698d9"},
+    {file = "vulture-2.5.tar.gz", hash = "sha256:2831694055eb2e36a09c3b7680934837102b9b6c0969206e3902d513612177c3"},
 ]
 wrapt = [
     {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
@@ -2194,6 +2464,6 @@ wrapt = [
     {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
 ]
 zipp = [
-    {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
-    {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
+    {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"},
+    {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"},
 ]
diff --git a/pyproject.toml b/pyproject.toml
index 64f0d8ad..6072c4ab 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -25,39 +25,41 @@ normcap = "normcap.app:main"
 
 [tool.poetry.dependencies]
 python = ">=3.9,<3.11"
-PySide6-Essentials = "^6.3.0"
-jeepney = ">=0.7"
+PySide6-Essentials = "^6.3.1"
+jeepney = ">=0.8"
 pytesseract = ">=0.3.9"
-packaging = ">=21.0"
+packaging = ">=21.3"
 
 [tool.poetry.dev-dependencies]
 black = ">=22.3.0"
 isort = ">=5.10.1"
-mypy = ">=0.960"
+mypy = ">=0.961"
 pre-commit = ">=2.19"
 pydocstyle = ">=6.1.1"
-pylint = ">=2.13.9"
+pylint = ">=2.14.1"
 pytest = ">=7.1.2"
 pytest-cov = ">=3.0.0"
-pytest-qt = ">=4.0.2"
-pytest-xvfb = ">=2.0.0"
+pytest-qt = ">=4.1.0"
 pylint-pytest = "^1.1.2"
+pytest-xvfb = "^2.0.0"
 toml = ">=0.10.2"
 mdformat-gfm = ">=0.3.5"
 coveralls = ">=3.3.1"
+coverage = { extras = ["toml"], version = "^6.4.2" }
 tbump = ">=6.9.0"
 Levenshtein = ">=0.18.1"
 rope = ">=1.1.1"
 types-toml = ">=0.10.7"
-types-requests = ">=2.27.29"
+types-requests = ">=2.27.30"
 types-Pillow = ">=9.0.19"
 pydeps = ">=1.10.18"
-bandit = "^1.7.4"
-briefcase = ">=0.3.7"
-safety = "^1.10.3"
+bandit = ">=1.7.4"
+briefcase = "^0.3.8"
+safety = ">=1.10.3"
 radon = { version = ">=5.1.0", optional = true }
-viztracer = { version = ">=0.15.2", optional = true }
+viztracer = { version = ">=0.15.3", optional = true }
 vulture = { version = "^2.4", optional = true }
+Nuitka = "^0.9.6"
 
 [tool.poetry.extras]
 analysis = ["radon", "vistracer", "vulture"]
@@ -116,13 +118,14 @@ convention = "google"
 add-ignore = "D107,D104,D103,D100,D105"
 
 [tool.pytest.ini_options]
-#addopts = "--cov normcap --cov-report xml:cov.xml --cov-report html"
 testpaths = ["src/tests"]
 qt_api = "pyside6"
-markers = ["skip_on_gh: do not run during CI/CD on github"]
 xvfb_width = 1920
 xvfb_height = 1080
 
+[tool.coverage.run]
+source = ["normcap"]
+
 [build-system]
 requires = ["poetry-core>=1.0.0", "briefcase"]
 build-backend = "poetry.core.masonry.api"
@@ -140,17 +143,17 @@ author_email = "dynobo@mailbox.org"
 formal_name = "NormCap"
 description = "OCR-powered screen-capture tool to capture information instead of images"
 sources = ["src/normcap"]
-icon = "src/normcap/resources/normcap"
-installer_icon = "src/normcap/resources/normcap_install"
-installer_background = "src/normcap/resources/normcap_install_bg"
+icon = "package/imgs/normcap"
+installer_icon = "package/imgs/normcap_install"
+installer_background = "package/imgs/normcap_install_bg"
 requires = ["pyside6", "jeepney", "pytesseract", "packaging"]
 
 [tool.briefcase.app.normcap.macOS]
 requires = ["std-nslog==1.0.0"]
 
 [tool.briefcase.app.normcap.linux]
-requires = ["Pillow==7.2.0"]
-system_requires = ["tesseract-ocr", "pkg-config", "libtiff-dev"]
+requires = ["Pillow==9.2.0"]
+system_requires = ["tesseract-ocr", "pkg-config", "libtiff-dev", "libfuse2"]
 
 [tool.briefcase.app.normcap.windows]
 
@@ -191,6 +194,10 @@ search = 'NormCap-{current_version}-'
 src = "README.md"
 search = 'download/v{current_version}/'
 
+[[tool.tbump.file]]
+src = "build/normcap.wxs"
+search = 'ProductVersion = "{current_version}"'
+
 [[tool.tbump.before_commit]]
 name = "check changelog"
 cmd = "grep -q {new_version} CHANGELOG.md"
diff --git a/script.js b/script.js
deleted file mode 100644
index b88f0991..00000000
--- a/script.js
+++ /dev/null
@@ -1,8 +0,0 @@
-
-    client = workspace.activeClient;
-    client.geometry = {
-        x: 0,
-        y: 0+10,
-        width: 1920,
-        height: 984
-    };
diff --git a/src/normcap/app.py b/src/normcap/app.py
index 9e6e74fa..9cdb7955 100644
--- a/src/normcap/app.py
+++ b/src/normcap/app.py
@@ -1,5 +1,4 @@
 """Main application entry point."""
-
 import locale
 import logging
 import os
@@ -14,9 +13,9 @@
 from normcap import __version__
 from normcap.gui import system_info, utils
 from normcap.gui.tray import SystemTray
-from normcap.utils import create_argparser, set_environ_for_briefcase
+from normcap.utils import create_argparser, set_environ_for_prebuild_package
 
-set_environ_for_briefcase()
+set_environ_for_prebuild_package()
 
 logging.basicConfig(
     format="%(asctime)s - %(levelname)-7s - %(name)s:%(lineno)d - %(message)s",
@@ -51,7 +50,7 @@ def main():
     # Wrap QT logging output
     QtCore.qInstallMessageHandler(utils.qt_log_wrapper)
 
-    if system_info.is_briefcase_package():
+    if system_info.is_prebuild_package():
         utils.copy_tessdata_files_to_config_dir()
 
     app = QtWidgets.QApplication(sys.argv)
@@ -62,4 +61,8 @@ def main():
     tray = SystemTray(app, vars(args))
     tray.setVisible(True)
 
-    sys.exit(app.exec_())
+    sys.exit(app.exec())
+
+
+if __name__ == "__main__":
+    main()
diff --git a/src/normcap/gui/notifier.py b/src/normcap/gui/notifier.py
index c459b149..7dc58506 100644
--- a/src/normcap/gui/notifier.py
+++ b/src/normcap/gui/notifier.py
@@ -27,17 +27,13 @@ def __init__(self, parent):
     def send_notification(self, capture: Capture):
         """Show tray icon then send notification."""
         logger.debug("Send notification")
-        on_windows = sys.platform == "win32"
-        icon_file = "normcap.png" if on_windows else "tray.png"
+        icon_file = "normcap.png" if sys.platform == "win32" else "tray.png"
         notification_icon = get_icon(icon_file, "tool-magic-symbolic")
 
         title, message = self.compose_notification(capture)
         self.parent().show()
         self.parent().showMessage(title, message, notification_icon)
-
-        # Delay quit or hide to get notification enough time to show up.
-        delay = 5000 if sys.platform == "win32" else 500
-        QtCore.QTimer.singleShot(delay, self.com.on_notification_sent.emit)
+        self.com.on_notification_sent.emit()
 
     @staticmethod
     def compose_notification(capture) -> tuple[str, str]:
diff --git a/src/normcap/gui/settings_menu.py b/src/normcap/gui/settings_menu.py
index 0fb9687a..0ae4ff00 100644
--- a/src/normcap/gui/settings_menu.py
+++ b/src/normcap/gui/settings_menu.py
@@ -217,7 +217,7 @@ def _add_languages_section(self, menu):
             action.setChecked(language in self.settings.value("language"))
             language_menu.addAction(action)
 
-        if system_info.is_briefcase_package():
+        if system_info.is_prebuild_package():
             action = QtGui.QAction("... open data folder", menu)
             traineddata_path = system_info.config_directory() / "tessdata"
             action.setObjectName(f"file:///{traineddata_path.resolve()}")
diff --git a/src/normcap/gui/system_info.py b/src/normcap/gui/system_info.py
index b880c2e5..d34d0515 100644
--- a/src/normcap/gui/system_info.py
+++ b/src/normcap/gui/system_info.py
@@ -5,6 +5,7 @@
 import sys
 from importlib import metadata
 from pathlib import Path
+from typing import Optional
 
 from PySide6 import QtCore, QtGui, QtWidgets
 from PySide6 import __version__ as PySide6_version
@@ -16,6 +17,23 @@
 logger = logging.getLogger(__name__)
 
 
+def get_resources_path() -> Path:
+    return (Path(__file__).parent.parent / "resources").resolve()
+
+
+def is_prebuild_package() -> Optional[str]:
+    package = sys.modules["__main__"].__package__
+    if package and "Briefcase-Version" in metadata.metadata(package):
+        # Briefcase package
+        return "briefcase"
+
+    if hasattr(sys.modules["__main__"], "__compiled__"):
+        # Nuitka package
+        return "nuitka"
+
+    return None
+
+
 @functools.cache
 def display_manager_is_wayland() -> bool:
     """Identify relevant display managers (Linux)."""
@@ -67,13 +85,6 @@ def screens() -> dict[int, Screen]:
     return screens_dict
 
 
-def is_briefcase_package() -> bool:
-    """Check if script is executed in briefcase package."""
-    if app_module := sys.modules["__main__"].__package__:
-        return "Briefcase-Version" in metadata.metadata(app_module)
-    return False
-
-
 def config_directory() -> Path:
     """Retrieve platform specific configuration directory."""
     postfix = "normcap"
@@ -96,7 +107,7 @@ def get_tessdata_path() -> str:
     """Deside which path for tesseract language files to use."""
     prefix = os.environ.get("TESSDATA_PREFIX", None)
 
-    if is_briefcase_package():
+    if is_prebuild_package():
         path = config_directory() / "tessdata"
     elif prefix:
         path = Path(prefix) / "tessdata"
@@ -115,7 +126,7 @@ def to_dict() -> dict:
     """Cast all system infos to string for logging."""
     return dict(
         cli_args=" ".join(sys.argv),
-        is_briefcase_package=is_briefcase_package(),
+        is_prebuild_package=is_prebuild_package(),
         platform=sys.platform,
         pyside6_version=PySide6_version,
         qt_version=QtCore.qVersion(),
@@ -127,6 +138,7 @@ def to_dict() -> dict:
             "TESSERACT_CMD": os.environ.get("TESSERACT_CMD", None),
             "TESSERACT_VERSION": os.environ.get("TESSERACT_VERSION", None),
             "TESSDATA_PREFIX": os.environ.get("TESSDATA_PREFIX", None),
+            "LD_LIBRARY_PATH": os.environ.get("LD_LIBRARY_PATH", None),
         },
         desktop_environment=desktop_environment(),
         display_manager_is_wayland=display_manager_is_wayland(),
diff --git a/src/normcap/gui/tray.py b/src/normcap/gui/tray.py
index 8a890c5e..e0451d4d 100644
--- a/src/normcap/gui/tray.py
+++ b/src/normcap/gui/tray.py
@@ -2,8 +2,10 @@
 import io
 import logging
 import os
+import sys
 import tempfile
 import time
+from functools import partial
 
 from PIL import Image
 from PySide6 import QtCore, QtGui, QtWidgets
@@ -89,7 +91,7 @@ def _set_signals(self):
 
     def _add_update_checker(self):
         if self.settings.value("update", type=bool):
-            checker = UpdateChecker(self, packaged=system_info.is_briefcase_package())
+            checker = UpdateChecker(self, packaged=system_info.is_prebuild_package())
             checker.com.on_version_retrieved.connect(checker.show_update_message)
             checker.com.on_click_get_new_version.connect(self.com.on_open_url_and_hide)
             QtCore.QTimer.singleShot(500, checker.check)
@@ -263,6 +265,13 @@ def _close_windows(self):
     def _close_or_exit(self, reason: str):
         if self.settings.value("tray", type=bool):
             self._close_windows()
+        elif reason == "notification sent" and sys.platform == "win32":
+            # Hide but delay exit to give notification enough time to show up.
+            self._close_windows()
+            delayed_exit = partial(
+                self._exit_application, reason="notification sent delaying exit"
+            )
+            QtCore.QTimer.singleShot(5000, delayed_exit)
         else:
             self._exit_application(reason)
 
diff --git a/src/normcap/gui/utils.py b/src/normcap/gui/utils.py
index 5b7ab6b5..064ffde9 100644
--- a/src/normcap/gui/utils.py
+++ b/src/normcap/gui/utils.py
@@ -10,7 +10,6 @@
 import sys
 import tempfile
 import traceback
-from importlib import resources
 from pathlib import Path
 from typing import Optional
 
@@ -26,7 +25,7 @@
 
 from normcap.gui import system_info
 from normcap.gui.constants import URLS
-from normcap.gui.models import Capture, CaptureMode, DesktopEnvironment
+from normcap.gui.models import Capture, DesktopEnvironment
 from normcap.ocr.models import OcrResult
 
 logger = logging.getLogger(__name__)
@@ -235,10 +234,9 @@ def get_icon(icon_file: str, system_icon: Optional[str] = None) -> QtGui.QIcon:
     if system_icon and QtGui.QIcon.hasThemeIcon(system_icon):
         return QtGui.QIcon.fromTheme(system_icon)
 
+    icon_path = system_info.get_resources_path() / icon_file
     icon = QtGui.QIcon()
-    with resources.path("normcap.resources", icon_file) as icon_path:
-        icon.addFile(str(icon_path.resolve()))
-
+    icon.addFile(str(icon_path.resolve()))
     return icon
 
 
@@ -257,9 +255,10 @@ def copy_tessdata_files_to_config_dir():
     if list(tessdata_path.glob("*.traineddata")):
         return
 
-    resource_path = Path(resources.files("normcap.resources"))
-    traineddata_files = list((resource_path / "tessdata").glob("*.traineddata"))
-    doc_files = list((resource_path / "tessdata").glob("*.txt"))
+    traineddata_files = list(
+        (system_info.get_resources_path() / "tessdata").glob("*.traineddata")
+    )
+    doc_files = list((system_info.get_resources_path() / "tessdata").glob("*.txt"))
 
     logger.info("Copy %s traineddata files to config directory", len(traineddata_files))
     tessdata_path.mkdir(parents=True, exist_ok=True)
diff --git a/src/normcap/ocr/enhance.py b/src/normcap/ocr/enhance.py
index 1207657d..2d505de7 100644
--- a/src/normcap/ocr/enhance.py
+++ b/src/normcap/ocr/enhance.py
@@ -9,7 +9,7 @@
 logger = logging.getLogger(__name__)
 
 
-def _identify_most_frequent_edge_color(img: Image.Image) -> tuple:
+def _identify_most_frequent_edge_color(img: Image.Image) -> tuple[int, int, int]:
     """Heuristically find color for padding."""
     # Top and bottom edge
     edge_colors = [img.getpixel((x, 0)) for x in range(img.width)]
@@ -54,7 +54,7 @@ def resize_image(image: Image.Image, factor: float = 3.2) -> Image.Image:
     logger.debug("Resize screenshot by factor %s", factor)
     return image.resize(
         size=(int(image.width * factor), int(image.height * factor)),
-        resample=Image.ANTIALIAS,
+        resample=Image.Resampling.LANCZOS,  # type: ignore
     )
 
 
diff --git a/src/normcap/ocr/magics/base_magic.py b/src/normcap/ocr/magics/base_magic.py
index 61b44872..6c7efa39 100644
--- a/src/normcap/ocr/magics/base_magic.py
+++ b/src/normcap/ocr/magics/base_magic.py
@@ -1,13 +1,15 @@
 """Base class for templating magics."""
+import abc
 
 from normcap.ocr.models import OcrResult
 
 # pylint: disable=unused-argument
 
 
-class BaseMagic:
+class BaseMagic(abc.ABC):
     """Base Class to be instantiated."""
 
+    @abc.abstractmethod
     def score(self, ocr_result: OcrResult) -> float:
         """Calculate the score of a magic.
 
@@ -20,8 +22,8 @@ def score(self, ocr_result: OcrResult) -> float:
         Returns:
             float -- score between 0-100 (100 = more likely)
         """
-        return 0.0
 
+    @abc.abstractmethod
     def transform(self, ocr_result: OcrResult) -> str:
         """Transform detected lineboxes into single(!) string.
 
@@ -31,4 +33,3 @@ def transform(self, ocr_result: OcrResult) -> str:
         Returns:
             str -- String to be copied to clipboard
         """
-        return ""
diff --git a/src/normcap/resources/tesseract/.keep b/src/normcap/resources/tesseract/.keep
new file mode 100644
index 00000000..119ebe44
--- /dev/null
+++ b/src/normcap/resources/tesseract/.keep
@@ -0,0 +1,1 @@
+# This folder will be filled with the language data for tesseract during build
diff --git a/src/normcap/utils.py b/src/normcap/utils.py
index 64addb4d..f86b1f82 100644
--- a/src/normcap/utils.py
+++ b/src/normcap/utils.py
@@ -1,8 +1,8 @@
 import argparse
 import os
 import sys
-from importlib import metadata, resources
 
+from normcap.gui import system_info
 from normcap.gui.constants import DEFAULT_SETTINGS, DESCRIPTION
 
 
@@ -36,34 +36,45 @@ def create_argparser() -> argparse.ArgumentParser:
     return parser
 
 
-# Some overrides when running in briefcase package
-def set_environ_for_briefcase():
-    package = sys.modules["__main__"].__package__
-    if package and "Briefcase-Version" in metadata.metadata(package):
-        if sys.platform == "linux":
-            # Use bundled tesseract binary
-            with resources.as_file(resources.files("normcap")) as normcap_path:
-                tesseract_path = normcap_path.parent.parent / "bin" / "tesseract"
-                os.environ["TESSERACT_CMD"] = str(tesseract_path.resolve())
+# Some overrides when running in prebuild package
+def set_environ_for_prebuild_package():
 
-        if sys.platform == "darwin":
-            # Use bundled tesseract binary
-            with resources.as_file(resources.files("normcap")) as normcap_path:
-                tesseract_path = (
-                    normcap_path.parent.parent / "app_packages" / "tesseract"
-                )
-                os.environ["TESSERACT_CMD"] = str(tesseract_path.resolve())
+    package = system_info.is_prebuild_package()
 
-        elif sys.platform == "win32":
-            with resources.as_file(
-                resources.files("normcap.resources")
-            ) as resource_path:
-                # TODO: Check if this is still necessary:
-                # Add openssl shipped with briefcase package to path
-                openssl_path = resource_path / "openssl"
-                os.environ["PATH"] += os.pathsep + str(openssl_path.resolve())
+    if package is None:
+        return
 
-                # Use bundled tesseract binary
-                tesseract_path = resource_path / "tesseract" / "tesseract.exe"
-                os.environ["TESSERACT_CMD"] = str(tesseract_path.resolve())
-                os.environ["TESSERACT_VERSION"] = "5.0.0"
+    if sys.platform == "linux":
+        # resources are currently not resolved on linux by nuitka:
+        # https://github.com/Nuitka/Nuitka/issues/1451
+        # Workround with using __file__
+        if package == "nuitka":
+            tesseract_path = system_info.get_resources_path() / "tesseract"
+            tesseract_bin = tesseract_path / "tesseract"
+            ld_library_path = (
+                f"{os.environ.get('LD_LIBRARY_PATH', '')}:{tesseract_path.resolve()}"
+            )
+            os.environ["LD_LIBRARY_PATH"] = ld_library_path
+            os.environ["TESSERACT_CMD"] = str(tesseract_bin.resolve())
+        elif package == "briefcase":
+            tesseract_path = (
+                system_info.get_resources_path().parent.parent.parent
+                / "bin"
+                / "tesseract"
+            )
+            os.environ["TESSERACT_CMD"] = str(tesseract_path.resolve())
+    if sys.platform == "darwin":
+        if package == "nuitka":
+            tesseract_bin = system_info.get_resources_path() / "tesseract" / "tesseract"
+        elif package == "briefcase":
+            tesseract_bin = (
+                system_info.get_resources_path().parent.parent.parent
+                / "app_packages"
+                / "tesseract"
+            )
+        os.environ["TESSERACT_CMD"] = str(tesseract_bin.resolve())
+
+    elif sys.platform == "win32":
+        tesseract_bin = system_info.get_resources_path() / "tesseract" / "tesseract.exe"
+        os.environ["TESSERACT_CMD"] = str(tesseract_bin.resolve())
+        os.environ["TESSERACT_VERSION"] = "5.0.0"


Test patch:
diff --git a/src/tests/conftest.py b/src/tests/conftest.py
index dceb4d58..143466e6 100644
--- a/src/tests/conftest.py
+++ b/src/tests/conftest.py
@@ -11,6 +11,10 @@
 from normcap.utils import create_argparser
 
 
+def pytest_configure(config):
+    config.addinivalue_line("markers", "skip_on_gh: do not run during CI/CD on github")
+
+
 @pytest.fixture(scope="session")
 def capture() -> Generator[Capture, None, None]:
     """Create argparser and provide its default values."""
diff --git a/src/tests/integration/test_normcap.py b/src/tests/integration/test_normcap.py
index 668d1919..3e6bc8c8 100644
--- a/src/tests/integration/test_normcap.py
+++ b/src/tests/integration/test_normcap.py
@@ -1,4 +1,5 @@
 import logging
+import time
 from pathlib import Path
 
 import Levenshtein
@@ -13,41 +14,49 @@
 
 logger = logging.getLogger(__name__)
 
-# Specific settings for pytest
-# pylint: disable=redefined-outer-name,protected-access,unused-argument
 
+def _check_ocr_result(normcap_tray):
+    def __check_ocr_result():
+        assert normcap_tray.capture.ocr_text
 
-@pytest.mark.parametrize(
-    "data",
-    TESTCASES,
-)
-def test_app(monkeypatch, qtbot, qapp, xvfb, data):
+    return __check_ocr_result
+
+
+def _load_test_image(image_path):
+    def __load_test_image():
+        return [QtGui.QImage(image_path.resolve())]
+
+    return __load_test_image
+
+
+def test_app(monkeypatch, qapp, qtbot):
     """Tests complete OCR workflow."""
     screen_rect = qapp.primaryScreen().size()
     if screen_rect.width() != 1920 or screen_rect.height() != 1080:
         pytest.xfail("Skipped due to wrong screen resolution.")
+    for data in TESTCASES:
+        image = Path(__file__).parent / "testcases" / data["image"]
+        monkeypatch.setattr(normcap.gui.tray, "grab_screens", _load_test_image(image))
+        args = create_argparser().parse_args(
+            ["--language=eng", "--mode=parse", "--tray=True"]
+        )
+        tray = SystemTray(None, vars(args))
 
-    test_file = Path(__file__).parent / "testcases" / data["image"]
-    test_image = QtGui.QImage(test_file.absolute())
-
-    monkeypatch.setattr(normcap.gui.tray, "grab_screens", lambda: [test_image])
-    args = create_argparser().parse_args(["--language=eng", "--mode=parse"])
-    tray = SystemTray(None, vars(args))
-    tray.show()
+        tray.show()
 
-    window = tray.windows[0]
-    qtbot.mousePress(window, QtCore.Qt.LeftButton, pos=QtCore.QPoint(*data["tl"]))
-    qtbot.mouseMove(window, pos=QtCore.QPoint(*data["br"]))
-    qtbot.mouseRelease(window, QtCore.Qt.LeftButton, pos=QtCore.QPoint(*data["br"]))
+        window = tray.windows[0]
+        qtbot.mousePress(window, QtCore.Qt.LeftButton, pos=QtCore.QPoint(*data["tl"]))
+        qtbot.mouseMove(window, pos=QtCore.QPoint(*data["br"]))
+        qtbot.mouseRelease(window, QtCore.Qt.LeftButton, pos=QtCore.QPoint(*data["br"]))
 
-    def check_ocr_result():
-        assert tray.capture.ocr_text
+        qtbot.waitUntil(_check_ocr_result(tray))
+        capture = tray.capture
 
-    qtbot.waitUntil(check_ocr_result)
-    capture = tray.capture
+        # Text output is not 100% predictable across different machines:
+        similarity = Levenshtein.ratio(capture.ocr_text, data["transformed"])
 
-    # Text output is not 100% predictable across different machines:
-    similarity = Levenshtein.ratio(capture.ocr_text, data["transformed"])
+        assert capture.ocr_applied_magic == data["ocr_applied_magic"], capture.ocr_text
+        assert similarity >= 0.98, f"{capture.ocr_text=}"
 
-    assert capture.ocr_applied_magic == data["ocr_applied_magic"], capture.ocr_text
-    assert similarity >= 0.98, f"{capture.ocr_text=}"
+        tray.com.on_quit.emit()
+        time.sleep(0.5)
diff --git a/src/tests/integration/testcases/data.py b/src/tests/integration/testcases/data.py
index a4e1e0bf..75c17d7e 100644
--- a/src/tests/integration/testcases/data.py
+++ b/src/tests/integration/testcases/data.py
@@ -1,5 +1,6 @@
 TESTCASES = [
     {
+        "id": 0,
         "image": "ocr_test_1.png",
         "tl": (46, 745),
         "br": (500, 950),
@@ -15,6 +16,7 @@
         "ocr_applied_magic": "UrlMagic",
     },
     {
+        "id": 1,
         "image": "ocr_test_1.png",
         "tl": (312, 550),
         "br": (470, 572),
@@ -22,6 +24,7 @@
         "ocr_applied_magic": "UrlMagic",
     },
     {
+        "id": 2,
         "image": "ocr_test_1.png",
         "tl": (1115, 530),
         "br": (1305, 570),
@@ -30,6 +33,7 @@
     },
     {
         # First two rows of email addresses
+        "id": 3,
         "image": "ocr_test_1.png",
         "tl": (50, 300),
         "br": (700, 342),
@@ -38,6 +42,7 @@
     },
     {
         # All three rows of email addresses, 3rd row contains invalids
+        "id": 4,
         "image": "ocr_test_1.png",
         "tl": (50, 300),
         "br": (700, 363),
diff --git a/src/tests/test_utils.py b/src/tests/test_utils.py
index 3458d0aa..dea951dd 100644
--- a/src/tests/test_utils.py
+++ b/src/tests/test_utils.py
@@ -28,7 +28,6 @@ def test_argparser_help_is_complete():
     assert len(argparser.description) > 10
     for action in argparser._actions:  # pylint: disable=protected-access
         assert len(action.help) > 10
-    assert True
 
 
 def test_all_argparser_attributes_in_settings(argparser_defaults):
@@ -52,13 +51,12 @@ def test_argparser_defaults_are_correct(argparser_defaults):
 
 @pytest.mark.parametrize("os_str", ("linux", "win32", "darwin"))
 def test_set_environ_for_briefcase_not_packaged(monkeypatch, os_str):
-    monkeypatch.setattr(utils.metadata, "metadata", lambda _: [])
     monkeypatch.setattr(utils.sys, "platform", os_str)
 
     tesseract_cmd = os.environ.get("TESSERACT_CMD", None)
     tesseract_version = os.environ.get("TESSERACT_VERSION", None)
 
-    utils.set_environ_for_briefcase()  # pylint: disable=protected-access
+    utils.set_environ_for_prebuild_package()  # pylint: disable=protected-access
 
     assert tesseract_cmd == os.environ.get("TESSERACT_CMD", None)
     assert tesseract_version == os.environ.get("TESSERACT_VERSION", None)
@@ -74,7 +72,7 @@ def test_set_environ_for_briefcase_is_packaged(monkeypatch, os_str):
     monkeypatch.setenv("TESSERACT_CMD", "")
     monkeypatch.setenv("TESSERACT_VERSION", "")
 
-    utils.set_environ_for_briefcase()  # pylint: disable=protected-access
+    utils.set_environ_for_prebuild_package()
 
     if os_str == "win32":
         assert os.environ.get("TESSERACT_CMD").endswith("tesseract.exe")
diff --git a/src/tests/tests_gui/test_system_info.py b/src/tests/tests_gui/test_system_info.py
index 59b7877c..b8af7e9e 100644
--- a/src/tests/tests_gui/test_system_info.py
+++ b/src/tests/tests_gui/test_system_info.py
@@ -83,15 +83,15 @@ def test_desktop_environment_other(monkeypatch):
     assert system_info.desktop_environment() == models.DesktopEnvironment.OTHER
 
 
-def test_is_briefcase_package(monkeypatch):
-    assert not system_info.is_briefcase_package()
+def test_is_prebuild_package(monkeypatch):
+    assert not system_info.is_prebuild_package()
 
     monkeypatch.setattr(metadata, "metadata", lambda _: {"Briefcase-Version": "9.9.9"})
     monkeypatch.setattr(sys.modules["__main__"], "__package__", "normcap")
-    assert system_info.is_briefcase_package()
+    assert system_info.is_prebuild_package()
 
     monkeypatch.setattr(sys.modules["__main__"], "__package__", "")
-    assert not system_info.is_briefcase_package()
+    assert not system_info.is_prebuild_package()
 
 
 def test_screens():
@@ -110,14 +110,14 @@ def test_get_tessdata_path(monkeypatch, tmp_path):
     data_file.touch(exist_ok=True)
 
     try:
-        monkeypatch.setattr(system_info, "is_briefcase_package", lambda: True)
+        monkeypatch.setattr(system_info, "is_prebuild_package", lambda: True)
         path_briefcase = system_info.get_tessdata_path()
 
-        monkeypatch.setattr(system_info, "is_briefcase_package", lambda: False)
+        monkeypatch.setattr(system_info, "is_prebuild_package", lambda: False)
         monkeypatch.setenv("TESSDATA_PREFIX", str(data_file.parent.parent.resolve()))
         path_env_var = system_info.get_tessdata_path()
 
-        monkeypatch.setattr(system_info, "is_briefcase_package", lambda: False)
+        monkeypatch.setattr(system_info, "is_prebuild_package", lambda: False)
         monkeypatch.setenv("TESSDATA_PREFIX", "")
         path_non = system_info.get_tessdata_path()
     finally:
@@ -128,7 +128,7 @@ def test_get_tessdata_path(monkeypatch, tmp_path):
     assert path_non == ""
 
     # mock config dir not existing:
-    monkeypatch.setattr(system_info, "is_briefcase_package", lambda: True)
+    monkeypatch.setattr(system_info, "is_prebuild_package", lambda: True)
     monkeypatch.setattr(system_info, "config_directory", lambda: tmp_path / "nan")
     with pytest.raises(RuntimeError) as e:
         _ = system_info.get_tessdata_path()
@@ -143,7 +143,7 @@ def test_get_tessdata_path(monkeypatch, tmp_path):
 
     # mock directory but _no_ language data:
     monkeypatch.setattr(system_info, "config_directory", lambda: Path("/tmp"))
-    monkeypatch.setattr(system_info, "is_briefcase_package", lambda: True)
+    monkeypatch.setattr(system_info, "is_prebuild_package", lambda: True)
     with pytest.raises(RuntimeError):
         _ = system_info.get_tessdata_path()
 
@@ -174,7 +174,7 @@ def test_to_string():
     string = system_info.to_dict()
     expected = [
         "cli_args",
-        "is_briefcase_package",
+        "is_prebuild_package",
         "platform",
         "pyside6_version",
         "qt_version",
diff --git a/src/tests/tests_gui/test_utils.py b/src/tests/tests_gui/test_utils.py
index 81b32cd5..2233d04e 100644
--- a/src/tests/tests_gui/test_utils.py
+++ b/src/tests/tests_gui/test_utils.py
@@ -13,8 +13,6 @@
 from normcap.gui.models import Capture
 from normcap.ocr.models import OcrResult
 
-# pylint: disable=unused-argument
-
 
 def test_init_tessdata_copies_files(tmp_path, monkeypatch):
     # Create placeholder for traineddata files, if they don't exist
@@ -73,20 +71,20 @@ def test_save_image_in_tempfolder():
     assert "unittest" in str(list(png_files)[0])
 
 
-def test_get_icon_custom(qtbot):
+def test_get_icon_custom():
     icon = utils.get_icon("normcap.png")
     assert icon.name() == ""
     assert len(icon.availableSizes()) == 1
 
 
 @pytest.mark.skip_on_gh
-def test_get_icon_sytem(qtbot):
+def test_get_icon_sytem():
     icon = utils.get_icon("normcap.png", "edit-undo")
     assert icon.name() == "edit-undo"
     assert len(icon.availableSizes()) >= 1
 
 
-def test_get_icon_sytem_use_fallback(qtbot):
+def test_get_icon_sytem_use_fallback():
     icon = utils.get_icon("normcap.png", "not-existing-icon")
     assert icon.name() == ""
     assert len(icon.availableSizes()) == 1
@@ -139,7 +137,7 @@ def test_hook_exception_fails(monkeypatch, caplog):
     assert "debug output limited" in caplog.text
 
 
-def test_set_cursor(qtbot):
+def test_set_cursor():
     # I do not know how to read cursor shape. Therefor I just test that
     # no exceptions are thrown.
     utils.set_cursor()