Repository: dynobo/normcap (language: python)

Issue:
Switch to NOX and/or Hatch
Use [NOX](https://pypi.org/project/nox/) or [hatch](https://hatch.pypa.io/latest/) for things like
- [x] Linting
- [x] Testing
- [x] Formatting
- [x] l10n update tasks
- [x] Python dependency & venv management (hatch, replaces poetry)
- [x] Building (?) 
- [ ] Installing system dependencies (?)

It would be great if we could replace the duplicated test defined in
- [x] pre-commit hooks
- [x] github actions 

Also document the decision:
- [x] write ADR
 
See also:
- NOX: [Best practice](https://learn.scientific-python.org/development/guides/tasks/), [Example](https://dev.to/houseman/creating-a-great-python-devx-39c6#nox)
- Hatch: [Switching to Hatch](https://andrich.me/2023/08/switching-to-hatch/)


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml
index 2526b307..903e9d0d 100644
--- a/.github/workflows/coverage.yaml
+++ b/.github/workflows/coverage.yaml
@@ -17,12 +17,11 @@ jobs:
     steps:
       # SETUP ENVIRONMENT
       - uses: actions/checkout@v3
-      - name: Install poetry
-        run: pipx install poetry==1.6.1
+      - name: Install hatch
+        run: pipx install hatch
       - uses: actions/setup-python@v4
         with:
           python-version: "3.10"
-          cache: "poetry"
       - name: Prepare Linux
         if: matrix.os  == 'ubuntu-22.04'
         run: |
@@ -80,14 +79,12 @@ jobs:
           tesseract --version
           tesseract --list-langs
 
-      - name: Poetry install
-        run: poetry install
+      - name: Hatch env create
+        run: hatch env create
+
+      - name: Run pytest
+        run: hatch run test
 
-      # PERFORM TESTS
-      - name: Pytest
-        run: |
-          poetry run pytest
-          poetry run coverage lcov
       - name: Coveralls Parallel
         uses: coverallsapp/github-action@master
         with:
diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml
index cd1c3681..79bbfbf7 100644
--- a/.github/workflows/python.yaml
+++ b/.github/workflows/python.yaml
@@ -39,12 +39,11 @@ jobs:
         if: ${{ github.event_name == 'workflow_dispatch' }}
         with:
           ref: ${{ inputs.refToBuild }}
-      - name: Install poetry
-        run: pipx install poetry==1.6.1
+      - name: Install hatch
+        run: pipx install hatch
       - uses: actions/setup-python@v4
         with:
           python-version: "3.10"
-          cache: "poetry"
       - name: Prepare Linux
         if: matrix.os  == 'ubuntu-22.04'
         run: |
@@ -104,30 +103,12 @@ jobs:
           tesseract --version
           tesseract --list-langs
 
-      - name: Poetry install
-        run: poetry install
+      - name: Hatch env create
+        run: hatch env create
+
+      - name: Run project checks
+        run: hatch run check
 
-      # Perform tests
-      - name: Ruff
-        if: always()
-        run: poetry run ruff .
-      - name: Mypy
-        if: always()
-        run: poetry run mypy
-      - name: Black
-        if: always()
-        run: poetry run black --check --diff .
-      - name: Pip-Audit
-        if: matrix.os  == 'ubuntu-22.04'
-        run:
-          bash -c "poetry run pip-audit -r <(poetry export -f requirements.txt
-          --with=dev)"
-      # - name: Setup upterm session
-      #   if: matrix.os  == 'ubuntu-22.04'
-      - name: Pytest
-        run: poetry run pytest
-      - name: Coverage
-        run: poetry run coverage lcov
       - name: Coveralls Parallel
         uses: coverallsapp/github-action@master
         with:
@@ -139,7 +120,7 @@ jobs:
       # Build test packages
       - name: Test build briefcase package
         shell: bash -l {0}
-        run: poetry run python bundle/build.py --framework=briefcase --dev
+        run: hatch run python bundle/build.py --framework=briefcase --dev
       - name: Print briefcase log in case of error
         if: failure()
         shell: bash -l {0}
@@ -149,7 +130,7 @@ jobs:
 
       # Build
       - name: Test build python package
-        run: poetry build
+        run: hatch build
 
       # Release test package
       - name: Set current date as env variable
@@ -191,18 +172,17 @@ jobs:
         os: [ubuntu-22.04, macos-12, windows-2022]
     steps:
       - uses: actions/checkout@v3
-      - name: Install poetry
-        run: pipx install poetry==1.6.1
+      - name: Install hatch
+        run: pipx install hatch
       - uses: actions/setup-python@v4
         with:
           python-version: "3.10"
-          cache: "poetry"
       - name: Install dependencies
         shell: bash -l {0}
-        run: poetry install
+        run: hatch env create
       - name: Build package briefcase
         shell: bash -l {0}
-        run: poetry run python bundle/build.py --framework=briefcase
+        run: hatch run python bundle/build.py --framework=briefcase
       - name: Draft release
         if: github.repository == 'dynobo/normcap'
         uses: ncipollo/release-action@v1
@@ -245,13 +225,13 @@ jobs:
       contents: write
     steps:
       - uses: actions/checkout@v3
-      - name: Install poetry
-        run: pipx install poetry==1.6.1
+      - name: Install hatch
+        run: pipx install hatch
       - uses: actions/setup-python@v4
         with:
           python-version: "3.10"
       - name: Build Python package
-        run: poetry build
+        run: hatch build
       - name: Publish to PyPi
         uses: pypa/gh-action-pypi-publish@release/v1
         with:
diff --git a/.gitignore b/.gitignore
index 2b15af52..759197e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
 # Edit at https://www.gitignore.io/?templates=python
 
 # Own
-.venv/
+.virtualenvs/
 .vscode/
 .ruff_cache/
 normcap/resources/tessdata/*.traineddata
@@ -29,7 +29,10 @@ result.html
 cov.xml
 coverage
 .coverage
+coverage.lcov
+coverage.xml
 .coveralls.yml
+.envrc
 
 ### Python ###
 # Byte-compiled / optimized / DLL files
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 85bd5c7e..c764d46e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -20,73 +20,9 @@ repos:
       - id: mixed-line-ending
   - repo: local
     hooks:
-      - id: compile_locales
-        name: compile locales
+      - id: check
+        name: run project checks
         stages: [commit]
         language: system
-        entry: poetry run python l10n.py
-        pass_filenames: false
-
-      - id: mdformat
-        name: mdformat
-        stages: [commit]
-        language: system
-        entry: poetry run mdformat
-        types: [markdown]
-
-      - id: black
-        name: black
-        stages: [commit]
-        language: system
-        entry: poetry run black normcap tests/ bundle/
-        types: [python]
-
-      - id: ruff
-        name: ruff
-        stages: [commit]
-        language: system
-        entry: poetry run ruff --fix .
-        types: [python]
-        pass_filenames: false
-
-      - id: mypy
-        name: mypy
-        stages: [commit]
-        language: system
-        entry: poetry run mypy
-        types: [python]
-        pass_filenames: false
-
-      - id: pytest
-        name: pytest
-        stages: [commit]
-        language: system
-        entry: poetry run pytest tests/
-        types: [python]
-        pass_filenames: false
-
-      - id: pip-audit
-        name: pip-audit
-        stages: [commit]
-        language: system
-        entry:
-          bash -c "poetry run pip-audit --strict -r <(poetry export -f requirements.txt
-          --with=dev)"
-        pass_filenames: false
-        types: [toml]
-
-      - id: pydeps
-        name: pydeps
-        stages: [commit]
-        language: system
-        entry: poetry run pydeps normcap --max-bacon=2 -o=pydeps.png -T=png
-        types: [python]
-        pass_filenames: false
-
-      - id: pydeps-internal
-        name: pydeps-internal
-        stages: [commit]
-        language: system
-        entry: poetry run pydeps normcap --max-bacon=1 -o=pydeps_internal.png -T=png
-        types: [python]
+        entry: hatch run pre-commit
         pass_filenames: false
diff --git a/README.md b/README.md
index b8014bcf..2cb66e15 100644
--- a/README.md
+++ b/README.md
@@ -152,8 +152,11 @@ See [XKCD](https://xkcd.com):
 
 ## Development
 
-Prerequisites for setting up a development environment are: **Python >=3.9**,
-**Poetry>=1.3.2** and **Tesseract** (incl. **language data**).
+Prerequisites for setting up a development environment are:
+[**Python >=3.9**](https://www.python.org/downloads/),
+[**hatch**](https://hatch.pypa.io/latest/install/) and
+[**Tesseract >=5.0**](https://tesseract-ocr.github.io/tessdoc/#5xx) (incl. **language
+data**).
 
 ```sh
 # Clone repository
@@ -163,13 +166,13 @@ git clone https://github.com/dynobo/normcap.git
 cd normcap
 
 # Create virtual env and install dependencies
-poetry install
+hatch env create
 
 # Register pre-commit hook
-poetry run pre-commit install
+hatch run pre-commit install
 
 # Run NormCap in virtual env
-poetry run python -m normcap
+hatch run python -m normcap
 ```
 
 ## Credits
diff --git a/adr/005-use-hatch-instead-poetry.md b/adr/005-use-hatch-instead-poetry.md
new file mode 100644
index 00000000..fe7ceb4f
--- /dev/null
+++ b/adr/005-use-hatch-instead-poetry.md
@@ -0,0 +1,148 @@
+# Use hatch instead poetry
+
+- Status: accepted
+- Deciders: @dynobo
+- Date: 2023-10-27
+
+## Context and Problem Statement
+
+Currently, [poetry](https://github.com/python-poetry/poetry) is used for dependency
+management & locking, virtual environment management, and building. While in general
+this works quite well, there are some reoccurring pain points:
+
+- The scripting capabilities
+  [are limited](https://python-poetry.org/docs/pyproject#scripts).
+  - This led to duplicate implementations of tasks like formatting, linting, testing and
+    l10n for pre-commit hooks and for the GitHub actions.
+  - There are currently multiple entry points for various different tasks, e.g. Python
+    package (`poetry build`), Briefcase package (`/bundle/build.py`, babel (`l10n.py`),
+    running normcap (script `normcap`), which increases cognitive overhead.
+- Dependency resolution can be quite slow
+- Poetry does not follow PEP standards (however, no problem so far)
+
+## Decision Drivers
+
+- Maintenance efforts
+- Complexity reduction
+- Implementation efforts
+
+## Considered Options
+
+### (A) Do nothing.
+
+Stay with [poetry](https://github.com/python-poetry/poetry).
+
+### (B) Keep using [poetry](https://github.com/python-poetry/poetry) and combine it with a task-runner like [nox](https://github.com/wntrblm/nox)
+
+### (C) Switch to [nox](https://github.com/wntrblm/nox) and script tasks like building
+
+Scripts should use builtin Python's tools for building and virtual environment
+management, otherwise complexity would not be reduced.
+
+### (D) Switch to [hatch](https://github.com/pypa/hatch)
+
+## Decision Outcome
+
+**Chosen option: (D) Switch to hatch.**
+
+### Positive Consequences
+
+- Reduced complexity:
+  - Use `hatch` as _one_ tool for most tasks `poetry` supported _as well as_ simple task
+    runner.
+  - Single entrypoint to tasks (`hatch run ...`)
+- Less maintenance effort because of less duplicated code for tasks.
+- `hatch` was adopted by PyPA and therefore is future-proof and well-supported.
+- Testing a new tool (learning opportunity).
+
+### Negative Consequences
+
+- Implementation effort for transition.
+- Some integration efforts (e.g. venv activation via
+  [direnv](https://github.com/direnv/direnv) with 3rd party `layout hatch` to be used in
+  `zsh` and VSCode). Hopefully, this situation will improve over the time!
+- New tool (learning efforts).
+
+### Neutral
+
+- `hatch` does not yet support dependency locking. This is a minor issue, because:
+  - A locking feature might be added to `hatch` in midterm (needs some PEP-work, which
+    already started).
+  - Freezing is supported via 3rd party plugin
+    [hatch-pip-deepfreeze](https://github.com/sbidoul/hatch-pip-deepfreeze).
+  - In NormCap, currently the only dependencies are `PySide6` & `shiboken6`. They are
+    pinned to specific versions anyway and don't have any child-dependencies themselves.
+  - For development dependencies this is an issue, but the impact of potential problems
+    is minor.
+- It's unclear, if the scripting support is good enough to ease all required tasks.
+  - If this _is_ the case, it would be a positive consequence, as more powerful tools
+    like `nox` would bring in more complexity and onboarding efforts.
+  - If this is _not_ the case, then it would have negative consequences, because the
+    complexity would again grow because of workarounds or bringing in a task runner as
+    additional tool.
+
+## Pros and Cons of the Options
+
+### (A) Do nothing
+
+- Good, because less implementation effort.
+- Good, because dependency locking grantees coherent development environment and stable
+  builds.
+- Good, because it is widely spread and therefore has good integration support (e.g.
+  `zsh`, VSCode, GitHub actions).
+- Bad, because more maintenance effort of duplicate coded tasks.
+- Bad, because it requires more cognitive load for running tasks through multiple
+  entrypoints.
+- Bad, because the slow dependency resolution slows down a bit.
+
+### (B) Keep using poetry and combine it with a task-runner like nox
+
+**Note:** `nox` is just _one_ exemplary (and very promising) task runner. The arguments
+below very likely apply to similar tools as well.
+
+- Good, because it covers all required feature very well.
+- Good, because the scripting capabilities are great and might be a good option to unify
+  the available scripts (`l10.py`, `/bundle/..`).
+- Bad, because more tools mean more complexity.
+- Bad, because the slow dependency resolution still slows down a bit.
+- Bad, because of implementation efforts of migrating the tasks to nox.
+
+### (C) Switch to nox and script tasks like building
+
+**Note:** Tasks that are _not_ integrated in `nox` and should be implemented using
+Python standard toolings to have a good development workflow (Dependency management,
+Virtual environment management, Building).
+
+**Note:** Another option would be to do leave dependency & and venv management to the
+individual developer. (For building, this is probably not a good idea.)
+
+- Good, as it should cover and ease _all_ task scripting activities (l10n, briefcase
+  bundles, linting, etc.)
+- Good, as it offers a single entrypoint for tasks (if all are scripted!).
+- Bad, because it might mean re-implementing tasks which other tools already do quite
+  well, or relying on the individual developers to do the right things.
+
+### (D) Switch to hatch
+
+- Good, as its strict standard compliance might make it easier to also use other build
+  tools. (NormCap, doesn't really benefit from this.)
+- Good, as it offers a single entrypoint for tasks.
+- Neutral, as dependency locking is currently not PEP compliant and therefore not
+  integrate into `hatch` core. However, this is subject to change, and until it is
+  change the 3rd party plugin
+  [hatch-pip-deepfreeze](https://github.com/sbidoul/hatch-pip-deepfreeze) could be used.
+- Neutral, as it has better scripting capabilities than `poetry`, but is way less
+  flexible than task runners like `nox`. Currently, it is unclear, if those capabilities
+  are really needed.
+- Bad, because of implementation efforts during the transition.
+- Bad, because it is (not yet) as widely adopted and therefore less well integrated.
+  E.g. it takes more effort to get the following things to work:
+  - Auto-activation of environment in `zsh`.
+  - Auto-activation of environment in VSCode.
+  - Caching of environments in GitHub actions. (Caching with `poetry` is integrated in
+    the official `actions/setup-python`.)
+
+## References
+
+- [Issue #527](https://github.com/dynobo/normcap/issues/527)
+- [PR #549](https://github.com/dynobo/normcap/pull/549)
diff --git a/l10n.py b/bundle/l10n.py
similarity index 77%
rename from l10n.py
rename to bundle/l10n.py
index 5bb65118..4cd40bcd 100755
--- a/l10n.py
+++ b/bundle/l10n.py
@@ -7,16 +7,27 @@
 import subprocess
 from pathlib import Path
 
+import toml
 from babel.messages.frontend import CommandLineInterface
 
+LOCALES_PATH = Path(__file__).parent.parent / "normcap" / "resources" / "locales"
+
 
 def _get_version() -> str:
-    """Get versions string from pyproject.toml."""
-    import toml
+    """Get normcap versions string."""
+    try:
+        from normcap import __version__
+
+        version = __version__
+    except Exception:
+        print("Could not import __version__. Fallback to pyproject.toml.")  # noqa: T201
+        with (Path(__file__).parent.parent / "pyproject.toml").open(
+            encoding="utf8"
+        ) as toml_file:
+            pyproject_toml = toml.load(toml_file)
+        version = pyproject_toml["tool"]["briefcase"]["version"]
 
-    with (Path(__file__).parent / "pyproject.toml").open(encoding="utf8") as toml_file:
-        pyproject_toml = toml.load(toml_file)
-    return pyproject_toml["tool"]["poetry"]["version"]
+    return version
 
 
 def _update_coverage(lines: list[str]) -> None:
@@ -47,7 +58,7 @@ def _update_coverage(lines: list[str]) -> None:
     )
 
     # Render stats to markdown file
-    md_file = Path(__file__).parent / "normcap" / "resources" / "locales" / "README.md"
+    md_file = LOCALES_PATH / "README.md"
     md_text = md_file.read_text("utf-8")
     md_text = re.sub(
         r"(.*## Status\n).*?(##.*)",
@@ -73,7 +84,7 @@ def compile_locales() -> None:
             "compile",
             "--use-fuzzy",
             "--directory",
-            "normcap/resources/locales",
+            f"{LOCALES_PATH.resolve()}",
             "--statistics",
         ]
     )
@@ -91,8 +102,8 @@ def extract_strings() -> None:
             "--width=79",
             "--add-comments=L10N:",
             "--strip-comment-tag",
-            "--input-dirs=./normcap",
-            "--output-file=./normcap/resources/locales/messages.pot",
+            f"--input-dir={Path('__file__').parent.parent.resolve()}",
+            f"--output-file={(LOCALES_PATH / 'messages.pot').resolve()}",
         ]
     )
 
@@ -102,8 +113,8 @@ def update_locales() -> None:
         [
             "pybabel",
             "update",
-            "--input-file=./normcap/resources/locales/messages.pot",
-            "--output-dir=./normcap/resources/locales",
+            f"--input-file={(LOCALES_PATH / 'messages.pot').resolve()}",
+            f"--output-dir={LOCALES_PATH.resolve()}",
             "--width=79",
             "--ignore-obsolete",
         ]
@@ -116,8 +127,8 @@ def create_new(locales: list[str]) -> None:
             [
                 "pybabel",
                 "init",
-                "--input-file=./normcap/resources/locales/messages.pot",
-                "--output-dir=./normcap/resources/locales",
+                f"--input-file={(LOCALES_PATH / 'messages.pot').resolve()}",
+                f"--output-dir={LOCALES_PATH.resolve()}",
                 f"--locale={locale}",
             ]
         )
diff --git a/bundle/platforms/utils.py b/bundle/platforms/utils.py
index aafea0fc..6f5bff69 100644
--- a/bundle/platforms/utils.py
+++ b/bundle/platforms/utils.py
@@ -68,7 +68,7 @@ def compile_locales(self) -> None:
         """Create .mo files for all locales."""
         print("Compiling locales...")  # noqa: T201
         self.run(
-            cmd="python l10n.py",
+            cmd="python bundle/l10n.py",
             cwd=self.PROJECT_PATH,
         )
 
@@ -88,7 +88,7 @@ def get_version(self) -> str:
 
         with Path(self.PYPROJECT_PATH).open(encoding="utf8") as toml_file:
             pyproject_toml = toml.load(toml_file)
-        return pyproject_toml["tool"]["poetry"]["version"]
+        return pyproject_toml["tool"]["briefcase"]["version"]
 
     @staticmethod
     def run(cmd: Union[str, list], cwd: Optional[Path] = None) -> Optional[str]:
diff --git a/hatch_build.py b/hatch_build.py
new file mode 100644
index 00000000..1ba0e28e
--- /dev/null
+++ b/hatch_build.py
@@ -0,0 +1,15 @@
+import argparse
+import sys
+from pathlib import Path
+from typing import Any
+
+from hatchling.builders.hooks.plugin.interface import BuildHookInterface
+
+
+class CustomBuildHook(BuildHookInterface):
+    def initialize(self, version: str, build_data: dict[str, Any]) -> None:
+        sys.path.insert(0, f"{(Path(__file__).parent / 'bundle').resolve()}")
+        from l10n import main
+
+        args = argparse.Namespace(update_all=False, create_new=False)
+        main(args)
diff --git a/normcap/resources/locales/README.md b/normcap/resources/locales/README.md
index 58e3e4ef..d0464c7c 100644
--- a/normcap/resources/locales/README.md
+++ b/normcap/resources/locales/README.md
@@ -108,7 +108,7 @@ via [opening a new issue](https://github.com/dynobo/normcap/issues/new)!
 
 _Prerequisite:_ Follow the general
 [setup of the development environment](../../../README.md#Development) and activate the
-virtual Python environment via `poetry shell`.
+virtual Python environment via `hatch shell`.
 
 _Note_: All commands should be run in the repository's root directory.
 
@@ -123,7 +123,7 @@ _Note_: All commands should be run in the repository's root directory.
 2. Run the following command to create an initial `messages.po`-file for the language.
    Make sure to replace `<LOCALE_NAME>` by the string identified in step 1.
    ```sh
-   python l10n.py --create-new <LOCALE_NAME>
+   hatch run create-locale <LOCALE_NAME>
    ```
 3. Edit the file `./normcap/resources/locales/<LOCALE_NAME>/LC_MESSAGES/messages.po`
    which was created in step 2. Add your translations as the respective `msgstr`. If you
@@ -135,7 +135,7 @@ _Note_: All commands should be run in the repository's root directory.
      automatically.
 4. Compile the new `.po` file to the machine-readable `.mo` file:
    ```sh
-   python l10n.py
+   hatch run locales-compile
    ```
 5. To test your translation, run NormCap with the `LANGUAGE` environment variable set:
    ```sh
@@ -150,5 +150,5 @@ This is only necessary, when translatable strings in NormCap's source code got c
 
 1. Generate `.pot` file and update all existing `.po` files:
    ```sh
-   python l10n.py --update-all
+   hatch run locales-update
    ```
diff --git a/normcap/resources/locales/de_DE/LC_MESSAGES/messages.po b/normcap/resources/locales/de_DE/LC_MESSAGES/messages.po
index 38829052..f2eb75ff 100644
--- a/normcap/resources/locales/de_DE/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/de_DE/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: de_DE\n"
@@ -17,45 +17,45 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr "Download Fehler."
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr "Einführung in NormCap"
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr "Beim Start anzeigen"
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr "Ok"
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr "Strg + v"
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr "Cmd + v"
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr "1. Bereich auswählen"
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
@@ -64,12 +64,12 @@ msgstr ""
 "gewünschten Bereich aus."
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr "2. Erkennung abwarten"
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
@@ -78,12 +78,12 @@ msgstr ""
 "Farbänderung des Symbols im Infobereich."
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr "3. Aus Zwischenablage einfügen"
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
@@ -92,12 +92,12 @@ msgstr ""
 " in eine beliebige Anwendung ein ({shortcut})."
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr "Einstellungen & mehr"
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
@@ -106,63 +106,65 @@ msgstr ""
 "Bildschirms."
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr "Grundlegende Bedienung"
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr "Sprachen verwalten"
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr "Installiert:"
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr "Löschen"
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr "Verfügbar:"
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr "Herunterladen"
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr "Schließen"
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr "NormCap schließen und das tessdata-Verzeichnis öffnen..."
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr "Fehler"
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr "Download der Sprache fehlgeschlagen!"
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr "Information"
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
@@ -170,7 +172,7 @@ msgstr ""
 "Es ist nicht möglich, alle Sprachen zu löschen. NormCap benötigt mindestens "
 "eine, um korrekt zu funktionieren."
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -181,32 +183,32 @@ msgstr ""
 "Installation nach, wie Du zusätzliche Sprachen installieren kannst."
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr "Einstellungen"
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr "Erkennungsmodus"
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr "Sprachen"
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr "Anwendung"
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr "Benachrichtigung anzeigen"
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -216,11 +218,11 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr "Im Infobereich behalten"
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
@@ -229,11 +231,11 @@ msgstr ""
 "können über das Symbol im Infobereich gestartet werden."
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr "Nach Aktualisierung suchen"
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
@@ -242,11 +244,11 @@ msgstr ""
 "zeige eine Nachricht, falls eine Aktualisierung verfügbar ist."
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr "intelligent"
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -260,11 +262,11 @@ msgstr ""
 "stattdessen den 'einfach'-Modus."
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr "einfach"
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
@@ -273,75 +275,75 @@ msgstr ""
 "die Texterkennungs-Software detektiert hat."
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr "Hinzufügen/Entfernen..."
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr "... andere?"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr "Über"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr "Einführung"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr "Webseite (eng)"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr "Häufige Fragen (eng)"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr "Quellcode"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr "Versionen"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr "Problem melden"
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr "Einen Kaffee spenden"
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 "Beende NormCap, oder minimiere es in den\n"
 "Infobereich (sofern aktiviert)."
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr "Nichts erkannt!"
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr "Bitte versuche es nochmal."
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] "1 Absatz erkannt"
@@ -349,7 +351,7 @@ msgstr[1] "{count} Absätze erkannt"
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] "1 E-Mail Adresse erkannt"
@@ -357,7 +359,7 @@ msgstr[1] "{count} E-Mail Adressen erkannt"
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] "1 Wort erkannt"
@@ -365,7 +367,7 @@ msgstr[1] "{count} Wörter erkannt"
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] "1 Zeile erkannt"
@@ -373,7 +375,7 @@ msgstr[1] "{count} Zeilen erkannt"
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] "1 URL erkannt"
@@ -381,7 +383,7 @@ msgstr[1] "{count} URLs erkannt"
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] "1 Buchstabe erkannt"
@@ -389,7 +391,7 @@ msgstr[1] "{count} Buchstaben erkannt"
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 #, fuzzy
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
@@ -409,7 +411,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -423,29 +425,29 @@ msgstr ""
 "href='{issues_url}'>melden dies bitte als Fehler</a> über GitHub.</small>"
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr "Erkennen"
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr "Beenden"
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr "NormCap v{version} ist verfügbar."
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr "Du hast v{version}"
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -458,7 +460,7 @@ msgstr ""
 "Möchtest Du jetzt die Webseite mit den Releases besuchen?"
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
@@ -469,3 +471,4 @@ msgstr ""
 "install normcap --upgrade'.\n"
 "\n"
 "Möchtest Du die Liste der Neuerungen auf GitHub ansehen?"
+
diff --git a/normcap/resources/locales/es_ES/LC_MESSAGES/messages.po b/normcap/resources/locales/es_ES/LC_MESSAGES/messages.po
index a675c12f..ece157eb 100644
--- a/normcap/resources/locales/es_ES/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/es_ES/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: NormCap 0.4.4\n"
 "Report-Msgid-Bugs-To: dynobo@mailbox.org\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: 2023-10-08 12:15+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: es_ES\n"
@@ -16,150 +16,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -167,32 +169,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -200,33 +202,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -235,84 +237,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -320,7 +322,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -328,7 +330,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -336,7 +338,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -344,7 +346,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -352,7 +354,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -360,7 +362,7 @@ msgstr[1] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -372,7 +374,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -382,29 +384,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -413,10 +415,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/fr_FR/LC_MESSAGES/messages.po b/normcap/resources/locales/fr_FR/LC_MESSAGES/messages.po
index 6e248787..552e86f1 100644
--- a/normcap/resources/locales/fr_FR/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/fr_FR/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: fr_FR\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,84 +238,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -321,7 +323,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -329,7 +331,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -337,7 +339,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -345,7 +347,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -353,7 +355,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -361,7 +363,7 @@ msgstr[1] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -373,7 +375,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -383,29 +385,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -414,10 +416,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/hi_IN/LC_MESSAGES/messages.po b/normcap/resources/locales/hi_IN/LC_MESSAGES/messages.po
index daaf2488..f4ed8e17 100644
--- a/normcap/resources/locales/hi_IN/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/hi_IN/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: hi_IN\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,84 +238,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -321,7 +323,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -329,7 +331,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -337,7 +339,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -345,7 +347,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -353,7 +355,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -361,7 +363,7 @@ msgstr[1] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -373,7 +375,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -383,29 +385,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -414,10 +416,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/it_IT/LC_MESSAGES/messages.po b/normcap/resources/locales/it_IT/LC_MESSAGES/messages.po
index 4b82e1d2..5dfe6da4 100644
--- a/normcap/resources/locales/it_IT/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/it_IT/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: NormCap 0.4.4\n"
 "Report-Msgid-Bugs-To: dynobo@mailbox.org\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: 2023-10-08 12:15+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: it_IT\n"
@@ -16,150 +16,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -167,32 +169,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -200,33 +202,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -235,84 +237,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -320,7 +322,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -328,7 +330,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -336,7 +338,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -344,7 +346,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -352,7 +354,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -360,7 +362,7 @@ msgstr[1] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -372,7 +374,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -382,29 +384,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -413,10 +415,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/pl_PL/LC_MESSAGES/messages.po b/normcap/resources/locales/pl_PL/LC_MESSAGES/messages.po
index 0002f1a7..b2de2205 100644
--- a/normcap/resources/locales/pl_PL/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/pl_PL/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: NormCap 0.4.4\n"
 "Report-Msgid-Bugs-To: dynobo@mailbox.org\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: 2023-10-08 12:40+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: pl_PL\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,84 +238,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -322,7 +324,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -331,7 +333,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -340,7 +342,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -349,7 +351,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -358,7 +360,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -367,7 +369,7 @@ msgstr[2] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -379,7 +381,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -389,29 +391,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -420,10 +422,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/pt_PT/LC_MESSAGES/messages.po b/normcap/resources/locales/pt_PT/LC_MESSAGES/messages.po
index f30ca401..72e3cd6c 100644
--- a/normcap/resources/locales/pt_PT/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/pt_PT/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: pt_PT\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,84 +238,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -321,7 +323,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -329,7 +331,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -337,7 +339,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -345,7 +347,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -353,7 +355,7 @@ msgstr[1] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -361,7 +363,7 @@ msgstr[1] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -373,7 +375,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -383,29 +385,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -414,10 +416,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/ru_RU/LC_MESSAGES/messages.po b/normcap/resources/locales/ru_RU/LC_MESSAGES/messages.po
index db4c9ebf..6900fb9b 100644
--- a/normcap/resources/locales/ru_RU/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/ru_RU/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: ru_RU\n"
@@ -18,150 +18,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -169,32 +171,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -202,33 +204,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -237,84 +239,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -323,7 +325,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -332,7 +334,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -341,7 +343,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -350,7 +352,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -359,7 +361,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -368,7 +370,7 @@ msgstr[2] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -380,7 +382,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -390,29 +392,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -421,10 +423,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/uk_UA/LC_MESSAGES/messages.po b/normcap/resources/locales/uk_UA/LC_MESSAGES/messages.po
index 20ad4b1d..bb090220 100644
--- a/normcap/resources/locales/uk_UA/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/uk_UA/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: NormCap 0.4.4\n"
 "Report-Msgid-Bugs-To: dynobo@mailbox.org\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: 2023-10-08 12:16+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: uk_UA\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,84 +238,84 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
@@ -322,7 +324,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
@@ -331,7 +333,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
@@ -340,7 +342,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
@@ -349,7 +351,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
@@ -358,7 +360,7 @@ msgstr[2] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
@@ -367,7 +369,7 @@ msgstr[2] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -379,7 +381,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -389,29 +391,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -420,10 +422,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/normcap/resources/locales/zh_CN/LC_MESSAGES/messages.po b/normcap/resources/locales/zh_CN/LC_MESSAGES/messages.po
index 1a331098..fc9a279c 100644
--- a/normcap/resources/locales/zh_CN/LC_MESSAGES/messages.po
+++ b/normcap/resources/locales/zh_CN/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-10-08 12:47+0200\n"
+"POT-Creation-Date: 2023-10-27 04:37+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: zh_CN\n"
@@ -17,150 +17,152 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.13.0\n"
+"Generated-By: Babel 2.13.1\n"
 
 #. Generic error message when any download failed.
-#: normcap/gui/downloader.py:58
+#: /home/holger/Code/normcap/normcap/gui/downloader.py:58
 msgid "Download error."
 msgstr ""
 
 #. Introduction window title
-#: normcap/gui/introduction.py:50
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:50
 msgid "Introduction to NormCap"
 msgstr ""
 
 #. Introduction window checkbox
-#: normcap/gui/introduction.py:55
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:56
 msgid "Show on startup"
 msgstr ""
 
 #. Introduction window button
-#: normcap/gui/introduction.py:58
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:59
 msgid "Ok"
 msgstr ""
 
 #. Introduction window shortcut for pasting on Linux and Windows
-#: normcap/gui/introduction.py:75
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:76
 msgid "Ctrl + v"
 msgstr ""
 
 #. Introduction window shortcut for pasting on macOS
-#: normcap/gui/introduction.py:77
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:78
 msgid "Cmd + v"
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:81
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:82
 msgid "1. Select area"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:83
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:84
 msgid ""
 "Wait until a pink border appears around your screen, then select the desired"
 " capture area."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:91
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:92
 msgid "2. Wait for detection"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:93
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:94
 msgid ""
 "Processing takes time. Wait for a notification or a color change of the "
 "system tray icon."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:101
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:102
 msgid "3. Paste from clipboard"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:103
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:104
 msgid ""
 "The detection result will be copied to your system's clipboard. Paste it "
 "into any application ({shortcut})."
 msgstr ""
 
 #. Introduction window step title
-#: normcap/gui/introduction.py:115
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:116
 msgid "Settings & more"
 msgstr ""
 
 #. Introduction window step description
-#: normcap/gui/introduction.py:117
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:118
 msgid ""
 "Open the menu using the gear icon in the upper right corner of corner your "
 "screen."
 msgstr ""
 
 #. Introduction window headline
-#: normcap/gui/introduction.py:127
+#: /home/holger/Code/normcap/normcap/gui/introduction.py:128
 msgid "Basic Usage"
 msgstr ""
 
 #. Title of Language Manager
-#: normcap/gui/language_manager.py:31
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:31
 msgid "Manage Languages"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:44
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:44
 msgid "Installed:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:47
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:47
 msgid "Delete"
 msgstr ""
 
 #. Language Manager section
-#: normcap/gui/language_manager.py:54
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:54
 msgid "Available:"
 msgstr ""
 
 #. Language Manager button
-#: normcap/gui/language_manager.py:57
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:57
 msgid "Download"
 msgstr ""
 
 #. Language Manager button
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/language_manager.py:66 normcap/gui/menu_button.py:391
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:66
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:391
 msgid "Close"
 msgstr ""
 
 #. Language Manager link to directory on file system
-#: normcap/gui/language_manager.py:72
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:72
 msgid "Close and view tessdata folder in file manager..."
 msgstr ""
 
 #. Language Manager error message box title
-#: normcap/gui/language_manager.py:97 normcap/gui/tray.py:406
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:97
+#: /home/holger/Code/normcap/normcap/gui/tray.py:411
 msgid "Error"
 msgstr ""
 
 #. Language Manager error message box text
-#: normcap/gui/language_manager.py:99
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:99
 msgid "Language download failed!"
 msgstr ""
 
 #. Language Manager information message box title
-#: normcap/gui/language_manager.py:129
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:129
 msgid "Information"
 msgstr ""
 
 #. Language Manager information message box text
-#: normcap/gui/language_manager.py:131
+#: /home/holger/Code/normcap/normcap/gui/language_manager.py:131
 msgid ""
 "It is not possible to delete all languages. NormCap needs at least one to "
 "function correctly."
 msgstr ""
 
-#: normcap/gui/menu_button.py:154
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:154
 msgid ""
 "This installation of NormCap uses the Tesseract binary installed on your "
 "system. To install additional languages, please refer to the documentation "
@@ -168,32 +170,32 @@ msgid ""
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:200
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:200
 msgid "Settings"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:204
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:204
 msgid "Capture mode"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:208
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:208
 msgid "Languages"
 msgstr ""
 
 #. Section title in Main Menu
-#: normcap/gui/menu_button.py:212
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:212
 msgid "Application"
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:232
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:232
 msgid "Show notification"
 msgstr ""
 
 #. Tooltip of main menu's "Show notification" entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:237
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:237
 msgid ""
 "Show status information via your system's desktop\n"
 "notification center."
@@ -201,33 +203,33 @@ msgstr ""
 
 #. Extension "Show notification"-Tooltip on macOS and Windows.
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:249
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:249
 msgid "Keep in system tray"
 msgstr ""
 
-#: normcap/gui/menu_button.py:255
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:255
 msgid ""
 "Keep NormCap running in the background. Another\n"
 "capture can be triggered via the tray icon."
 msgstr ""
 
 #. Entry in main menu's 'setting' section
-#: normcap/gui/menu_button.py:263
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:263
 msgid "Check for update"
 msgstr ""
 
-#: normcap/gui/menu_button.py:269
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:269
 msgid ""
 "Frequently fetch NormCap's releases online and display\n"
 "a message if a new version is available."
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:282
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:282
 msgid "parse"
 msgstr ""
 
-#: normcap/gui/menu_button.py:288
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:288
 msgid ""
 "Tries to determine the text's type (e.g. line,\n"
 "paragraph, URL, email) and formats the output\n"
@@ -236,126 +238,126 @@ msgid ""
 msgstr ""
 
 #. Entry in main menu's 'Capture mode' section
-#: normcap/gui/menu_button.py:298
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:298
 msgid "raw"
 msgstr ""
 
-#: normcap/gui/menu_button.py:304
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:304
 msgid ""
 "Returns the text exactly as detected by the Optical\n"
 "Character Recognition Software."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in prebuilt package.
-#: normcap/gui/menu_button.py:333
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:333
 msgid "add/remove..."
 msgstr ""
 
 #. Entry in main menu's 'Languages' section. Shown in Python package.
-#: normcap/gui/menu_button.py:337
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:337
 msgid "... need more?"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:346
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:346
 msgid "About"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:354
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:354
 msgid "Introduction"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:359
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:359
 msgid "Website"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:364
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:364
 msgid "FAQs"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:369
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:369
 msgid "Source code"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:374
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:374
 msgid "Releases"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:379
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:379
 msgid "Report a problem"
 msgstr ""
 
 #. Entry in main menu's 'Application' section.
-#: normcap/gui/menu_button.py:384
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:384
 msgid "Donate a coffee"
 msgstr ""
 
 #. Tooltip of main menu's 'close' entry. Use <56 chars p. line.
-#: normcap/gui/menu_button.py:394
+#: /home/holger/Code/normcap/normcap/gui/menu_button.py:394
 msgid "Exit NormCap, or minimize to system tray (if enabled)."
 msgstr ""
 
 #. Notification title
-#: normcap/gui/notification.py:40
+#: /home/holger/Code/normcap/normcap/gui/notification.py:40
 msgid "Nothing captured!"
 msgstr ""
 
 #. Notification text
-#: normcap/gui/notification.py:42
+#: /home/holger/Code/normcap/normcap/gui/notification.py:42
 msgid "Please try again."
 msgstr ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:53
+#: /home/holger/Code/normcap/normcap/gui/notification.py:53
 msgid "1 paragraph captured"
 msgid_plural "{count} paragraphs captured"
 msgstr[0] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:60
+#: /home/holger/Code/normcap/normcap/gui/notification.py:60
 msgid "1 email captured"
 msgid_plural "{count} emails captured"
 msgstr[0] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:67
+#: /home/holger/Code/normcap/normcap/gui/notification.py:67
 msgid "1 word captured"
 msgid_plural "{count} words captured"
 msgstr[0] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:74
+#: /home/holger/Code/normcap/normcap/gui/notification.py:74
 msgid "1 line captured"
 msgid_plural "{count} lines captured"
 msgstr[0] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:81
+#: /home/holger/Code/normcap/normcap/gui/notification.py:81
 msgid "1 URL captured"
 msgid_plural "{count} URLs captured"
 msgstr[0] ""
 
 #. Notification title.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/notification.py:90
+#: /home/holger/Code/normcap/normcap/gui/notification.py:90
 msgid "1 character captured"
 msgid_plural "{count} characters captured"
 msgstr[0] ""
 
 #. Error message box on macOS only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:411
+#: /home/holger/Code/normcap/normcap/gui/tray.py:416
 msgid ""
 "'{application}' is missing the permission for 'Screen Recording'.\n"
 "\n"
@@ -367,7 +369,7 @@ msgstr ""
 
 #. Error message box on Linux with Wayland only.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/tray.py:422
+#: /home/holger/Code/normcap/normcap/gui/tray.py:427
 msgid ""
 "<b>NormCap is missing the permission for screen capture.</b><br><br>Grant it"
 " via the dialog that will appear after you clicked 'Ok'.<br>Then start "
@@ -377,29 +379,29 @@ msgid ""
 msgstr ""
 
 #. Tray menu entry
-#: normcap/gui/tray.py:511
+#: /home/holger/Code/normcap/normcap/gui/tray.py:517
 msgid "Capture"
 msgstr ""
 
 #. Tray menu entry for exiting NormCap completely.
-#: normcap/gui/tray.py:518
+#: /home/holger/Code/normcap/normcap/gui/tray.py:524
 msgid "Exit"
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:80
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:80
 msgid "NormCap v{version} is available."
 msgstr ""
 
 #. Update available dialog box.
 #. Do NOT translate the variables in curly brackets "{some_variable}"!
-#: normcap/gui/update_check.py:83
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:83
 msgid "You have v{version}"
 msgstr ""
 
 #. Message box shown when new version available (Prebuilt package)
-#: normcap/gui/update_check.py:87
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:87
 msgid ""
 "You can download the new version of NormCap for your operating system from "
 "GitHub.\n"
@@ -408,10 +410,11 @@ msgid ""
 msgstr ""
 
 #. Message box shown when new version available (Python package)
-#: normcap/gui/update_check.py:94
+#: /home/holger/Code/normcap/normcap/gui/update_check.py:94
 msgid ""
 "You can upgrade NormCap via the command line, e.g. by running 'pip install "
 "normcap --upgrade'.\n"
 "\n"
 "Do you want to view the changelog on GitHub now?"
 msgstr ""
+
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index bd266294..00000000
--- a/poetry.lock
+++ /dev/null
@@ -1,2107 +0,0 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
-
-[[package]]
-name = "arrow"
-version = "1.3.0"
-description = "Better dates & times for Python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"},
-    {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"},
-]
-
-[package.dependencies]
-python-dateutil = ">=2.7.0"
-types-python-dateutil = ">=2.8.10"
-
-[package.extras]
-doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"]
-test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"]
-
-[[package]]
-name = "babel"
-version = "2.13.1"
-description = "Internationalization utilities"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"},
-    {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"},
-]
-
-[package.extras]
-dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
-
-[[package]]
-name = "binaryornot"
-version = "0.4.4"
-description = "Ultra-lightweight pure Python package to check if a file is binary or text."
-optional = false
-python-versions = "*"
-files = [
-    {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"},
-    {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
-]
-
-[package.dependencies]
-chardet = ">=3.0.2"
-
-[[package]]
-name = "black"
-version = "23.10.1"
-description = "The uncompromising code formatter."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"},
-    {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"},
-    {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"},
-    {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"},
-    {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"},
-    {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"},
-    {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"},
-    {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"},
-    {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"},
-    {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"},
-    {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"},
-    {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"},
-    {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"},
-    {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"},
-    {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"},
-    {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"},
-    {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"},
-    {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"},
-]
-
-[package.dependencies]
-click = ">=8.0.0"
-mypy-extensions = ">=0.4.3"
-packaging = ">=22.0"
-pathspec = ">=0.9.0"
-platformdirs = ">=2"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
-
-[package.extras]
-colorama = ["colorama (>=0.4.3)"]
-d = ["aiohttp (>=3.7.4)"]
-jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
-uvloop = ["uvloop (>=0.15.2)"]
-
-[[package]]
-name = "boolean-py"
-version = "4.0"
-description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL."
-optional = false
-python-versions = "*"
-files = [
-    {file = "boolean.py-4.0-py3-none-any.whl", hash = "sha256:2876f2051d7d6394a531d82dc6eb407faa0b01a0a0b3083817ccd7323b8d96bd"},
-    {file = "boolean.py-4.0.tar.gz", hash = "sha256:17b9a181630e43dde1851d42bef546d616d5d9b4480357514597e78b203d06e4"},
-]
-
-[[package]]
-name = "briefcase"
-version = "0.3.16"
-description = "Tools to support converting a Python project into a standalone native application."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "briefcase-0.3.16-py3-none-any.whl", hash = "sha256:dd20070069ef2ad499d2acd8510f0dcedd5419be7a3a2c8a3383ef9a26a4b0be"},
-    {file = "briefcase-0.3.16.tar.gz", hash = "sha256:b728ddc895528922cc056f85e93795b0472523445350a723faecb3321d7d99c2"},
-]
-
-[package.dependencies]
-build = ">=0.10"
-cookiecutter = ">=2.3.1,<3.0"
-dmgbuild = {version = ">=1.6,<2.0", markers = "sys_platform == \"darwin\""}
-GitPython = ">=3.1,<4.0"
-importlib-metadata = {version = ">=4.4", markers = "python_version <= \"3.9\""}
-packaging = ">=22.0"
-pip = ">=23.1.1"
-platformdirs = ">=2.6,<4.0"
-psutil = ">=5.9,<6.0"
-requests = ">=2.28,<3.0"
-rich = ">=12.6,<14.0"
-setuptools = ">=60"
-tomli = {version = ">=2.0,<3.0", markers = "python_version <= \"3.10\""}
-tomli-w = ">=1.0,<2.0"
-wheel = ">=0.37"
-
-[package.extras]
-dev = ["coverage-conditional-plugin (==0.9.0)", "coverage[toml] (==7.3.2)", "pre-commit (==3.5.0)", "pytest (==7.4.2)", "pytest-xdist (==3.3.1)", "setuptools-scm[toml] (==8.0.4)", "tox (==4.11.3)"]
-docs = ["furo (==2023.9.10)", "pyenchant (==3.2.2)", "sphinx (==7.1.2)", "sphinx (==7.2.6)", "sphinx-autobuild (==2021.3.14)", "sphinx-copybutton (==0.5.2)", "sphinx-tabs (==3.4.1)", "sphinxcontrib-spelling (==8.0.0)"]
-
-[[package]]
-name = "build"
-version = "1.0.3"
-description = "A simple, correct Python build frontend"
-optional = false
-python-versions = ">= 3.7"
-files = [
-    {file = "build-1.0.3-py3-none-any.whl", hash = "sha256:589bf99a67df7c9cf07ec0ac0e5e2ea5d4b37ac63301c4986d1acb126aa83f8f"},
-    {file = "build-1.0.3.tar.gz", hash = "sha256:538aab1b64f9828977f84bc63ae570b060a8ed1be419e7870b8b4fc5e6ea553b"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "os_name == \"nt\""}
-importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""}
-packaging = ">=19.0"
-pyproject_hooks = "*"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-
-[package.extras]
-docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
-test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
-typing = ["importlib-metadata (>=5.1)", "mypy (>=1.5.0,<1.6.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
-virtualenv = ["virtualenv (>=20.0.35)"]
-
-[[package]]
-name = "cachecontrol"
-version = "0.13.1"
-description = "httplib2 caching for requests"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
-    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
-]
-
-[package.dependencies]
-filelock = {version = ">=3.8.0", optional = true, markers = "extra == \"filecache\""}
-msgpack = ">=0.5.2"
-requests = ">=2.16.0"
-
-[package.extras]
-dev = ["CacheControl[filecache,redis]", "black", "build", "cherrypy", "mypy", "pytest", "pytest-cov", "sphinx", "tox", "types-redis", "types-requests"]
-filecache = ["filelock (>=3.8.0)"]
-redis = ["redis (>=2.10.5)"]
-
-[[package]]
-name = "certifi"
-version = "2023.7.22"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
-    {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
-]
-
-[[package]]
-name = "cfgv"
-version = "3.4.0"
-description = "Validate configuration and produce human readable error messages."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
-    {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
-]
-
-[[package]]
-name = "chardet"
-version = "5.2.0"
-description = "Universal encoding detector for Python 3"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
-    {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.3.1"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.7.0"
-files = [
-    {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"},
-    {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"},
-    {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"},
-    {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-win32.whl", hash = "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9"},
-    {file = "charset_normalizer-3.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-win32.whl", hash = "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb"},
-    {file = "charset_normalizer-3.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"},
-    {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"},
-    {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"},
-]
-
-[[package]]
-name = "cli-ui"
-version = "0.17.2"
-description = "Build Nice User Interfaces In The Terminal"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "cli-ui-0.17.2.tar.gz", hash = "sha256:2f67e50cf474e76ad160c3e660bbad98bf8b8dfb8d847765f3a261b7e13c05fa"},
-    {file = "cli_ui-0.17.2-py3-none-any.whl", hash = "sha256:6a1ebdbbcd83a0fa06b2f63f4434082a3ba8664aebedd91f1ff86b9e4289d53e"},
-]
-
-[package.dependencies]
-colorama = ">=0.4.1,<0.5.0"
-tabulate = ">=0.8.3,<0.9.0"
-unidecode = ">=1.0.23,<2.0.0"
-
-[[package]]
-name = "click"
-version = "8.1.7"
-description = "Composable command line interface toolkit"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
-    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-description = "Cross-platform colored terminal text."
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
-files = [
-    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
-    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
-]
-
-[[package]]
-name = "contextlib2"
-version = "21.6.0"
-description = "Backports and enhancements for the contextlib module"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "contextlib2-21.6.0-py2.py3-none-any.whl", hash = "sha256:3fbdb64466afd23abaf6c977627b75b6139a5a3e8ce38405c5b413aed7a0471f"},
-    {file = "contextlib2-21.6.0.tar.gz", hash = "sha256:ab1e2bfe1d01d968e1b7e8d9023bc51ef3509bba217bb730cee3827e1ee82869"},
-]
-
-[[package]]
-name = "cookiecutter"
-version = "2.4.0"
-description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "cookiecutter-2.4.0-py3-none-any.whl", hash = "sha256:8344663028abc08ec09b912e663636a97e1775bffe973425ec0107431acd390e"},
-    {file = "cookiecutter-2.4.0.tar.gz", hash = "sha256:6d1494e66a784f23324df9d593f3e43af3db4f4b926b9e49e6ff060169fc042a"},
-]
-
-[package.dependencies]
-arrow = "*"
-binaryornot = ">=0.4.4"
-click = ">=7.0,<9.0.0"
-Jinja2 = ">=2.7,<4.0.0"
-python-slugify = ">=4.0.0"
-pyyaml = ">=5.3.1"
-requests = ">=2.23.0"
-rich = "*"
-
-[[package]]
-name = "coverage"
-version = "6.5.0"
-description = "Code coverage measurement for Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"},
-    {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"},
-    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"},
-    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"},
-    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"},
-    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"},
-    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"},
-    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"},
-    {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"},
-    {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"},
-    {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"},
-    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"},
-    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"},
-    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"},
-    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"},
-    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"},
-    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"},
-    {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"},
-    {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"},
-    {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"},
-    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"},
-    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"},
-    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"},
-    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"},
-    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"},
-    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"},
-    {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"},
-    {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"},
-    {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"},
-    {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"},
-    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"},
-    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"},
-    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"},
-    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"},
-    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"},
-    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"},
-    {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"},
-    {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"},
-    {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"},
-    {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"},
-    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"},
-    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"},
-    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"},
-    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"},
-    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"},
-    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"},
-    {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"},
-    {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"},
-    {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"},
-    {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"},
-]
-
-[package.dependencies]
-tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
-
-[package.extras]
-toml = ["tomli"]
-
-[[package]]
-name = "coveralls"
-version = "3.3.1"
-description = "Show coverage stats online via coveralls.io"
-optional = false
-python-versions = ">= 3.5"
-files = [
-    {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"},
-    {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"},
-]
-
-[package.dependencies]
-coverage = ">=4.1,<6.0.dev0 || >6.1,<6.1.1 || >6.1.1,<7.0"
-docopt = ">=0.6.1"
-requests = ">=1.0.0"
-
-[package.extras]
-yaml = ["PyYAML (>=3.10)"]
-
-[[package]]
-name = "cyclonedx-python-lib"
-version = "4.2.3"
-description = "A library for producing CycloneDX SBOM (Software Bill of Materials) files."
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "cyclonedx_python_lib-4.2.3-py3-none-any.whl", hash = "sha256:e9b923af525b6acf7bab917a35360b4b562b85dc15fde9eaa500828949adf73a"},
-    {file = "cyclonedx_python_lib-4.2.3.tar.gz", hash = "sha256:904068b55d1665f0ea96f38307603cc14f95c3b421f1687fc2411326aefde3a6"},
-]
-
-[package.dependencies]
-license-expression = ">=30,<31"
-packageurl-python = ">=0.11"
-py-serializable = ">=0.11.1,<0.12.0"
-sortedcontainers = ">=2.4.0,<3.0.0"
-
-[[package]]
-name = "decorator"
-version = "5.1.1"
-description = "Decorators for Humans"
-optional = false
-python-versions = ">=3.5"
-files = [
-    {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
-    {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
-]
-
-[[package]]
-name = "defusedxml"
-version = "0.7.1"
-description = "XML bomb protection for Python stdlib modules"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
-    {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
-    {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
-]
-
-[[package]]
-name = "distlib"
-version = "0.3.7"
-description = "Distribution utilities"
-optional = false
-python-versions = "*"
-files = [
-    {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"},
-    {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"},
-]
-
-[[package]]
-name = "dmgbuild"
-version = "1.6.1"
-description = "macOS command line utility to build disk images"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "dmgbuild-1.6.1-py3-none-any.whl", hash = "sha256:45dba6af4a64872c6a91eb335ebeaf5e1f4f4f39c89fd77cf40e841bd1226166"},
-    {file = "dmgbuild-1.6.1.tar.gz", hash = "sha256:7ced2603d684e29c22b4cd507d1e15a1907e91b86259924b8cfe480d80553b43"},
-]
-
-[package.dependencies]
-ds-store = ">=1.1.0"
-mac-alias = ">=2.0.1"
-
-[package.extras]
-badge-icons = ["pyobjc-framework-Quartz (>=3.0.4)"]
-dev = ["pre-commit", "tox"]
-docs = ["sphinx", "sphinx-autobuild", "sphinx-rtd-theme"]
-test = ["pytest", "pytest-cov", "pytest-tldr"]
-
-[[package]]
-name = "docopt"
-version = "0.6.2"
-description = "Pythonic argument parser, that will make you smile"
-optional = false
-python-versions = "*"
-files = [
-    {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"},
-]
-
-[[package]]
-name = "ds-store"
-version = "1.3.1"
-description = "Manipulate Finder .DS_Store files from Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "ds_store-1.3.1-py3-none-any.whl", hash = "sha256:fbacbb0bd5193ab3e66e5a47fff63619f15e374ffbec8ae29744251a6c8f05b5"},
-    {file = "ds_store-1.3.1.tar.gz", hash = "sha256:c27d413caf13c19acb85d75da4752673f1f38267f9eb6ba81b3b5aa99c2d207c"},
-]
-
-[package.dependencies]
-mac-alias = ">=2.0.1"
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-docs = ["sphinx", "sphinx-autobuild", "sphinx-rtd-theme"]
-test = ["pytest", "pytest-cov", "pytest-tldr"]
-
-[[package]]
-name = "exceptiongroup"
-version = "1.1.3"
-description = "Backport of PEP 654 (exception groups)"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"},
-    {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"},
-]
-
-[package.extras]
-test = ["pytest (>=6)"]
-
-[[package]]
-name = "filelock"
-version = "3.12.4"
-description = "A platform independent file lock."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"},
-    {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"},
-]
-
-[package.extras]
-docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"]
-testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"]
-typing = ["typing-extensions (>=4.7.1)"]
-
-[[package]]
-name = "gitdb"
-version = "4.0.11"
-description = "Git Object Database"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"},
-    {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"},
-]
-
-[package.dependencies]
-smmap = ">=3.0.1,<6"
-
-[[package]]
-name = "gitpython"
-version = "3.1.40"
-description = "GitPython is a Python library used to interact with Git repositories"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"},
-    {file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"},
-]
-
-[package.dependencies]
-gitdb = ">=4.0.1,<5"
-
-[package.extras]
-test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"]
-
-[[package]]
-name = "html5lib"
-version = "1.1"
-description = "HTML parser based on the WHATWG HTML specification"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
-    {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
-    {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
-]
-
-[package.dependencies]
-six = ">=1.9"
-webencodings = "*"
-
-[package.extras]
-all = ["chardet (>=2.2)", "genshi", "lxml"]
-chardet = ["chardet (>=2.2)"]
-genshi = ["genshi"]
-lxml = ["lxml"]
-
-[[package]]
-name = "identify"
-version = "2.5.30"
-description = "File identification library for Python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "identify-2.5.30-py2.py3-none-any.whl", hash = "sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54"},
-    {file = "identify-2.5.30.tar.gz", hash = "sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d"},
-]
-
-[package.extras]
-license = ["ukkonen"]
-
-[[package]]
-name = "idna"
-version = "3.4"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.5"
-files = [
-    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
-    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
-]
-
-[[package]]
-name = "importlib-metadata"
-version = "6.8.0"
-description = "Read metadata from Python packages"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
-    {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
-]
-
-[package.dependencies]
-zipp = ">=0.5"
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-perf = ["ipython"]
-testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
-
-[[package]]
-name = "iniconfig"
-version = "2.0.0"
-description = "brain-dead simple config-ini parsing"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
-    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
-]
-
-[[package]]
-name = "jinja2"
-version = "3.1.2"
-description = "A very fast and expressive template engine."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
-    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
-]
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "license-expression"
-version = "30.1.1"
-description = "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "license-expression-30.1.1.tar.gz", hash = "sha256:42375df653ad85e6f5b4b0385138b2dbea1f5d66360783d8625c3e4f97f11f0c"},
-    {file = "license_expression-30.1.1-py3-none-any.whl", hash = "sha256:8d7e5e2de0d04fc104a4f952c440e8f08a5ba63480a0dad015b294770b7e58ec"},
-]
-
-[package.dependencies]
-"boolean.py" = ">=4.0"
-
-[package.extras]
-docs = ["Sphinx (==5.1.0)", "doc8 (>=0.8.1)", "sphinx-rtd-theme (>=0.5.0)", "sphinxcontrib-apidoc (>=0.3.0)"]
-testing = ["black", "isort", "pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)", "twine"]
-
-[[package]]
-name = "linkify-it-py"
-version = "2.0.2"
-description = "Links recognition library with FULL unicode support."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"},
-    {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"},
-]
-
-[package.dependencies]
-uc-micro-py = "*"
-
-[package.extras]
-benchmark = ["pytest", "pytest-benchmark"]
-dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"]
-doc = ["myst-parser", "sphinx", "sphinx-book-theme"]
-test = ["coverage", "pytest", "pytest-cov"]
-
-[[package]]
-name = "mac-alias"
-version = "2.2.2"
-description = "Generate/parse Mac OS Alias records from Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "mac_alias-2.2.2-py3-none-any.whl", hash = "sha256:504ab8ac546f35bbd75ad014d6ad977c426660aa721f2cd3acf3dc2f664141bd"},
-    {file = "mac_alias-2.2.2.tar.gz", hash = "sha256:c99c728eb512e955c11f1a6203a0ffa8883b26549e8afe68804031aa5da856b7"},
-]
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-docs = ["sphinx", "sphinx-autobuild", "sphinx-rtd-theme"]
-test = ["pytest", "pytest-cov", "pytest-tldr"]
-
-[[package]]
-name = "mando"
-version = "0.7.1"
-description = "Create Python CLI apps with little to no effort at all!"
-optional = false
-python-versions = "*"
-files = [
-    {file = "mando-0.7.1-py2.py3-none-any.whl", hash = "sha256:26ef1d70928b6057ee3ca12583d73c63e05c49de8972d620c278a7b206581a8a"},
-    {file = "mando-0.7.1.tar.gz", hash = "sha256:18baa999b4b613faefb00eac4efadcf14f510b59b924b66e08289aa1de8c3500"},
-]
-
-[package.dependencies]
-six = "*"
-
-[package.extras]
-restructuredtext = ["rst2ansi"]
-
-[[package]]
-name = "markdown-it-py"
-version = "2.2.0"
-description = "Python port of markdown-it. Markdown parsing, done right!"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"},
-    {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"},
-]
-
-[package.dependencies]
-linkify-it-py = {version = ">=1,<3", optional = true, markers = "extra == \"linkify\""}
-mdurl = ">=0.1,<1.0"
-
-[package.extras]
-benchmarking = ["psutil", "pytest", "pytest-benchmark"]
-code-style = ["pre-commit (>=3.0,<4.0)"]
-compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
-linkify = ["linkify-it-py (>=1,<3)"]
-plugins = ["mdit-py-plugins"]
-profiling = ["gprof2dot"]
-rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
-testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
-
-[[package]]
-name = "markupsafe"
-version = "2.1.3"
-description = "Safely add untrusted strings to HTML/XML markup."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
-    {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
-    {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
-    {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
-    {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
-    {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
-    {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
-    {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
-]
-
-[[package]]
-name = "mdformat"
-version = "0.7.17"
-description = "CommonMark compliant Markdown formatter"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "mdformat-0.7.17-py3-none-any.whl", hash = "sha256:91ffc5e203f5814a6ad17515c77767fd2737fc12ffd8b58b7bb1d8b9aa6effaa"},
-    {file = "mdformat-0.7.17.tar.gz", hash = "sha256:a9dbb1838d43bb1e6f03bd5dca9412c552544a9bc42d6abb5dc32adfe8ae7c0d"},
-]
-
-[package.dependencies]
-importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
-markdown-it-py = ">=1.0.0,<4.0.0"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-
-[[package]]
-name = "mdformat-gfm"
-version = "0.3.5"
-description = "Mdformat plugin for GitHub Flavored Markdown compatibility"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "mdformat-gfm-0.3.5.tar.gz", hash = "sha256:5ee5f0de1d3b56d5edfced023bfff0aeed958be328e5460dac3221ac1b61ce7c"},
-    {file = "mdformat_gfm-0.3.5-py3-none-any.whl", hash = "sha256:1e627edc7665b59e008b3b9e5decc18c40cbd625c196d77e5ea3bc624e80ac8a"},
-]
-
-[package.dependencies]
-markdown-it-py = {version = "*", extras = ["linkify"]}
-mdformat = ">=0.7.5,<0.8.0"
-mdformat-tables = ">=0.4.0"
-mdit-py-plugins = ">=0.2.0,<0.4.0"
-
-[[package]]
-name = "mdformat-pyproject"
-version = "0.0.1"
-description = "An mdformat plugin for..."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "mdformat_pyproject-0.0.1-py3-none-any.whl", hash = "sha256:35fe74984ca86c3c5219280be7ea8a161fdc0d0a27bd0a788dcec5d9e322a871"},
-    {file = "mdformat_pyproject-0.0.1.tar.gz", hash = "sha256:a2a03b8f77ec43a60060ab5da4402f613c7d83eca51ff9f19373d590ecdba3aa"},
-]
-
-[package.dependencies]
-mdformat = ">=0.7,<1.0"
-tomli = {version = ">=2.0,<3.0", markers = "python_version < \"3.11\""}
-
-[package.extras]
-dev = ["pre-commit"]
-test = ["coverage", "pytest (>=6.0,<7.0)", "pytest-cov"]
-
-[[package]]
-name = "mdformat-tables"
-version = "0.4.1"
-description = "An mdformat plugin for rendering tables."
-optional = false
-python-versions = ">=3.6.1"
-files = [
-    {file = "mdformat_tables-0.4.1-py3-none-any.whl", hash = "sha256:981f3dc7350027f78e3fd6a5fe8a16e123eec423af2d140e588d855751501019"},
-    {file = "mdformat_tables-0.4.1.tar.gz", hash = "sha256:3024e88e9d29d7b8bb07fd6b59c9d5dcf14d2060122be29e30e72d27b65d7da9"},
-]
-
-[package.dependencies]
-mdformat = ">=0.7.5,<0.8.0"
-
-[package.extras]
-test = ["coverage", "pytest (>=6.0,<7.0)", "pytest-cov"]
-
-[[package]]
-name = "mdit-py-plugins"
-version = "0.3.5"
-description = "Collection of plugins for markdown-it-py"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"},
-    {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"},
-]
-
-[package.dependencies]
-markdown-it-py = ">=1.0.0,<3.0.0"
-
-[package.extras]
-code-style = ["pre-commit"]
-rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"]
-testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
-
-[[package]]
-name = "mdurl"
-version = "0.1.2"
-description = "Markdown URL utilities"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
-    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
-]
-
-[[package]]
-name = "msgpack"
-version = "1.0.7"
-description = "MessagePack serializer"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
-    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
-    {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
-    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
-    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
-    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
-    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
-    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
-    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
-    {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
-    {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
-    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
-    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
-    {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
-    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
-    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
-    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
-    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
-    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
-    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
-    {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
-    {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
-    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
-    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
-    {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
-    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
-    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
-    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
-    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
-    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
-    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
-    {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
-    {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
-    {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"},
-    {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"},
-    {file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"},
-    {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"},
-    {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"},
-    {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"},
-    {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"},
-    {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"},
-    {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"},
-    {file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"},
-    {file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"},
-    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
-    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
-    {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
-    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
-    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
-    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
-    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
-    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
-    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
-    {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
-    {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
-    {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
-]
-
-[[package]]
-name = "mypy"
-version = "1.6.1"
-description = "Optional static typing for Python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"},
-    {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"},
-    {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"},
-    {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"},
-    {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"},
-    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
-    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
-    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
-    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
-    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
-    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
-    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
-    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
-    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
-    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
-    {file = "mypy-1.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:41697773aa0bf53ff917aa077e2cde7aa50254f28750f9b88884acea38a16169"},
-    {file = "mypy-1.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7274b0c57737bd3476d2229c6389b2ec9eefeb090bbaf77777e9d6b1b5a9d143"},
-    {file = "mypy-1.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbaf4662e498c8c2e352da5f5bca5ab29d378895fa2d980630656178bd607c46"},
-    {file = "mypy-1.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bb8ccb4724f7d8601938571bf3f24da0da791fe2db7be3d9e79849cb64e0ae85"},
-    {file = "mypy-1.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:68351911e85145f582b5aa6cd9ad666c8958bcae897a1bfda8f4940472463c45"},
-    {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"},
-    {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"},
-    {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"},
-    {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"},
-    {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"},
-    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
-    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
-]
-
-[package.dependencies]
-mypy-extensions = ">=1.0.0"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-typing-extensions = ">=4.1.0"
-
-[package.extras]
-dmypy = ["psutil (>=4.0)"]
-install-types = ["pip"]
-reports = ["lxml"]
-
-[[package]]
-name = "mypy-extensions"
-version = "1.0.0"
-description = "Type system extensions for programs checked with the mypy type checker."
-optional = false
-python-versions = ">=3.5"
-files = [
-    {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
-    {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
-]
-
-[[package]]
-name = "nodeenv"
-version = "1.8.0"
-description = "Node.js virtual environment builder"
-optional = false
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
-files = [
-    {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"},
-    {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"},
-]
-
-[package.dependencies]
-setuptools = "*"
-
-[[package]]
-name = "objprint"
-version = "0.2.3"
-description = "A library that can print Python objects in human readable format"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "objprint-0.2.3-py3-none-any.whl", hash = "sha256:1721e6f97bae5c5b86c2716a0d45a9dd2c9a4cd9f52cfc8a0dfbe801805554cb"},
-    {file = "objprint-0.2.3.tar.gz", hash = "sha256:73d0ad5a7c3151fce634c8892e5c2a050ccae3b1a353bf1316f08b7854da863b"},
-]
-
-[[package]]
-name = "packageurl-python"
-version = "0.11.2"
-description = "A purl aka. Package URL parser and builder"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "packageurl-python-0.11.2.tar.gz", hash = "sha256:01fbf74a41ef85cf413f1ede529a1411f658bda66ed22d45d27280ad9ceba471"},
-    {file = "packageurl_python-0.11.2-py3-none-any.whl", hash = "sha256:799acfe8d9e6e3534bbc19660be97d5b66754bc033e62c39f1e2f16323fcfa84"},
-]
-
-[package.extras]
-build = ["wheel"]
-lint = ["black", "isort", "mypy"]
-sqlalchemy = ["sqlalchemy (>=2.0.0)"]
-test = ["pytest"]
-
-[[package]]
-name = "packaging"
-version = "23.2"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
-    {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
-]
-
-[[package]]
-name = "pathspec"
-version = "0.11.2"
-description = "Utility library for gitignore style pattern matching of file paths."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"},
-    {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
-]
-
-[[package]]
-name = "pip"
-version = "23.3.1"
-description = "The PyPA recommended tool for installing Python packages."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pip-23.3.1-py3-none-any.whl", hash = "sha256:55eb67bb6171d37447e82213be585b75fe2b12b359e993773aca4de9247a052b"},
-    {file = "pip-23.3.1.tar.gz", hash = "sha256:1fcaa041308d01f14575f6d0d2ea4b75a3e2871fe4f9c694976f908768e14174"},
-]
-
-[[package]]
-name = "pip-api"
-version = "0.0.30"
-description = "An unofficial, importable pip API"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pip-api-0.0.30.tar.gz", hash = "sha256:a05df2c7aa9b7157374bcf4273544201a0c7bae60a9c65bcf84f3959ef3896f3"},
-    {file = "pip_api-0.0.30-py3-none-any.whl", hash = "sha256:2a0314bd31522eb9ffe8a99668b0d07fee34ebc537931e7b6483001dbedcbdc9"},
-]
-
-[package.dependencies]
-pip = "*"
-
-[[package]]
-name = "pip-audit"
-version = "2.6.1"
-description = "A tool for scanning Python environments for known vulnerabilities"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pip_audit-2.6.1-py3-none-any.whl", hash = "sha256:8a32bb67dca6a76c244bbccebed562c0f6957b1fc9d34d59a9ec0fbff0672ae0"},
-    {file = "pip_audit-2.6.1.tar.gz", hash = "sha256:55c9bd18b0fe3959f73397db08d257c6012ad1826825e3d74cb6c3f79e95c245"},
-]
-
-[package.dependencies]
-CacheControl = {version = ">=0.13.0", extras = ["filecache"]}
-cyclonedx-python-lib = ">=4.0,<5.0"
-html5lib = ">=1.1"
-packaging = ">=23.0.0"
-pip-api = ">=0.0.28"
-pip-requirements-parser = ">=32.0.0"
-requests = ">=2.31.0"
-rich = ">=12.4"
-toml = ">=0.10"
-
-[package.extras]
-dev = ["build", "bump (>=1.3.2)", "pip-audit[doc,lint,test]"]
-doc = ["pdoc"]
-lint = ["black (>=22.3.0)", "interrogate", "isort", "mypy", "ruff (<0.0.281)", "types-html5lib", "types-requests", "types-toml"]
-test = ["coverage[toml]", "pretend", "pytest", "pytest-cov"]
-
-[[package]]
-name = "pip-requirements-parser"
-version = "32.0.1"
-description = "pip requirements parser - a mostly correct pip requirements parsing library because it uses pip's own code."
-optional = false
-python-versions = ">=3.6.0"
-files = [
-    {file = "pip-requirements-parser-32.0.1.tar.gz", hash = "sha256:b4fa3a7a0be38243123cf9d1f3518da10c51bdb165a2b2985566247f9155a7d3"},
-    {file = "pip_requirements_parser-32.0.1-py3-none-any.whl", hash = "sha256:4659bc2a667783e7a15d190f6fccf8b2486685b6dba4c19c3876314769c57526"},
-]
-
-[package.dependencies]
-packaging = "*"
-pyparsing = "*"
-
-[package.extras]
-docs = ["Sphinx (>=3.3.1)", "doc8 (>=0.8.1)", "sphinx-rtd-theme (>=0.5.0)"]
-testing = ["aboutcode-toolkit (>=6.0.0)", "black", "pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)"]
-
-[[package]]
-name = "platformdirs"
-version = "3.11.0"
-description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
-    {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
-]
-
-[package.extras]
-docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
-
-[[package]]
-name = "pluggy"
-version = "1.3.0"
-description = "plugin and hook calling mechanisms for python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
-    {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
-]
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "pre-commit"
-version = "3.5.0"
-description = "A framework for managing and maintaining multi-language pre-commit hooks."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"},
-    {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"},
-]
-
-[package.dependencies]
-cfgv = ">=2.0.0"
-identify = ">=1.0.0"
-nodeenv = ">=0.11.1"
-pyyaml = ">=5.1"
-virtualenv = ">=20.10.0"
-
-[[package]]
-name = "psutil"
-version = "5.9.6"
-description = "Cross-platform lib for process and system monitoring in Python."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-files = [
-    {file = "psutil-5.9.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d"},
-    {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c"},
-    {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28"},
-    {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017"},
-    {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c"},
-    {file = "psutil-5.9.6-cp27-none-win32.whl", hash = "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9"},
-    {file = "psutil-5.9.6-cp27-none-win_amd64.whl", hash = "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac"},
-    {file = "psutil-5.9.6-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a"},
-    {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c"},
-    {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4"},
-    {file = "psutil-5.9.6-cp36-cp36m-win32.whl", hash = "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602"},
-    {file = "psutil-5.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa"},
-    {file = "psutil-5.9.6-cp37-abi3-win32.whl", hash = "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c"},
-    {file = "psutil-5.9.6-cp37-abi3-win_amd64.whl", hash = "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a"},
-    {file = "psutil-5.9.6-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57"},
-    {file = "psutil-5.9.6.tar.gz", hash = "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a"},
-]
-
-[package.extras]
-test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"]
-
-[[package]]
-name = "py-serializable"
-version = "0.11.1"
-description = "Library for serializing and deserializing Python Objects to and from JSON and XML."
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "py-serializable-0.11.1.tar.gz", hash = "sha256:ba0e1287b9e4f645a5334f1913abd8e647e7250209f84f55dce3909498a6f586"},
-    {file = "py_serializable-0.11.1-py3-none-any.whl", hash = "sha256:79e21f0672822e6200b15f45ce9f636e8126466f62dbd7d488c67313c72b5c3e"},
-]
-
-[package.dependencies]
-defusedxml = ">=0.7.1,<0.8.0"
-
-[[package]]
-name = "pydeps"
-version = "1.12.17"
-description = "Display module dependencies"
-optional = false
-python-versions = "*"
-files = [
-    {file = "pydeps-1.12.17-py3-none-any.whl", hash = "sha256:4fb2e86071c78c1b85a1c63745a267d100e91daf6bab2f14331b3c77433b58b4"},
-    {file = "pydeps-1.12.17.tar.gz", hash = "sha256:c308e8355a1e77ff0af899d6f9f1665d4eb07019692dba9fb1dc1cab05df36a4"},
-]
-
-[package.dependencies]
-stdlib-list = "*"
-
-[[package]]
-name = "pygments"
-version = "2.16.1"
-description = "Pygments is a syntax highlighting package written in Python."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"},
-    {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
-]
-
-[package.extras]
-plugins = ["importlib-metadata"]
-
-[[package]]
-name = "pyparsing"
-version = "3.1.1"
-description = "pyparsing module - Classes and methods to define and execute parsing grammars"
-optional = false
-python-versions = ">=3.6.8"
-files = [
-    {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
-    {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
-]
-
-[package.extras]
-diagrams = ["jinja2", "railroad-diagrams"]
-
-[[package]]
-name = "pyproject-hooks"
-version = "1.0.0"
-description = "Wrappers to call pyproject.toml-based build backend hooks."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
-    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
-]
-
-[package.dependencies]
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-
-[[package]]
-name = "pyside6-essentials"
-version = "6.6.0"
-description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)"
-optional = false
-python-versions = "<3.13,>=3.8"
-files = [
-    {file = "PySide6_Essentials-6.6.0-cp38-abi3-macosx_11_0_universal2.whl", hash = "sha256:26d27e3e3a18acbc770a69a30774fd345414fe4932fcb89d2cfc4fc130c3eb33"},
-    {file = "PySide6_Essentials-6.6.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:60284641619f964e1cb4d53cf3169d7a385e0378b74edb75610918d2aea1c4e5"},
-    {file = "PySide6_Essentials-6.6.0-cp38-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:37d5d9c6ee696a17890f07e7ce1f88f890174bd4aca29f47922ecc959ab28352"},
-    {file = "PySide6_Essentials-6.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:97bbe33f584a09cef6a3fbc1295fb0fd7acaac345bc0f5601bf45d41c91683ac"},
-]
-
-[package.dependencies]
-shiboken6 = "6.6.0"
-
-[[package]]
-name = "pytest"
-version = "7.4.2"
-description = "pytest: simple powerful testing with Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"},
-    {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
-
-[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
-
-[[package]]
-name = "pytest-cov"
-version = "4.1.0"
-description = "Pytest plugin for measuring coverage."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"},
-    {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"},
-]
-
-[package.dependencies]
-coverage = {version = ">=5.2.1", extras = ["toml"]}
-pytest = ">=4.6"
-
-[package.extras]
-testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
-
-[[package]]
-name = "pytest-qt"
-version = "4.2.0"
-description = "pytest support for PyQt and PySide applications"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-qt-4.2.0.tar.gz", hash = "sha256:00a17b586dd530b6d7a9399923a40489ca4a9a309719011175f55dc6b5dc8f41"},
-    {file = "pytest_qt-4.2.0-py2.py3-none-any.whl", hash = "sha256:a7659960a1ab2af8fc944655a157ff45d714b80ed7a6af96a4b5bb99ecf40a22"},
-]
-
-[package.dependencies]
-pytest = ">=3.0.0"
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-doc = ["sphinx", "sphinx-rtd-theme"]
-
-[[package]]
-name = "pytest-xvfb"
-version = "3.0.0"
-description = "A pytest plugin to run Xvfb (or Xephyr/Xvnc) for tests."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-xvfb-3.0.0.tar.gz", hash = "sha256:3746ab1f4d1159f03f751638d053689ccd284291b38b8fb03d3ebbe7bf69cfc0"},
-    {file = "pytest_xvfb-3.0.0-py3-none-any.whl", hash = "sha256:352f247c788457ccdfcfeec8a47a2a6594c8eaf22f0302dae9e2635bb23975c2"},
-]
-
-[package.dependencies]
-pytest = ">=2.8.1"
-pyvirtualdisplay = ">=1.3"
-
-[[package]]
-name = "python-dateutil"
-version = "2.8.2"
-description = "Extensions to the standard Python datetime module"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-files = [
-    {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
-    {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
-]
-
-[package.dependencies]
-six = ">=1.5"
-
-[[package]]
-name = "python-slugify"
-version = "8.0.1"
-description = "A Python slugify application that also handles Unicode"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"},
-    {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"},
-]
-
-[package.dependencies]
-text-unidecode = ">=1.3"
-
-[package.extras]
-unidecode = ["Unidecode (>=1.1.1)"]
-
-[[package]]
-name = "pytoolconfig"
-version = "1.2.6"
-description = "Python tool configuration"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytoolconfig-1.2.6-py3-none-any.whl", hash = "sha256:e8b2e538f11dbabc4617884d45401e0105e2d7db920cb8ae6baa94d66126a8e3"},
-    {file = "pytoolconfig-1.2.6.tar.gz", hash = "sha256:f2d00ea4f8cbdffd3006780ba51016618c835b338f634e3f7f8b2715b1710889"},
-]
-
-[package.dependencies]
-packaging = ">=22.0"
-platformdirs = {version = ">=1.4.4", optional = true, markers = "extra == \"global\""}
-tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
-
-[package.extras]
-doc = ["sphinx (>=4.5.0)", "tabulate (>=0.8.9)"]
-gendocs = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"]
-global = ["platformdirs (>=1.4.4)"]
-validation = ["pydantic (>=1.7.4)"]
-
-[[package]]
-name = "pyvirtualdisplay"
-version = "3.0"
-description = "python wrapper for Xvfb, Xephyr and Xvnc"
-optional = false
-python-versions = "*"
-files = [
-    {file = "PyVirtualDisplay-3.0-py3-none-any.whl", hash = "sha256:40d4b8dfe4b8de8552e28eb367647f311f88a130bf837fe910e7f180d5477f0e"},
-    {file = "PyVirtualDisplay-3.0.tar.gz", hash = "sha256:09755bc3ceb6eb725fb07eca5425f43f2358d3bf08e00d2a9b792a1aedd16159"},
-]
-
-[[package]]
-name = "pyyaml"
-version = "6.0.1"
-description = "YAML parser and emitter for Python"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
-    {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
-    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
-    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
-    {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
-    {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
-    {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
-    {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
-    {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
-    {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
-    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
-    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
-    {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
-    {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
-    {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
-    {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
-    {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
-    {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
-    {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
-    {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
-    {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
-    {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
-    {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
-    {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
-    {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
-    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
-    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
-    {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
-    {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
-    {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
-    {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
-    {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
-    {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
-    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
-    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
-    {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
-    {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
-    {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
-    {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
-    {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
-]
-
-[[package]]
-name = "radon"
-version = "6.0.1"
-description = "Code Metrics in Python"
-optional = false
-python-versions = "*"
-files = [
-    {file = "radon-6.0.1-py2.py3-none-any.whl", hash = "sha256:632cc032364a6f8bb1010a2f6a12d0f14bc7e5ede76585ef29dc0cecf4cd8859"},
-    {file = "radon-6.0.1.tar.gz", hash = "sha256:d1ac0053943a893878940fedc8b19ace70386fc9c9bf0a09229a44125ebf45b5"},
-]
-
-[package.dependencies]
-colorama = {version = ">=0.4.1", markers = "python_version > \"3.4\""}
-mando = ">=0.6,<0.8"
-
-[package.extras]
-toml = ["tomli (>=2.0.1)"]
-
-[[package]]
-name = "requests"
-version = "2.31.0"
-description = "Python HTTP for Humans."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
-    {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
-]
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
-
-[[package]]
-name = "retry2"
-version = "0.9.5"
-description = "Easy to use retry decorator."
-optional = false
-python-versions = ">=2.6"
-files = [
-    {file = "retry2-0.9.5-py2.py3-none-any.whl", hash = "sha256:f7fee13b1e15d0611c462910a6aa72a8919823988dd0412152bc3719c89a4e55"},
-]
-
-[package.dependencies]
-decorator = ">=3.4.2"
-
-[[package]]
-name = "rich"
-version = "13.6.0"
-description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
-optional = false
-python-versions = ">=3.7.0"
-files = [
-    {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
-    {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
-]
-
-[package.dependencies]
-markdown-it-py = ">=2.2.0"
-pygments = ">=2.13.0,<3.0.0"
-
-[package.extras]
-jupyter = ["ipywidgets (>=7.5.1,<9)"]
-
-[[package]]
-name = "rope"
-version = "1.10.0"
-description = "a python refactoring library..."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "rope-1.10.0-py3-none-any.whl", hash = "sha256:4e9f06d7296708a8a6518590c49352c99394053d91fde5b1d74c9ffc85c76d5b"},
-    {file = "rope-1.10.0.tar.gz", hash = "sha256:14bfcc7dfea69fa32c53db0667e86e321ef059de555c7f8101a0cb91c8d85a55"},
-]
-
-[package.dependencies]
-pytoolconfig = {version = ">=1.2.2", extras = ["global"]}
-
-[package.extras]
-dev = ["build (>=0.7.0)", "pre-commit (>=2.20.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
-doc = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"]
-release = ["pip-tools (>=6.12.1)", "toml (>=0.10.2)", "twine (>=4.0.2)"]
-
-[[package]]
-name = "ruff"
-version = "0.1.2"
-description = "An extremely fast Python linter, written in Rust."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "ruff-0.1.2-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:0d3ee66b825b713611f89aa35d16de984f76f26c50982a25d52cd0910dff3923"},
-    {file = "ruff-0.1.2-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:f85f850a320ff532b8f93e8d1da6a36ef03698c446357c8c43b46ef90bb321eb"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:809c6d4e45683696d19ca79e4c6bd3b2e9204fe9546923f2eb3b126ec314b0dc"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46005e4abb268e93cad065244e17e2ea16b6fcb55a5c473f34fbc1fd01ae34cb"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10cdb302f519664d5e2cf954562ac86c9d20ca05855e5b5c2f9d542228f45da4"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f89ebcbe57a1eab7d7b4ceb57ddf0af9ed13eae24e443a7c1dc078000bd8cc6b"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7344eaca057d4c32373c9c3a7afb7274f56040c225b6193dd495fcf69453b436"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dffa25f6e03c4950b6ac6f216bc0f98a4be9719cb0c5260c8e88d1bac36f1683"},
-    {file = "ruff-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42ddaea52cb7ba7c785e8593a7532866c193bc774fe570f0e4b1ccedd95b83c5"},
-    {file = "ruff-0.1.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a8533efda625bbec0bf27da2886bd641dae0c209104f6c39abc4be5b7b22de2a"},
-    {file = "ruff-0.1.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b0b1b82221ba7c50e03b7a86b983157b5d3f4d8d4f16728132bdf02c6d651f77"},
-    {file = "ruff-0.1.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c1362eb9288f8cc95535294cb03bd4665c8cef86ec32745476a4e5c6817034c"},
-    {file = "ruff-0.1.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ffa7ef5ded0563329a35bd5a1cfdae40f05a75c0cc2dd30f00b1320b1fb461fc"},
-    {file = "ruff-0.1.2-py3-none-win32.whl", hash = "sha256:6e8073f85e47072256e2e1909f1ae515cf61ff5a4d24730a63b8b4ac24b6704a"},
-    {file = "ruff-0.1.2-py3-none-win_amd64.whl", hash = "sha256:b836ddff662a45385948ee0878b0a04c3a260949905ad861a37b931d6ee1c210"},
-    {file = "ruff-0.1.2-py3-none-win_arm64.whl", hash = "sha256:b0c42d00db5639dbd5f7f9923c63648682dd197bf5de1151b595160c96172691"},
-    {file = "ruff-0.1.2.tar.gz", hash = "sha256:afd4785ae060ce6edcd52436d0c197628a918d6d09e3107a892a1bad6a4c6608"},
-]
-
-[[package]]
-name = "schema"
-version = "0.7.5"
-description = "Simple data validation library"
-optional = false
-python-versions = "*"
-files = [
-    {file = "schema-0.7.5-py2.py3-none-any.whl", hash = "sha256:f3ffdeeada09ec34bf40d7d79996d9f7175db93b7a5065de0faa7f41083c1e6c"},
-    {file = "schema-0.7.5.tar.gz", hash = "sha256:f06717112c61895cabc4707752b88716e8420a8819d71404501e114f91043197"},
-]
-
-[package.dependencies]
-contextlib2 = ">=0.5.5"
-
-[[package]]
-name = "setuptools"
-version = "68.2.2"
-description = "Easily download, build, install, upgrade, and uninstall Python packages"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
-    {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
-]
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
-
-[[package]]
-name = "shiboken6"
-version = "6.6.0"
-description = "Python/C++ bindings helper module"
-optional = false
-python-versions = "<3.13,>=3.8"
-files = [
-    {file = "shiboken6-6.6.0-cp38-abi3-macosx_11_0_universal2.whl", hash = "sha256:bf23c43e53ffe6097853666ced05358c6640c378e992902a36c4cf77efb0223b"},
-    {file = "shiboken6-6.6.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:456b89fb4b323e0c5002d92e4d346b48bb4e709db801208df8a0d6b4f5efc33d"},
-    {file = "shiboken6-6.6.0-cp38-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:fb8c683206c3365f9240fff7f908485384893b02efb089b69ff816b4390baa9a"},
-    {file = "shiboken6-6.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:e62b2610b84f0ff7ed0181a4c535849cdc0654127097b5ef561cf0a33078f245"},
-]
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
-    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
-    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-
-[[package]]
-name = "smmap"
-version = "5.0.1"
-description = "A pure Python implementation of a sliding window memory map manager"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"},
-    {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"},
-]
-
-[[package]]
-name = "sortedcontainers"
-version = "2.4.0"
-description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set"
-optional = false
-python-versions = "*"
-files = [
-    {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"},
-    {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"},
-]
-
-[[package]]
-name = "stdlib-list"
-version = "0.9.0"
-description = "A list of Python Standard Libraries (2.7 through 3.9)."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "stdlib_list-0.9.0-py3-none-any.whl", hash = "sha256:f79957d59e41930d44afcd81e465f740b9a7a9828707a40e24ab1092b12bd423"},
-    {file = "stdlib_list-0.9.0.tar.gz", hash = "sha256:98eb66135976c96b4ee3f4c0ef0552ebb5a9977ce3028433db79f4738b02af26"},
-]
-
-[package.extras]
-dev = ["build", "stdlib-list[doc,lint,test]"]
-doc = ["furo", "sphinx"]
-lint = ["black", "mypy", "ruff"]
-support = ["sphobjinv"]
-test = ["coverage[toml]", "pytest", "pytest-cov"]
-
-[[package]]
-name = "tabulate"
-version = "0.8.10"
-description = "Pretty-print tabular data"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
-    {file = "tabulate-0.8.10-py3-none-any.whl", hash = "sha256:0ba055423dbaa164b9e456abe7920c5e8ed33fcc16f6d1b2f2d152c8e1e8b4fc"},
-    {file = "tabulate-0.8.10.tar.gz", hash = "sha256:6c57f3f3dd7ac2782770155f3adb2db0b1a269637e42f27599925e64b114f519"},
-]
-
-[package.extras]
-widechars = ["wcwidth"]
-
-[[package]]
-name = "tbump"
-version = "6.11.0"
-description = "Bump software releases"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "tbump-6.11.0-py3-none-any.whl", hash = "sha256:6b181fe6f3ae84ce0b9af8cc2009a8bca41ded34e73f623a7413b9684f1b4526"},
-    {file = "tbump-6.11.0.tar.gz", hash = "sha256:385e710eedf0a8a6ff959cf1e9f3cfd17c873617132fc0ec5f629af0c355c870"},
-]
-
-[package.dependencies]
-cli-ui = ">=0.10.3"
-docopt = ">=0.6.2,<0.7.0"
-schema = ">=0.7.1,<0.8.0"
-tomlkit = ">=0.11,<0.12"
-
-[[package]]
-name = "text-unidecode"
-version = "1.3"
-description = "The most basic Text::Unidecode port"
-optional = false
-python-versions = "*"
-files = [
-    {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
-    {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
-]
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
-    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
-    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-
-[[package]]
-name = "tomli"
-version = "2.0.1"
-description = "A lil' TOML parser"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
-    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
-]
-
-[[package]]
-name = "tomli-w"
-version = "1.0.0"
-description = "A lil' TOML writer"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "tomli_w-1.0.0-py3-none-any.whl", hash = "sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463"},
-    {file = "tomli_w-1.0.0.tar.gz", hash = "sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9"},
-]
-
-[[package]]
-name = "tomlkit"
-version = "0.11.8"
-description = "Style preserving TOML library"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"},
-    {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"},
-]
-
-[[package]]
-name = "types-python-dateutil"
-version = "2.8.19.14"
-description = "Typing stubs for python-dateutil"
-optional = false
-python-versions = "*"
-files = [
-    {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"},
-    {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"},
-]
-
-[[package]]
-name = "types-retry"
-version = "0.9.9.4"
-description = "Typing stubs for retry"
-optional = false
-python-versions = "*"
-files = [
-    {file = "types-retry-0.9.9.4.tar.gz", hash = "sha256:e4731dc684b56b875d9746459ad665d3bc281a56b530acdf1c97730167799941"},
-    {file = "types_retry-0.9.9.4-py3-none-any.whl", hash = "sha256:f29760a9fe8b1fefe253e5fe6be7e4c0eba243932c600e0eccffb42a21d17765"},
-]
-
-[[package]]
-name = "types-toml"
-version = "0.10.8.7"
-description = "Typing stubs for toml"
-optional = false
-python-versions = "*"
-files = [
-    {file = "types-toml-0.10.8.7.tar.gz", hash = "sha256:58b0781c681e671ff0b5c0319309910689f4ab40e8a2431e205d70c94bb6efb1"},
-    {file = "types_toml-0.10.8.7-py3-none-any.whl", hash = "sha256:61951da6ad410794c97bec035d59376ce1cbf4453dc9b6f90477e81e4442d631"},
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.8.0"
-description = "Backported and Experimental Type Hints for Python 3.8+"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
-    {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
-]
-
-[[package]]
-name = "uc-micro-py"
-version = "1.0.2"
-description = "Micro subset of unicode data files for linkify-it-py projects."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"},
-    {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"},
-]
-
-[package.extras]
-test = ["coverage", "pytest", "pytest-cov"]
-
-[[package]]
-name = "unidecode"
-version = "1.3.7"
-description = "ASCII transliterations of Unicode text"
-optional = false
-python-versions = ">=3.5"
-files = [
-    {file = "Unidecode-1.3.7-py3-none-any.whl", hash = "sha256:663a537f506834ed836af26a81b210d90cbde044c47bfbdc0fbbc9f94c86a6e4"},
-    {file = "Unidecode-1.3.7.tar.gz", hash = "sha256:3c90b4662aa0de0cb591884b934ead8d2225f1800d8da675a7750cbc3bd94610"},
-]
-
-[[package]]
-name = "urllib3"
-version = "2.0.7"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"},
-    {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
-[[package]]
-name = "virtualenv"
-version = "20.24.6"
-description = "Virtual Python Environment builder"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"},
-    {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"},
-]
-
-[package.dependencies]
-distlib = ">=0.3.7,<1"
-filelock = ">=3.12.2,<4"
-platformdirs = ">=3.9.1,<4"
-
-[package.extras]
-docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
-
-[[package]]
-name = "viztracer"
-version = "0.16.0"
-description = "A debugging and profiling tool that can trace and visualize python code execution"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "viztracer-0.16.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:334e303c275bb9da78effa2035dc2109ddbfbdc3ea79dfea766c71081bc4a2f2"},
-    {file = "viztracer-0.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8c477fbebde7c9ea01ebad97ad2c07a487bcd0b84e78a0bb37e56bd2a5c2c83"},
-    {file = "viztracer-0.16.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb3caacff02dcf3c13bcfa69d3c7b2af182f2dca346364e9ca49f9c633d2d070"},
-    {file = "viztracer-0.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c36bf33ed1a7d40e2c92cbf8f30669b5731eed94091106fcca2cea6de13d5f"},
-    {file = "viztracer-0.16.0-cp310-cp310-win32.whl", hash = "sha256:79745c6c2a0d715319a743d8bf8c518c96f972dae2acdd7e7b14d737e43521fc"},
-    {file = "viztracer-0.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f5af5e7386796170b6e05900868a693b997d9fcc29061e767e0c44a226638d"},
-    {file = "viztracer-0.16.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:70f4456303e671b624fbbabe5be7cdd0faa5afca68b98c51a8bd0959b33c047a"},
-    {file = "viztracer-0.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87056eb227b40855d7f3a128779fb26eb957bbfc134c4a76cdfc05a5d93d2492"},
-    {file = "viztracer-0.16.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b3842642efe73d7ede92d29e92c6ee508ddd5b7b1aacbc615b771548a16fa9d"},
-    {file = "viztracer-0.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2920f144d55dce1dfb2877f1be99ecad0b4092295d10b804a3b85088a0b41407"},
-    {file = "viztracer-0.16.0-cp311-cp311-win32.whl", hash = "sha256:c91b364d09d2b661a97372c985cca0bc644b1575d13942d7e7c60b8e03e0dbba"},
-    {file = "viztracer-0.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0637df42cde083175fd831cb808a2d2b6634f14121330edf39743d1d9247a4d"},
-    {file = "viztracer-0.16.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:e9a5fc0040bf81eca44df9e5e93b38f33d1e48c6041288267f909cecf90ca282"},
-    {file = "viztracer-0.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de12b7a3ba47448abfa2969bc57f0ef498da9ca8c351445c2b2fd7ca4d003b1"},
-    {file = "viztracer-0.16.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4652686574f304a97afc4b8ed376fd22832435e105565d2f3ecee6695fb7637"},
-    {file = "viztracer-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b329a1c6ac7b40d00f14978d63d13d4651fa496882f5ea7764aacb7f0e49c98f"},
-    {file = "viztracer-0.16.0-cp312-cp312-win32.whl", hash = "sha256:0cfc8d9d1145215335af21625405dc07692539f41491df0de4f7ecf6b2f51259"},
-    {file = "viztracer-0.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:3431e3f4d8346c782a5f388795f41838d6a95f62e85719f8912591b52e9a0828"},
-    {file = "viztracer-0.16.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e3bfa351da503b64bb742694b1f0d4c89ba0b84d59b7461c468f9c1f09ceaba1"},
-    {file = "viztracer-0.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e80a118baab28ac0cf69bd17c77c59c6d7b8dc1f7ec5f231d28b8577884aed"},
-    {file = "viztracer-0.16.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b6a71b4d5e93e044cef08412034e5e63d407aafdaf1ab21f0743cf6bdb7d3ef"},
-    {file = "viztracer-0.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc0f389e6f7344484f4280f4324148eeb970cacb2df599a0e7f864755fe0554d"},
-    {file = "viztracer-0.16.0-cp38-cp38-win32.whl", hash = "sha256:1bdabe95ea851ba4ee0ff71b36d85ff9f6d82ba863f6ae45a43827d75bfe86a4"},
-    {file = "viztracer-0.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:b016d4991bef001864827b22dec24d3b193ed312fa0d07d949c93538ce2e32a6"},
-    {file = "viztracer-0.16.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:8e9ebae7e1515da9f913e77b4086d676b19c4cc3ca3aa67a210f5cb7aa772fcd"},
-    {file = "viztracer-0.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536cc9c23295c45a3b163a1d09d625902f4ecb2ab16669c02a4a23ccb42b1d14"},
-    {file = "viztracer-0.16.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:169d240e4b32457bd1694019c6c1faf64cf001f04ac684627890fb12f8eaabaa"},
-    {file = "viztracer-0.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af94ad611ac0c58b4ac7f50dd1105173c8f38e09f049ecf497b765054769e7db"},
-    {file = "viztracer-0.16.0-cp39-cp39-win32.whl", hash = "sha256:626eb1605587a04b65c46b083729ff6af082ce22c2ecc5307a639f5f04339c84"},
-    {file = "viztracer-0.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:a5ea63d298c94f084eed34a49722c5b49d14f6e4cbf08e7604634d694ddd732f"},
-    {file = "viztracer-0.16.0.tar.gz", hash = "sha256:934a99d4985f4bde23c8039cef4ab248f4b55e799b785c33b55fe314d29fac80"},
-]
-
-[package.dependencies]
-objprint = ">0.1.3"
-
-[package.extras]
-full = ["orjson"]
-
-[[package]]
-name = "vulture"
-version = "2.10"
-description = "Find dead code"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "vulture-2.10-py2.py3-none-any.whl", hash = "sha256:568a4176db7468d0157817ae3bb1847a19f1ddc629849af487f9d3b279bff77d"},
-    {file = "vulture-2.10.tar.gz", hash = "sha256:2a5c3160bffba77595b6e6dfcc412016bd2a09cd4b66cdf7fbba913684899f6f"},
-]
-
-[package.dependencies]
-toml = "*"
-
-[[package]]
-name = "webencodings"
-version = "0.5.1"
-description = "Character encoding aliases for legacy web content"
-optional = false
-python-versions = "*"
-files = [
-    {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
-    {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
-]
-
-[[package]]
-name = "wheel"
-version = "0.41.2"
-description = "A built-package format for Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "wheel-0.41.2-py3-none-any.whl", hash = "sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8"},
-    {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"},
-]
-
-[package.extras]
-test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
-
-[[package]]
-name = "zipp"
-version = "3.17.0"
-description = "Backport of pathlib-compatible object wrapper for zip files"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
-    {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
-]
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
-
-[metadata]
-lock-version = "2.0"
-python-versions = ">=3.9,<3.12"
-content-hash = "544530f63671f79a3e262b67cd152e1e445225016eb6b16c21ea8ba580edf90f"
diff --git a/pyproject.toml b/pyproject.toml
index 61062fc3..9648d902 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,20 +1,24 @@
-[tool.poetry]
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[project]
 name = "normcap"
-version = "0.5.0-beta1"
+dynamic = ["version"]
 description = "OCR-powered screen-capture tool to capture information instead of images."
 keywords = ["screenshot", "ocr", "capture", "clipboard"]
-license = "GPLv3"
-authors = ["dynobo <dynobo@mailbox.org>"]
 readme = "README.md"
-homepage = "https://dynobo.github.io/normcap/"
-repository = "https://github.com/dynobo/normcap"
+requires-python = ">=3.9,<3.12"
+license = "GPL-3.0-or-later"
+authors = [{ name = "dynobo", email = "dynobo@mailbox.org" }]
 classifiers = [
   "Development Status :: 4 - Beta",
   "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
-  "Programming Language :: Python :: 3",
+  "Programming Language :: Python",
   "Programming Language :: Python :: 3.9",
   "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
+  "Programming Language :: Python :: Implementation :: CPython",
   "Topic :: Utilities",
   "Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
   "Intended Audience :: End Users/Desktop",
@@ -22,83 +26,84 @@ classifiers = [
   "Operating System :: POSIX :: Linux",
   "Operating System :: MacOS",
 ]
-include = [
-  "README.md",
-  "CHANGELOG",
-  "LICENSE",
-  "normcap/**/*.icns",
-  "normcap/**/*.ico",
-  "normcap/**/*.png",
-  "normcap/**/*.svg",
-  "normcap/**/*.mo",
+dependencies = ["shiboken6==6.6.0", "PySide6-Essentials==6.6.0"]
+
+[project.urls]
+Homepage = "https://dynobo.github.io/normcap/"
+Issues = "https://github.com/dynobo/normcap/issues"
+"Source Code" = "https://github.com/dynobo/normcap"
+FAQs = "https://dynobo.github.io/normcap/#faqs"
+Changelog = "https://github.com/dynobo/normcap/blob/main/CHANGELOG"
+
+[tool.hatch.version]
+path = "normcap/__init__.py"
+
+[tool.hatch.build]
+exclude = ["assets", "*.po"]
+artifacts = ["*.mo"]
+
+[tool.hatch.build.hooks.custom]
+dependencies = ["babel", "toml"]
+
+[tool.hatch.envs.default]
+dependencies = [
+  "briefcase==0.3.16",         # pinned because building relies on it!
+  "coverage[toml]>=6.5",
+  "babel>=2.12.1",
+  "black>=23.1.0",
+  "coveralls>=3.3.1",
+  "mdformat-gfm>=0.3.5",
+  "mypy>=1.3.0",
+  "pip-audit>=2.5.5",
+  "pre-commit>=3.0.2",
+  "pydeps>=1.11.0",
+  "pytest>=7.2.1",
+  "pytest-cov>=4.0.0",
+  "pytest-qt>=4.2.0",
+  "pytest-xvfb>=3.0.0",
+  "retry2>=0.9.5",
+  "types-retry>=0.9.9.4",
+  "rope>=1.7.0",
+  "ruff>=0.0.239",
+  "tbump>=6.9.0",
+  "toml>=0.10.2",
+  "types-toml>=0.10.8.1",
+  "typing-extensions>=4.4.0",
+  "mdformat-pyproject>=0.0.1",
 ]
 
-[tool.poetry.urls]
-"FAQs" = "https://dynobo.github.io/normcap/#faqs"
-"Issues" = "https://github.com/dynobo/normcap/issues"
+[tool.hatch.envs.default.scripts]
+style = [
+  "ruff {args:.}",
+  "black --check --diff {args:.}",
+  "mdformat --check --end-of-line keep {args:.}",
+]
+typing = "mypy"
+test = ["pytest {args:tests}", "coverage lcov"]
+security = "pip-audit"
+fmt = [
+  "ruff --fix {args:.}",
+  "black {args:.}",
+  "mdformat --end-of-line keep {args:.}",
+]
+charts = [
+  "pydeps normcap --max-bacon=2 -o=pydeps.png -T=png",
+  "pydeps normcap --max-bacon=1 -o=pydeps_internal.png -T=png",
+]
+# Main tasks:
+check = ["locales-compile", "style", "typing", "test", "security"]
+pre-commit = ["fmt", "check", "charts"]
+locales-compile = "python bundle/l10n.py"
+locales-update = "python bundle/l10n.py --update-all"
+create-locale = "python bundle/l10n.py --create-new"
 
-[tool.poetry.scripts]
-normcap = "normcap.app:main"
+[[tool.hatch.envs.all.matrix]]
+python = ["3.9", "3.10", "3.11"]
 
-[build-system]
-requires = ["babel>=2.12.1", "poetry-core>=1.0.0"]
-build-backend = "poetry.core.masonry.api"
-
-[tool.poetry.build]
-script = "l10n.py"
-generate-setup-file = false
-
-[tool.poetry.dependencies]
-python = ">=3.9,<3.12"
-shiboken6 = "6.6.0"
-PySide6-Essentials = "6.6.0"
-retry2 = "^0.9.5"
-
-[tool.poetry.group.dev.dependencies]
-babel = ">=2.12.1"
-black = ">=23.1.0"
-briefcase = "0.3.16"                                  # pinned because building relies on it!
-coverage = { extras = ["toml"], version = ">=6.4.2" }
-coveralls = ">=3.3.1"
-mdformat-gfm = ">=0.3.5"
-mypy = ">=1.3.0"
-pip-audit = ">=2.5.5"
-pre-commit = ">=3.0.2"
-pydeps = ">=1.11.0"
-pytest = ">=7.2.1"
-pytest-cov = ">=4.0.0"
-pytest-qt = ">=4.2.0"
-pytest-xvfb = ">=3.0.0"
-rope = ">=1.7.0"
-ruff = ">=0.0.239"
-tbump = ">=6.9.0"
-toml = ">=0.10.2"
-types-toml = ">=0.10.8.1"
-typing-extensions = ">=4.4.0"
-mdformat-pyproject = ">=0.0.1"
-types-retry = ">=0.9.9.4"
-
-[tool.poetry.group.analysis]
-optional = true
-
-[tool.poetry.group.analysis.dependencies]
-radon = ">=5.1.0"
-viztracer = ">=0.15.3"
-vulture = ">=2.4"
+[tool.hatch.envs.analysis]
+dependencies = ["radon>=5.1.0", "viztracer>=0.15.3", "vulture>=2.4"]
 
-[tool.black]
-line-length = 88
-include = '''
-(
-    ^/tests/.*py
-  | ^/normcap/.*py
-)
-'''
-exclude = '''
-(
-    __pycache__
-)
-'''
+[tool.hatch.envs.analysis.scripts]
 
 [tool.ruff]
 target-version = "py39"
@@ -145,11 +150,22 @@ ignore = [
   "ANN101", # Missing type annotation for `self` in method
   "TRY003", # Avoid specifying long messages outside the exception class
 ]
-per-file-ignores = { "tests*" = ["S101", "ANN", "D", "PLR2004", "PLR0913"] }
+
+[tool.ruff.per-file-ignores]
+"tests/**/*" = ["PLR2004", "PLR0913", "S101", "TID252", "ANN", "D"]
 
 [tool.ruff.pydocstyle]
 convention = "google"
 
+[tool.ruff.isort]
+known-first-party = ["normcap"]
+
+[tool.ruff.flake8-tidy-imports]
+ban-relative-imports = "all"
+
+[tool.black]
+line-length = 88
+
 [tool.mypy]
 files = ["normcap/**/*.py", "tests/**/*.py", "bundle/**/*.py"]
 follow_imports = "skip"
@@ -170,12 +186,15 @@ addopts = [
 markers = ["gui: tests which require a graphical interface to run"]
 
 [tool.coverage.run]
-source = ["normcap"]
+source = ["normcap", "tests"]
+branch = true
+parallel = true
+omit = []
 
 [tool.mdformat]
 wrap = 88
 number = true
-end_of_line = "lf"
+end_of_line = "keep"
 
 [tool.pydeps]
 no_show = true
@@ -295,46 +314,3 @@ USER brutus
 
 [tool.briefcase.app.normcap.windows]
 use_full_install_path = false
-
-[tool.tbump]
-
-[tool.tbump.version]
-current = "0.5.0-beta1"
-regex = '''
-  (?P<major>\d+)
-  \.
-  (?P<minor>\d+)
-  \.
-  (?P<patch>\d+)
-  (\-
-    (?P<extra>.+)
-  )?
-  '''
-
-[tool.tbump.git]
-message_template = "build(release): bump to {new_version}"
-tag_template = "v{new_version}"
-
-[[tool.tbump.file]]
-# Poetry version and Briefcase version
-src = "pyproject.toml"
-search = 'version = "{current_version}"'
-
-[[tool.tbump.file]]
-src = "normcap/__init__.py"
-search = '__version__ = "{current_version}"'
-
-[[tool.tbump.file]]
-src = "docs/index.html"
-
-[[tool.tbump.file]]
-src = "README.md"
-search = 'NormCap-{current_version}-'
-
-[[tool.tbump.file]]
-src = "README.md"
-search = 'download/v{current_version}/'
-
-[[tool.tbump.before_commit]]
-name = "check changelog"
-cmd = "grep -q {new_version} CHANGELOG"


Test patch:
diff --git a/tests/test_app.py b/tests/test_app.py
index 32c2d548..3c54da7e 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -16,11 +16,9 @@ def test_version():
     with Path("pyproject.toml").open(encoding="utf8") as toml_file:
         pyproject_toml = toml.load(toml_file)
 
-    poetry_version = pyproject_toml["tool"]["poetry"]["version"]
     briefcase_version = pyproject_toml["tool"]["briefcase"]["version"]
     normcap_version = normcap.__version__
-    assert poetry_version == normcap_version
-    assert poetry_version.startswith(briefcase_version)
+    assert normcap_version.startswith(briefcase_version)
 
 
 def test_get_args(monkeypatch):